StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StHistUtil.cxx
1 // $Id: StHistUtil.cxx,v 2.110 2021/03/19 19:27:35 genevb Exp $
2 // $Log: StHistUtil.cxx,v $
3 // Revision 2.110 2021/03/19 19:27:35 genevb
4 // Small adjustment to label size
5 //
6 // Revision 2.109 2021/03/18 21:37:39 genevb
7 // Update styles of numerous histograms
8 //
9 // Revision 2.108 2019/05/22 21:24:30 genevb
10 // Add sDCA vs. time-in-run
11 //
12 // Revision 2.107 2019/03/26 15:29:35 genevb
13 // Introduce ETOF
14 //
15 // Revision 2.106 2019/03/14 02:31:52 genevb
16 // Introduce iTPC plots
17 //
18 // Revision 2.105 2019/03/04 20:55:59 genevb
19 // Improve RDO layout for iTPC
20 //
21 // Revision 2.104 2019/02/25 19:20:18 genevb
22 // Sector numbering fix
23 //
24 // Revision 2.103 2018/07/06 22:13:04 smirnovd
25 // [Cosmetic] Changes in white space
26 //
27 // Revision 2.102 2018/07/06 22:10:26 smirnovd
28 // [Cosmetic] Inverse test conditions to skip loop iterations
29 //
30 // Revision 2.101 2018/05/05 04:00:54 genevb
31 // iTPC RDO outlines
32 //
33 // Revision 2.100 2018/05/02 21:06:32 genevb
34 // Initial accomodation for iTPC
35 //
36 // Revision 2.99 2016/06/13 20:31:10 genevb
37 // Resolve Coverity BUFFER_SIZE_WARNING with careful copy function
38 //
39 // Revision 2.98 2016/06/10 02:55:54 genevb
40 // Coverity: memory leaks, possible null pointer dereferences, over-write character buffers
41 //
42 // Revision 2.97 2016/03/16 20:39:21 genevb
43 // remove accidental extraneous line
44 //
45 // Revision 2.96 2016/03/16 20:34:43 genevb
46 // Histogram list by subsystem, single TPC sector reference choice, and a couple histogram minima set
47 //
48 // Revision 2.95 2015/01/21 17:30:33 genevb
49 // Provide histogram normalization
50 //
51 // Revision 2.94 2014/04/10 17:58:40 genevb
52 // Fix for dE/dx slope plot
53 //
54 // Revision 2.93 2014/02/20 20:16:19 genevb
55 // Adjust dE/dx slope hist range, handle ROOT change for 2D polar plots
56 //
57 // Revision 2.92 2014/01/30 19:44:06 genevb
58 // Additional TPC histogram for monitoring gas contamination
59 //
60 // Revision 2.91 2013/03/12 03:42:55 genevb
61 // typo correction
62 //
63 // Revision 2.90 2013/03/12 03:41:18 genevb
64 // handle fms/fpd naming for now
65 //
66 // Revision 2.89 2013/03/12 03:05:43 genevb
67 // Add FMS/FPD histograms for Run 13+
68 //
69 // Revision 2.88 2012/05/01 18:37:19 genevb
70 // ZCol for Vtx XY distribution
71 //
72 // Revision 2.87 2012/03/07 02:04:10 genevb
73 // Differentiate event counts for Reference
74 //
75 // Revision 2.86 2012/03/03 01:29:06 genevb
76 // Output found/total vertices
77 //
78 // Revision 2.85 2012/01/31 22:14:53 genevb
79 // QA Shift Mode, optimized for AutoQA Browser
80 //
81 // Revision 2.84 2011/05/24 20:50:43 genevb
82 // Allow limited graphics file printing
83 //
84 // Revision 2.83 2011/05/13 21:12:58 genevb
85 // Hide original prefixes in title when plotting reference hists
86 //
87 // Revision 2.82 2011/03/15 21:05:25 genevb
88 // TPC hit phi sector labels
89 //
90 // Revision 2.81 2011/02/23 20:56:56 genevb
91 // Default to general histograms for references in absence of trig typed
92 //
93 // Revision 2.80 2011/02/23 18:46:29 genevb
94 // Fixed a bug introduced in version 2.71 when adding hists
95 //
96 // Revision 2.79 2011/02/19 02:43:39 genevb
97 // Fix those missing consts
98 //
99 // Revision 2.78 2011/02/19 02:22:18 genevb
100 // Allow for specification of histogram usage by the required detector sets
101 //
102 // Revision 2.77 2011/02/07 20:25:26 genevb
103 // Allow for limiting detectors
104 //
105 // Revision 2.76 2011/01/28 18:47:55 genevb
106 // Better handling of dirName
107 //
108 // Revision 2.75 2011/01/24 18:36:28 genevb
109 // Save hist list to results file even if not comparing
110 //
111 // Revision 2.74 2011/01/19 02:05:22 genevb
112 // Allow plain ROOT files with hists, and individual plot generation from 1 file
113 //
114 // Revision 2.73 2010/12/13 16:23:26 genevb
115 // Remove previous change, add Kolmogorov maximum distance as default
116 //
117 // Revision 2.72 2010/12/11 23:28:00 genevb
118 // Allow negative modes for 1-result
119 //
120 // Revision 2.71 2010/04/19 20:43:49 genevb
121 // Fixed bug with AddHists introduced in last fix
122 //
123 // Revision 2.70 2010/04/19 19:11:13 genevb
124 // Fixed bug with AddHists when some files are missing hists
125 //
126 // Revision 2.69 2010/04/09 21:13:28 genevb
127 // Use hobj pointer to ensure proper handling with reference hists
128 //
129 // Revision 2.68 2010/03/17 02:53:06 genevb
130 // Add hists even if not in first file
131 //
132 // Revision 2.67 2010/03/12 17:28:15 genevb
133 // Same ROOT quirk fix as done in rev. 2.64, but for reference hists
134 //
135 // Revision 2.66 2010/03/12 07:29:05 genevb
136 // Additional capability for saving images of each pad
137 //
138 // Revision 2.65 2010/03/08 18:04:33 genevb
139 // Include analysis score/result on plots
140 //
141 // Revision 2.64 2010/01/14 19:29:53 genevb
142 // Fix ROOT quirk with 1 page print, fix string/char conversions, protect LOG calls
143 //
144 // Revision 2.63 2009/05/11 17:52:14 genevb
145 // Fix fit-not-attached-to-hist-for-empty-hists, needed for ROOT 5.22
146 //
147 // Revision 2.62 2009/05/06 17:19:09 genevb
148 // Avoid PDF bug with text at angles
149 //
150 // Revision 2.61 2009/05/05 23:16:12 genevb
151 // Draw TPC sector boundaries and labels
152 //
153 // Revision 2.60 2009/05/05 00:31:07 genevb
154 // Add Anode guide lines in TPC Sector plots
155 //
156 // Revision 2.59 2009/05/04 23:37:40 genevb
157 // Add RDO boundary lines in TPC Sector plots
158 //
159 // Revision 2.58 2009/04/18 02:55:06 genevb
160 // Larger arrays for more trigger type hists
161 //
162 // Revision 2.57 2009/04/05 14:37:59 genevb
163 // Catch missing files
164 //
165 // Revision 2.56 2009/03/27 21:18:36 genevb
166 // Add Jet Patch trigger histograms
167 //
168 // Revision 2.55 2009/03/25 02:42:30 genevb
169 // Box --> Col for 2D plots
170 //
171 // Revision 2.54 2009/03/23 23:50:16 genevb
172 // Add color and logarithmic scales to TPC hit location plots
173 //
174 // Revision 2.53 2009/03/19 17:43:42 genevb
175 // Catch XYTpc hists which were polar
176 //
177 // Revision 2.52 2009/03/19 01:08:08 genevb
178 // Show both xy and rphi TPC hit hists
179 //
180 // Revision 2.51 2009/03/13 21:45:40 genevb
181 // Remove unhelpful stats
182 //
183 // Revision 2.50 2009/03/13 19:27:24 genevb
184 // Now draw TPC xy hits in polar coords
185 //
186 // Revision 2.49 2009/01/17 01:48:54 genevb
187 // Fixed broken multi-page output introduced in previous commit
188 //
189 // Revision 2.48 2009/01/08 23:40:13 genevb
190 // Introduce analyses with reference histograms
191 //
192 // Revision 2.47 2008/07/10 21:25:08 genevb
193 // Add canvas-to-code output with .CC suffix
194 //
195 // Revision 2.46 2008/07/09 20:52:16 genevb
196 // allow saving histograms to plain ROOT file
197 //
198 // Revision 2.45 2008/05/30 05:48:03 genevb
199 // Add ability to write out histogram data to .C files
200 //
201 // Revision 2.44 2008/05/28 05:16:06 genevb
202 // Allow summing over (ignoring) histogram prefixes
203 //
204 // Revision 2.43 2008/05/23 17:54:54 genevb
205 // Allow subset histogram list when copying/extracting
206 //
207 // Revision 2.42 2008/05/23 17:09:22 genevb
208 // Allow the use of any file for PrintList specification
209 //
210 // Revision 2.41 2008/05/15 19:37:17 genevb
211 // Changes to FTPC radial step plots/fits
212 //
213 // Revision 2.40 2008/02/06 23:31:32 genevb
214 // missing reset of logZ
215 //
216 // Revision 2.39 2007/12/14 02:18:29 genevb
217 // Add text of counts on NullPrimVtx plots
218 //
219 // Revision 2.38 2007/12/13 23:17:45 genevb
220 // Force 0 minimum on FTPC radial hists
221 //
222 // Revision 2.37 2007/04/28 20:36:15 perev
223 // Redundant StChain.h removed
224 //
225 // Revision 2.36 2007/04/24 00:33:06 genevb
226 // SSD hists; Logz for Dedx
227 //
228 // Revision 2.35 2007/04/20 03:42:35 genevb
229 // cout -> LOG_INFO
230 //
231 // Revision 2.34 2007/04/20 01:11:11 genevb
232 // ZCol on Dedx; printf -> LOG_INFO
233 //
234 // Revision 2.33 2007/04/07 04:39:04 genevb
235 // Use ZCol for PointXYTpc
236 //
237 // Revision 2.32 2007/03/13 18:42:27 genevb
238 // Add Svt list, simplified hlist include files, handle StMultiH2F, store dirName
239 //
240 // Revision 2.31 2007/02/26 20:45:00 genevb
241 // SVT drift hist
242 //
243 // Revision 2.30 2007/01/03 19:03:41 genevb
244 // Patch for hist titles removed after migration to Root vers. 5
245 //
246 // Revision 2.29 2006/05/18 16:38:03 genevb
247 // Introduce StHistUtil::GetRunYear()
248 //
249 // Revision 2.28 2006/04/24 21:23:13 genevb
250 // Fix problem with overlayed hists, and Patch for missing titles
251 //
252 // Revision 2.27 2006/03/28 21:35:31 genevb
253 // Single page output capability for eps,jpg,png,gif,tiff,etc. [see TPad::Print()]
254 //
255 // Revision 2.26 2006/03/28 01:58:38 genevb
256 // Allow PDF (and other) output formats (was only PostScript)
257 //
258 // Revision 2.25 2005/04/19 15:14:17 genevb
259 // Slight reordering of some FTPC code on user ranges in radial hists
260 //
261 // Revision 2.24 2005/02/08 17:12:37 genevb
262 // Limiting range on some PMD histos
263 //
264 // Revision 2.23 2004/12/13 15:52:35 genevb
265 // Numerous updates: PMD, primtrk, FPD, QAShift lists
266 //
267 // Revision 2.22 2004/10/04 16:40:41 genevb
268 // FTPC radial histos
269 //
270 // Revision 2.21 2004/06/09 22:01:31 genevb
271 // Modify line parameter for FTPC hist
272 //
273 // Revision 2.20 2004/05/24 15:13:10 genevb
274 // Range limit on FTPC radial step hists
275 //
276 // Revision 2.19 2004/02/12 16:54:22 genevb
277 // Separate MinBias histos
278 //
279 // Revision 2.18 2004/02/12 05:02:59 genevb
280 // Year 4 AuAu changes. New SVT histos.
281 //
282 // Revision 2.17 2004/02/10 16:31:15 genevb
283 // A few extra histo lines, features
284 //
285 // Revision 2.16 2003/09/02 17:55:26 perev
286 // gcc 3.2 updates + WarnOff
287 //
288 // Revision 2.15 2003/02/20 20:08:36 genevb
289 // Add new prefixes, other small modifications
290 //
291 // Revision 2.14 2003/02/15 22:00:14 genevb
292 // Add tpcSectors
293 //
294 // Revision 2.13 2003/01/22 21:32:46 genevb
295 // Fix Solaris compilation errors
296 //
297 // Revision 2.12 2002/09/06 02:51:34 genevb
298 // Remove limit on maximum number of histograms that can be copied
299 //
300 // Revision 2.11 2002/04/23 01:59:54 genevb
301 // Addition of BBC/FPD histos
302 //
303 // Revision 2.10 2002/02/12 18:41:57 genevb
304 // Additional FTPC histograms
305 //
306 // Revision 2.9 2002/01/26 03:04:05 genevb
307 // Fixed some problems with fcl histos
308 //
309 // Revision 2.8 2002/01/21 22:09:23 genevb
310 // Include some ftpc histograms from StFtpcClusterMaker
311 //
312 // Revision 2.7 2001/08/27 21:16:03 genevb
313 // Better filename hanlding
314 //
315 // Revision 2.6 2001/05/24 01:47:42 lansdell
316 // minor bug fixes and updates
317 //
318 // Revision 2.5 2001/05/23 00:14:27 lansdell
319 // added some logx code
320 //
321 // Revision 2.4 2001/04/25 14:17:16 genevb
322 // Reduced line width for newer Root
323 //
324 // Revision 2.3 2000/09/15 21:19:10 fisyak
325 // HPUX does not like delete [] newHist
326 //
327 // Revision 2.2 2000/08/28 19:21:40 genevb
328 // Plot MultiH1F hists like 1d
329 //
330 // Revision 2.1 2000/08/25 22:06:50 genevb
331 // Added histo descriptor in top right
332 //
333 // Revision 2.0 2000/08/25 15:47:38 genevb
334 // New revision: cleaned up, multiple PS files
335 //
336 //
338 // Histogram Utility methods for use with star makers and bfc output
340 
341 
342 #include <Stiostream.h>
343 #include <math.h>
344 #include <stdlib.h>
345 #include <string.h>
346 #include <Stsstream.h>
347 #include "TFile.h"
348 #include "TROOT.h"
349 #include "PhysicalConstants.h"
350 #include "TStyle.h"
351 #include "TCanvas.h"
352 #include "TObjString.h"
353 #include "TMath.h"
354 #include "TString.h"
355 #include "TRegexp.h"
356 #include "TPaveLabel.h"
357 #include "TPaveText.h"
358 #include "TLegend.h"
359 #include "TDatime.h"
360 #include "TLine.h"
361 #include "TLatex.h"
362 #include "StMessMgr.h"
363 
364 #include "St_DataSetIter.h"
365 #include "StMaker.h"
366 #include "TF1.h"
367 #include "TH3.h"
368 #include "TProfile.h"
369 
370 #include "StHistUtil.h"
371 
372 typedef TH1* TH1ptr;
373 typedef const char* charptr;
374 
375 const char* possibleQAPrefixes[10] = {"","LM","MM","HM","HP","XX","MB","CL","HT","JP"};
376 const char* possibleQASuffixes[10] = {
377  "General",
378  "Low Mult",
379  "Mid Mult",
380  "High Mult",
381  "High Pt",
382  "Other Physics",
383  "MinBias",
384  "Central",
385  "High Tower",
386  "Jet Patch"
387 };
388 
389 enum QAprintModes {QAprintSet,
390  QAprintSetRef,
391  QAprintIndiv,
392  QAprintIndivRef};
393 UInt_t QAU1 = 1;
394 
395 int sizeOfCharPtr = sizeof(Char_t*);
396 int sizeOfTH1Ptr = sizeof(TH1*);
397 
398 //_____________________________________________________________________________
399 // copied from StdEdxY2Maker vers. 1.83,
400 // avoids loading that library just for these
401 Double_t StdEdxY2Maker_gaus2(Double_t *x, Double_t *p) {
402  Double_t NormL = p[0];
403  Double_t mu = p[1];
404  Double_t muP = mu + p[4];
405  Double_t sigma = p[2];
406  Double_t sigmaP = TMath::Sqrt(sigma*sigma + 0.101741*0.101741);
407  Double_t phi = p[3];
408  Double_t frac = TMath::Sin(phi);
409  frac *= frac;
410  return TMath::Exp(NormL)*((1 - frac)*TMath::Gaus(x[0],mu ,sigma ,kTRUE) +
411  frac *TMath::Gaus(x[0],muP,sigmaP,kTRUE));
412 }
413 TF1 *StdEdxY2Maker_Gaus2() {
414  TF1 *f = new TF1("Gaus2",StdEdxY2Maker_gaus2,-3,3,5);
415  f->SetParName(0,"NormL"); f->SetParLimits(0,-10.,10.);
416  f->SetParName(1,"mu"); f->SetParLimits(1,-0.5,0.5);
417  f->SetParName(2,"sigma"); f->SetParLimits(2, 0.2,0.5);
418  f->SetParName(3,"phiP"); f->SetParLimits(3, 0.0,TMath::Pi()/4);
419  f->SetParName(4,"muP");
420  f->SetParameters(10,0,0.3,0.1,1.315);
421  // f->FixParameter(4,1.425);
422  return f;
423 }
424 //_____________________________________________________________________________
425 
426 ClassImp(StHistUtil)
427 
428 //_____________________________________________________________________________
429 
430 // Constructor
431 
433 
434  numOfPosPrefixes = 10;
435  possiblePrefixes = possibleQAPrefixes;
436  possibleSuffixes = possibleQASuffixes;
437 
438  m_ListOfLogY = 0;
439  m_ListOfLogX = 0;
440  m_ListOfPrint = 0;
441  m_HistCanvas = 0;
442  m_HistCanvasR = 0;
443  debug = kFALSE;
444  m_CurPrefix = -1;
445  m_CurPage = 0;
446  m_CurFileName = "";
447  m_OutFileName = "";
448  m_OutType = "ps"; // postscript output by default
449  m_PrintMode = 0;
450  m_OutMultiPage = kTRUE;
451  m_OutIndividuals = "";
452  m_QAShiftMode = kFALSE;
453  m_RunYear = 0;
454 
455  Ltitle = 0;
456  Ldesc = 0;
457 
458  maxHistCopy = 4096;
459  newHist = new TH1ptr[maxHistCopy];
460  memset(newHist,0,maxHistCopy*sizeOfTH1Ptr);
461  m_dirName[0] = 0;
462 
463  ignorePrefixes = kFALSE;
464 
465  m_analMode = kFALSE;
466  m_refResultsFile[0] = 0;
467  m_refOutFile[0] = 0;
468  m_refCuts = 0;
469  m_refInFile = 0;
470  m_PntrToMaker = 0;
471  m_PntrToPlainFile = 0;
472 
473  m_PadColumns = 0;
474  m_PadRows = 0;
475  m_PaperWidth = 0;
476  m_PaperHeight = 0;
477 
478  m_Detectors = "";
479 
480  m_ItemsToClear = new TList();
481  m_ItemsToClear->SetOwner();
482 }
483 //_____________________________________________________________________________
484 
485 // Destructor
486 
487 StHistUtil::~StHistUtil(){
488  SafeDelete(m_HistCanvas);
489  SafeDelete(m_HistCanvasR);
490  if (m_ListOfLogY) {
491  m_ListOfLogY->Delete();
492  SafeDelete(m_ListOfLogY);
493  }
494  if (m_ListOfLogX) {
495  m_ListOfLogX->Delete();
496  SafeDelete(m_ListOfLogX);
497  }
498  if (m_ListOfPrint) {
499  m_ListOfPrint->Delete();
500  SafeDelete(m_ListOfPrint);
501  }
502  if (newHist) {
503  for (int ijk=0; ijk<maxHistCopy; ijk++) delete newHist[ijk];
504  delete [] newHist;
505  }
506  delete m_ItemsToClear;
507 }
508 //_____________________________________________________________________________
509 void StHistUtil::Clear() {
510  m_ItemsToClear->Clear();
511 }
512 //_____________________________________________________________________________
513 void StHistUtil::SetOutFile(const Char_t *fileName, const Char_t* type) {
514  m_OutFileName = fileName;
515  if (m_OutFileName.EndsWith("+")) {
516  m_OutIndividuals = ".eps"; // only option working in ROOT 5.22
517  m_PrintMode |= QAU1<<QAprintIndiv;
518  if (m_OutFileName.EndsWith("++")) m_PrintMode |= QAU1<<QAprintIndivRef;
519  while (m_OutFileName.EndsWith("+")) m_OutFileName.Chop();
520  }
521  if (type) {
522  m_OutType = type;
523  } else {
524  if (m_OutFileName.EndsWith(".ps")) m_OutType="ps";
525  else if (m_OutFileName.EndsWith(".eps")) m_OutType="eps";
526  else if (m_OutFileName.EndsWith(".epsf")) m_OutType="Preview";
527  else if (m_OutFileName.EndsWith(".pdf")) m_OutType="pdf";
528  else if (m_OutFileName.EndsWith(".jpg")) m_OutType="jpg";
529  else if (m_OutFileName.EndsWith(".jpeg")) m_OutType="jpg";
530  else if (m_OutFileName.EndsWith(".gif")) m_OutType="gif";
531  else if (m_OutFileName.EndsWith(".tif")) m_OutType="tiff";
532  else if (m_OutFileName.EndsWith(".tiff")) m_OutType="tiff";
533  else if (m_OutFileName.EndsWith(".svg")) m_OutType="svg";
534  else if (m_OutFileName.EndsWith(".xpm")) m_OutType="xpm";
535  else if (m_OutFileName.EndsWith(".png")) m_OutType="png";
536  else if (m_OutFileName.EndsWith(".CC")) m_OutType="CC"; // Save canvases as code
537  else if (m_OutFileName.EndsWith(".C")) m_OutType="C"; // Save histograms as code
538  else if (m_OutFileName.EndsWith(".root")) m_OutType="root";
539  else if (m_OutFileName.EndsWith("none")) m_OutType="none"; // No output set
540  else if (m_OutFileName.EndsWith(".qas")) m_OutType="qas"; // QA Shift mode
541  else {
542  LOG_INFO << "SetHistUtil::SetOutFile(): unknown type, assuming ps" << endm;
543  m_OutType = "ps";
544  m_OutFileName.Append(".ps");
545  }
546  }
547  if (!m_OutType.CompareTo("qas")) { // QA Shift mode options
548  m_QAShiftMode = kTRUE;
549  m_OutIndividuals = ".svg";
550  m_PrintMode |= QAU1<<QAprintIndiv;
551  m_PrintMode |= QAU1<<QAprintIndivRef;
552  m_OutType = "none";
553  }
554  if (m_OutType.CompareTo("none")) {
555  m_PrintMode |= QAU1<<QAprintSet;
556  m_PrintMode |= QAU1<<QAprintSetRef;
557  }
558 
559  // Multipage output for ps,pdf
560  m_OutMultiPage = !(m_OutType.CompareTo("ps")
561  && m_OutType.CompareTo("pdf") );
562  if (m_OutMultiPage) {
563  LOG_INFO << "StHistUtil::SetOutFile(): Multipage output" << endm;
564  } else {
565  LOG_INFO << "StHistUtil::SetOutFile(): Single page output" << endm;
566  }
567 }
568 //_____________________________________________________________________________
569 void StHistUtil::CloseOutFile() {
570  m_HistCanvas->Modified();
571  m_HistCanvas->Update();
572  if (!m_CurFileName.IsNull()) {
573  if (m_OutMultiPage) m_CurFileName.Append(")");
574  if (m_OutType.CompareTo("CC")) {
575  // single page seems to have a bug with "()" notation as of Root 5.22.00
576  if (m_CurPage==1) m_CurFileName.Chop().Chop();
577  if (m_PrintMode & QAU1<<QAprintSet)
578  m_HistCanvas->Print(m_CurFileName.Data(),m_OutType.Data());
579  } else
580  m_HistCanvas->SaveSource(m_CurFileName.Data());
581  if (m_refInFile) {
582  m_HistCanvasR->Modified();
583  m_HistCanvasR->Update();
584  m_CurFileNameR.Append(")");
585  // single page seems to have a bug with "()" notation as of Root 5.22.00
586  if (m_CurPage==1) m_CurFileNameR.Chop().Chop();
587  if (m_PrintMode & QAU1<<QAprintSetRef)
588  m_HistCanvasR->Print(m_CurFileNameR.Data(),m_OutType.Data());
589  // anal mode doesn't support single page output
590  }
591  } else {
592  LOG_INFO << "StHistUtil::CloseOutFile(): No output file" << endm;
593  }
594 }
595 //_____________________________________________________________________________
596 TString StHistUtil::StripPrefixes(const Char_t* histName, Int_t& prenum, Int_t mode) {
597  // mode < 0 : strip maker name
598  // mode > 0 : strip trigger prefix
599  // mode = 0 : strip both
600  // Figure out and strip appropriate prefix index
601  TString hName(histName);
602  Char_t makerBuffer[4];
603  memset(makerBuffer,0,4);
604  if ((hName.BeginsWith("Tab")) || (hName.BeginsWith("StE"))) {
605  memcpy(makerBuffer,histName,3);
606  hName.Remove(0,3);
607  }
608  prenum = 0; // Possible prefix=0 means no prefix
609  if (mode >= 0) {
610  for (Int_t i=1; i<numOfPosPrefixes; i++) {
611  if (hName.BeginsWith(possiblePrefixes[i])) {
612  prenum = i;
613  hName.Remove(0,strlen(possiblePrefixes[i]));
614  break;
615  }
616  }
617  if (mode>0) hName.Prepend(makerBuffer);
618  }
619  return hName;
620 }
621 //_____________________________________________________________________________
622 Bool_t StHistUtil::CheckOutFile(const Char_t *histName) {
623 // Method to determine appropriate PostScript file for output
624 
625  // Figure out appropriate prefix index
626  Int_t newPrefix = -1;
627  StripPrefixes(histName,newPrefix);
628 
629  if (newPrefix == m_CurPrefix) return kFALSE;
630 
631  CloseOutFile();
632  m_CurPrefix = newPrefix;
633  if (m_OutType.CompareTo("C") && m_OutType.CompareTo("root")) {
634  m_CurFileName = m_OutFileName;
635  Ssiz_t insertPos = m_CurFileName.Last('.');
636  if (insertPos<0) insertPos = m_CurFileName.Length();
637  if (m_OutMultiPage) m_CurFileName.Append("(");
638  else m_CurFileName.Insert(insertPos,"_");
639  m_CurFileName.Insert(insertPos,possiblePrefixes[m_CurPrefix]);
640  }
641  (m_CurFileNameR = "Ref_") += m_CurFileName;
642 
643  if (Ldesc) {
644  Ldesc->Clear();
645  Ldesc->AddText(possibleSuffixes[m_CurPrefix]);
646  Ldesc->AddText("Hists");
647  }
648  return kTRUE;
649 }
650 //_____________________________________________________________________________
651 Int_t StHistUtil::DrawHists(const Char_t *dirName) {
652 // Method DrawHists -->
653 // Plot the selected histograms and generate the postscript file as well
654 
655  LOG_INFO << " **** Now in StHistUtil::DrawHists **** " << endm;
656 
657  Int_t canvasWidth,canvasHeight;
658 
659  if (m_QAShiftMode) {
660  LOG_INFO << "In QA Shift Mode - overriding other inputs" << endm;
661  m_PadColumns=1;
662  m_PadRows=1;
663  canvasWidth = 250;
664  canvasHeight = 250;
665  } else {
666  // SetPaperSize wants width & height in cm: A4 is 20,26 & US is 20,24
667  gStyle->SetPaperSize(m_PaperWidth,m_PaperHeight);
668  // TCanvas wants width & height in pixels (712 x 950 corresponds to A4 paper)
669  // (600 x 780 US )
670  // TCanvas *m_HistCanvas = new TCanvas("CanvasName","Canvas Title",30*m_PaperWidth,30*m_PaperHeight);
671  canvasWidth = 600;
672  canvasHeight = 780;
673  }
674 
675  //set Style of Plots
676  const Int_t numPads = m_PadColumns*m_PadRows;
677  gStyle->SetStatStyle(0);
678  gStyle->SetOptDate(0);
679  gStyle->SetPalette(1);
680 
681 
682  //setup canvas
683  SafeDelete(m_HistCanvas);
684  SafeDelete(m_HistCanvasR);
685 
686  if (m_refInFile) {
687  m_HistCanvasR = new TCanvas("CanvasNameR"," STAR Reference Histogram Canvas",20,20,canvasWidth,canvasHeight);
688  }
689  m_HistCanvas = new TCanvas("CanvasName"," STAR Maker Histogram Canvas",0,0,canvasWidth,canvasHeight);
690 
691 
692  TPad *graphPad = m_HistCanvas;
693  TPad *graphPadR = m_HistCanvasR;
694  TPaveLabel* LtitleR = 0;
695  TPaveLabel *Ldatetime = 0;
696  TPaveLabel *Lpage = 0;
697  m_CurPage=1;
698 
699  if (!m_QAShiftMode) {
700  // Do not draw page numbers, titles, etc. in QA Shift mode
701 
702  // write title at top of canvas - first page
703  Ltitle = new TPaveLabel(0.08,0.96,0.88,1.0,m_GlobalTitle.Data(),"br");
704  Ltitle->SetFillColor(18);
705  Ltitle->SetTextFont(32);
706  Ltitle->SetTextSize(0.5);
707  Ltitle->Draw();
708  if (m_refInFile) {
709  m_HistCanvasR->cd();
710  LtitleR = new TPaveLabel(0.08,0.96,0.88,1.0,m_refInFile->GetName(),"br");
711  LtitleR->SetFillColor(18);
712  LtitleR->SetTextFont(32);
713  LtitleR->SetTextSize(0.5);
714  LtitleR->Draw();
715  m_HistCanvas->cd();
716  }
717 
718  // write descriptor at top of canvas - first page
719  Ldesc = new TPaveText(0.90,0.96,0.99,1.0,"br");
720  Ldesc->SetFillColor(18);
721  Ldesc->SetTextFont(32);
722  Ldesc->Draw();
723  if (m_refInFile) {
724  m_HistCanvasR->cd();
725  Ldesc->Draw();
726  m_HistCanvas->cd();
727  }
728 
729  // now put in date & time at bottom right of canvas - first page
730  TDatime HistTime;
731  const Char_t *myTime = HistTime.AsString();
732  Ldatetime = new TPaveLabel(0.7,0.01,0.95,0.03,myTime,"br");
733  Ldatetime->SetTextSize(0.6);
734  Ldatetime->Draw();
735  if (m_refInFile) {
736  m_HistCanvasR->cd();
737  Ldatetime->Draw();
738  m_HistCanvas->cd();
739  }
740 
741 
742  // now put in page # at bottom left of canvas - first page
743  Lpage = new TPaveLabel(0.1,0.01,0.16,0.03,Form("%d",m_CurPage),"br");
744  Lpage->SetTextSize(0.6);
745  Lpage->Draw();
746  if (m_refInFile) {
747  m_HistCanvasR->cd();
748  Lpage->Draw();
749  m_HistCanvas->cd();
750  }
751 
752  // Make 1 big pad on the canvas - make it a little bit inside the canvas
753  // - must cd to get to this pad!
754  // order is x1 y1 x2 y2
755  graphPad = new TPad("PadName","Pad Title",0.0,0.05,1.00,0.95);
756  graphPad->Draw();
757  graphPad->cd();
758  graphPad->Divide(m_PadColumns,m_PadRows);
759  if (m_refInFile) {
760  m_HistCanvasR->cd();
761  graphPadR = new TPad("PadNameR","Pad TitleR",0.0,0.05,1.00,0.95);
762  graphPadR->Draw();
763  graphPadR->cd();
764  graphPadR->Divide(m_PadColumns,m_PadRows);
765  graphPad->cd();
766  }
767 
768  } // !m_QAShiftMode
769 
770  Int_t padCount = 0;
771  Bool_t padAdvance = kTRUE;
772 
773 
774  // Now find the histograms
775  // get the TList pointer to the histograms:
776  PathCopy(m_dirName,dirName);
777  TList* dirList = (m_PntrToMaker ? FindHists(m_dirName) : FindHists(m_PntrToPlainFile));
778  if (!dirList) { LOG_INFO << " DrawHists - histograms not available! " << endm; }
779 
780  TIter nextHist(dirList);
781  Int_t histCounter = 0;
782  Int_t histReadCounter = 0;
783  Bool_t started = kFALSE;
784 
785 
786  TObject *obj = 0;
787  TLine ruler;
788  TLatex latex;
789  TF1* fcsFunc1 = 0;
790  TF1* fcsFunc2 = 0;
791  TF1* fcsFunc3 = 0;
792 
793  ofstream* C_ostr = 0;
794  TFile* root_ofile = 0;
795  if (!m_OutType.CompareTo("C")) {
796  C_ostr = new ofstream(m_OutFileName);
797  (*C_ostr) << " gSystem->Load(\"St_base\");" << endl;
798  (*C_ostr) << " gSystem->Load(\"StUtilities\");" << endl;
799  // not supporting ref output
800  } else if (!m_OutType.CompareTo("root"))
801  root_ofile = new TFile(m_OutFileName,"RECREATE");
802 
803  // Reference analyses:
804  TList* dirListR = 0;
805  ofstream* R_ostr = 0;
806  if (m_analMode) {
807  dirListR = FindHists(m_refInFile);
808  // By default, save histograms to a ROOT file as future reference
809  if (!root_ofile) root_ofile = new TFile(m_refOutFile,"RECREATE");
810  }
811 
812  // function to fit FTPC radial step
813  static TF1* fitFRS = 0;
814  if (!fitFRS) fitFRS = new TF1("fitFRS","[0]*(x<[1]-[2])+([0]+([3]-[0])*(x-([1]-[2]))/(2*[2]))*(x>[1]-[2])*(x<[1]+[2])+[3]*(x>[1]+[2])",6.5, 9.0);
815 
816  while ((obj = nextHist())) {
817 
818  if (!obj->InheritsFrom("TH1")) continue;
819 
820  TH1* hobj = (TH1*) obj;
821  const char* oname = hobj->GetName();
822  const char* otitle = hobj->GetTitle();
823  TString oName = oname;
824  oName.ReplaceAll(' ','_');
825  histReadCounter++;
826  LOG_INFO << Form(" %d. Reading ... %s::%s; Title=\"%s\"\n",
827  histReadCounter,hobj->ClassName(),oname, otitle) << endm;
828  if (!started && (m_FirstHistName.CompareTo("*")==0 ||
829  m_FirstHistName.CompareTo(oName)==0))
830  started = kTRUE;
831 
832 // Here is the actual loop over histograms !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
833  if (started) {
834  if (oName.CompareTo(m_LastHistName)==0) started = kFALSE;
835  histCounter++;
836 //...........................................................................
837 
838 
839  // If there's no print list, then print all histograms in directory
840  // If there is a print list, then only print if hist name is on list
841  if (!m_ListOfPrint || (m_ListOfPrint->FindObject(oname))) {
842 
843  // Some ROOT output options
844  if (root_ofile) {
845  root_ofile->cd();
846  hobj->Write();
847  }
848  if (C_ostr) {
849  hobj->SavePrimitive(*C_ostr);
850  continue;
851  }
852 
853  // this histogram will actually be printed/drawn!!
854  LOG_INFO << Form(" - %d. Drawing ... %s::%s; Title=\"%s\"\n",
855  histCounter,hobj->ClassName(),oname, otitle) << endm;
856 
857  // Switch to a new page...............................
858  if (CheckOutFile(oname)) {
859  padCount = numPads;
860  m_CurPage = 0;
861  }
862  if (m_QAShiftMode) {
863  graphPad->Clear();
864  if (m_refInFile) graphPadR->Clear();
865  padCount = 0;
866  m_CurPage++;
867  } else if (padCount == numPads) {
868  // must redraw the histcanvas for each new page!
869  m_HistCanvas->Modified();
870  m_HistCanvas->Update();
871  if (m_PrintMode & QAU1<<QAprintSet &&
872  m_CurPage>0 && !m_CurFileName.IsNull()) {
873  if (m_OutType.CompareTo("CC")) {
874  m_HistCanvas->Print(m_CurFileName.Data(),m_OutType.Data());
875  } else
876  m_HistCanvas->SaveSource(m_CurFileName.Data());
877  m_CurFileName.ReplaceAll("(",0); // doesn't hurt to do > once
878  } else {
879  m_HistCanvas->Draw();
880  }
881 
882  while (padCount > 0) graphPad->GetPad(padCount--)->Clear();
883 
884  if (m_refInFile) {
885  m_HistCanvasR->Modified();
886  m_HistCanvasR->Update();
887  if (m_PrintMode & QAU1<<QAprintSetRef &&
888  m_CurPage>0 && !m_CurFileName.IsNull()) {
889  m_HistCanvasR->Print(m_CurFileNameR.Data(),m_OutType.Data());
890  m_CurFileNameR.ReplaceAll("(",0); // doesn't hurt to do > once
891  } else m_HistCanvasR->Draw();
892  padCount = numPads;
893  while (padCount > 0) graphPadR->GetPad(padCount--)->Clear();
894  }
895 
896  // update the page number
897  m_CurPage++;
898  if (Lpage) Lpage->SetLabel(Form("%d",m_CurPage));
899 
900  if (!m_OutMultiPage && !m_CurFileName.IsNull()) {
901  Ssiz_t last_us = m_CurFileName.Last('_') + 1;
902  Ssiz_t lastdot = m_CurFileName.Last('.') - last_us;
903  m_CurFileName.Replace(last_us,lastdot,Form("%d",m_CurPage));
904  }
905  }
906 
907  // check dimension of histogram
908  Int_t chkdim = hobj->GetDimension();
909 
910  // go to next pad
911  int curPad = (++padCount);
912 
913  // Will need to display both histograms if doing reference analysis...
914  TH1* hobjO = hobj;
915  TH1* hobjR = 0;
916  if (dirListR) {
917  Int_t tempint = -1;
918  // try: full name
919  TString onamebase = oname;
920 #define SingleTpcSectorReference false
921  if (SingleTpcSectorReference && onamebase.Contains("iTpcSector")) {
922  // last parameter is the single sector to use for reference:
923  // e.g. TpcSector14 => TpcSector20 if the number is "20"
924  onamebase.Replace(onamebase.Index("iTpcSector")+10,2,"16");
925  } else if (SingleTpcSectorReference && onamebase.Contains("TpcSector")) {
926  // last parameter is the single sector to use for reference:
927  // e.g. TpcSector20 => TpcSector14 if the number is "14"
928  onamebase.Replace(onamebase.Index("TpcSector")+9,2,"9");
929  }
930  hobjR = (TH1*) (dirListR->FindObject(onamebase.Data()));
931  if (!hobjR) {
932  // try: strip just maker from name
933  onamebase = StripPrefixes(oname,tempint,-1);
934  hobjR = (TH1*) (dirListR->FindObject(onamebase.Data()));
935  if (!hobjR) {
936  // try: strip just trigger type from name
937  onamebase = StripPrefixes(oname,tempint,1);
938  hobjR = (TH1*) (dirListR->FindObject(onamebase.Data()));
939  if (!hobjR) {
940  // try: strip maker and trigger type from name
941  onamebase = StripPrefixes(oname,tempint,0);
942  hobjR = (TH1*) (dirListR->FindObject(onamebase.Data()));
943  }
944  }
945  }
946  if (hobjR) {
947  TString htitle = StripPrefixes(hobjR->GetTitle(),tempint,0);
948  if (!htitle.BeginsWith("Ref:")) htitle.Prepend("Ref:");
949  hobjR->SetTitle(htitle.Data());
950  }
951  }
952  TVirtualPad* objPad = 0;
953  for (int analRepeat = 0;analRepeat < (hobjR ? 2 : 1); analRepeat++) {
954 
955  padAdvance = kTRUE;
956  if (analRepeat) {
957  objPad=gPad;
958  graphPadR->cd(m_QAShiftMode ? 0 : curPad);
959  hobj=hobjR;
960  } else graphPad->cd(m_QAShiftMode ? 0 : curPad);
961 
962  // set x & y grid off by default
963  TRegexp bsmdPerModule("bsmd.*PerModule");
964  gPad->SetGridy(0);
965  if (oName.Contains("H_matchCand")) {
966  gPad->SetGridx(1);
967  gStyle->SetGridStyle(6);
968  gStyle->SetGridColor(kOrange);
969  } else if (oName.Contains(bsmdPerModule)) {
970  hobj->GetXaxis()->SetNdivisions(15);
971  hobj->GetXaxis()->SetLabelSize(0.03);
972  hobj->GetXaxis()->SetTitle("Module Number");
973  gPad->SetGridx();
974  } else {
975  gPad->SetGridx(0);
976  gStyle->SetGridStyle(3);
977  gStyle->SetGridColor(kGray);
978  }
979 
980  // set stats to draw
981  TRegexp bsmd2DPerModule("bsmd.*Strip.*PerModule");
982  if (oName.Contains("TpcSector") ||
983  oName.Contains("PointRPTpc") ||
984  oName.Contains("PointXYTpc") ||
985  oName.Contains("TrigBits")) {
986  gStyle->SetOptStat(11);
987  } else if (oName.Contains("NullPrim")) {
988  gStyle->SetOptStat(1111);
989  } else if (oName.Contains(bsmd2DPerModule)) {
990  gStyle->SetOptStat(0);
991  hobj->GetYaxis()->SetTitle("Strip Within Module");
992  hobj->GetYaxis()->SetTitleOffset(1.4);
993  } else {
994  gStyle->SetOptStat(111111);
995  }
996 
997  // set bottom margin of pad
998  if (oName.Contains("TrigBits")) {
999  gPad->SetBottomMargin(0.35);
1000  hobj->GetXaxis()->SetLabelSize(0.03);
1001  hobj->GetXaxis()->SetLabelFont(42);
1002  } else {
1003  gPad->SetBottomMargin(0.10);
1004  }
1005 
1006  if (oName.Contains("GtrkPadfT")) hobj->SetMinimum(0.8);
1007 
1008  // set logX,Y,Z scale on/off
1009 
1010 // Normalized histograms: rely on negative bin content 0 as a flag (seems OK for now, but not guaranteed)
1011  Float_t BinCont0 = hobj->GetBinContent(0);
1012  if (BinCont0 < 0) {
1013  LOG_INFO << " -- Will normalize by 1/" << -BinCont0 << ": " << oname << endm;
1014  hobj->Scale(-1.0/BinCont0);
1015  }
1016 
1017 
1018 // Set logY scale on if: there is a loglist, if the hist name is on the list, if it has entries
1019 // and if the max entries in all bins is > 0
1020  if (m_ListOfLogY && m_ListOfLogY->FindObject(oname) &&
1021  hobj->GetEntries() && hobj->GetMaximum() ) {
1022  gPad->SetLogy(1);
1023  if (!analRepeat) {LOG_INFO << " -- Will draw in logY scale: " << oname <<endm;}
1024  } else gPad->SetLogy(0);
1025 
1026 
1027 // Set logX scale on if: there is a loglist, if the hist name is on the list, if it has entries
1028 // and if the max entries in all bins is > 0
1029  if (m_ListOfLogX && m_ListOfLogX->FindObject(oname) &&
1030  hobj->GetEntries() && hobj->GetMaximum() ) {
1031  gPad->SetLogx(1);
1032  if (!analRepeat) {LOG_INFO << " -- Will draw in logX scale: " << oname <<endm;}
1033  } else gPad->SetLogx(0);
1034 
1035 // Set logZ scale
1036  if (oName.EndsWith("PVsDedx") ||
1037  oName.Contains("fms_qt_") ||
1038  oName.Contains("fpd_channel_") ||
1039  oName.Contains("TofPID") ||
1040  oName.Contains("multiplicity_etofHits") ||
1041  oName.Contains("eTofHits") ||
1042  oName.Contains("etofMult") ||
1043  oName.Contains("G_matchCand_") ||
1044  oName.Contains("RP_cluster_xy") ||
1045  oName.Contains("TpcSector") ||
1046  oName.Contains("PointRPTpc") ||
1047  oName.Contains("PointXYTpc")) {
1048  gPad->SetLogz(1);
1049  if (!analRepeat) {LOG_INFO << " -- Will draw in logZ scale: " << oname <<endm;}
1050  } else gPad->SetLogz(0);
1051 
1052 // Limit x range for some histograms
1053  if (oName.EndsWith("QaPointTpc") ||
1054  oName.EndsWith("QaPointSvt") ||
1055  oName.Contains("QaPointSvtLaser") ||
1056  oName.EndsWith("QaPointSsd") ||
1057  oName.EndsWith("QaPointFtpc") ||
1058  oName.EndsWith("QaRichTot") ||
1059  oName.EndsWith("QaV0Vtx") ||
1060  oName.EndsWith("QaXiVtxTot") ||
1061  oName.Contains("QaPmdTotal") ||
1062  oName.Contains("QaCpvTotal") ||
1063  oName.EndsWith("SImpactTime") ||
1064  oName.EndsWith("trkGoodTTS")) {
1065  Float_t mean = hobj->GetMean(1);
1066  Float_t window = hobj->GetRMS(1);
1067  Float_t bwid = hobj->GetXaxis()->GetBinWidth(1);
1068  if (window < bwid) window = bwid;
1069  hobj->SetAxisRange(mean-5*window,mean+5*window,"X");
1070  }
1071 
1072 // Limit both x & y ranges together for some histograms
1073  if (oName.EndsWith("trkGoodF")) {
1074  Float_t mean1 = hobj->GetMean(1);
1075  Float_t mean2 = hobj->GetMean(2);
1076  Float_t window1 = hobj->GetRMS(1);
1077  Float_t window2 = hobj->GetRMS(2);
1078  Float_t bwid = hobj->GetXaxis()->GetBinWidth(1);
1079  if (window1 < bwid) window1 = bwid;
1080  if (window2 < bwid) window2 = bwid;
1081  Float_t lo = TMath::Min(mean1-5*window1,mean2-5*window2);
1082  Float_t hi = TMath::Max(mean1+5*window1,mean2+5*window2);
1083  hobj->SetAxisRange(lo,hi,"X");
1084  hobj->SetAxisRange(lo,hi,"Y");
1085  }
1086 
1087 // Limit both x & y ranges for QaVtxFtpcE/WTpcXY histograms for non-year 7 runs
1088  if (oName.Contains("VtxFtpc")&&oName.Contains("TpcXY")&&m_RunYear!=7){
1089  hobj->GetXaxis()->SetRangeUser(-2.0,2.0);
1090  hobj->GetYaxis()->SetRangeUser(-2.0,2.0);
1091  }
1092 
1093 // Limit x (time) range for some ETOF histograms
1094  if (oName.Contains("Diff_etofHits")) {
1095  hobj->GetXaxis()->SetRangeUser(0.0,100.0);
1096  }
1097 
1098  // actually draw,print
1099  if ((chkdim == 3) && (hobj->InheritsFrom("StMultiH2F"))) {
1100  hobj->Draw("Col");
1101  } else if ((chkdim == 3) && (oName.Contains("Z3A"))) {
1102  latex.SetTextAngle(0);
1103  latex.SetTextAlign(12);
1104  TH3F* Z3A = (TH3F*) hobj;
1105  Bool_t noneYet = kTRUE;
1106  // copied from StdEdxY2Maker::FinishRun() vers. 1.83,
1107  // with minor modifications for plotting the results
1108  Double_t slope = 1.7502e-6;// slope from Blair 1/( O2 in ppm., cm )
1109  const Char_t *IO[2] = {"Inner", "Outer"};
1110  Double_t xmin[2] = { 40, 40};
1111  Double_t xmax[2] = {200,180};
1112  TF1 *gg = StdEdxY2Maker_Gaus2();
1113  float histmiddle = 0;
1114  for (Int_t io = 1; io <= 2; io++) {
1115  Z3A->GetXaxis()->SetRange(io,io);
1116  TH2 *I = (TH2 *) Z3A->Project3D(Form("zy%i",io));
1117  if (I) {
1118  I->FitSlicesY(gg);
1119  TH1D *proj = (TH1D*) gDirectory->Get(Form("%s_1",I->GetName()));
1120  if (proj) {
1121  proj->Fit("pol1","erq",(noneYet ? "" : "same"),xmin[io-1],xmax[io-1]);
1122  proj->SetLineColor(8-io);
1123  proj->SetMarkerColor(8-io);
1124  proj->SetMarkerStyle(24-io);
1125  proj->SetStats(0);
1126  proj->SetTitle(otitle);
1127  TF1 *f = (TF1 *) proj->GetListOfFunctions()->FindObject("pol1");
1128  if (f) {
1129  gMessMgr->Info() << "StHistUtil: Estimated content of O2 (ppm) "
1130  << "from slope in drift distance for "
1131  << Form("%s = %10.2f +/- %10.2f", IO[io-1],
1132  -f->GetParameter(1)/slope, f->GetParError(1)/slope)
1133  << endm;
1134  if (noneYet) histmiddle = f->Eval(100.0);
1135  f->SetLineColor(6-2*io);
1136  latex.SetTextColor(6-2*io);
1137  latex.DrawLatex(20,histmiddle+0.9-0.6*io,Form("%s : %10.2f +/- %10.2f\n",
1138  IO[io-1],-f->GetParameter(1)/slope,f->GetParError(1)/slope));
1139  }
1140  if (noneYet) {
1141  proj->SetMinimum(histmiddle-0.4);
1142  proj->SetMaximum(histmiddle+0.4);
1143  noneYet = kFALSE;
1144  }
1145  }
1146  }
1147  }
1148  latex.SetTextColor(1);
1149  } else if ((chkdim==2) && (oName.Contains("PointRPTpc") ||
1150  (oName.Contains("PointXYTpc") && // Unfortunately was polar for a short time
1151  TMath::Abs((hobj->GetYaxis()->GetXmax()/TMath::Pi())-2)<1e-5))) {
1152  TH2F* htmp = new TH2F(Form("%s.",hobj->GetName()),hobj->GetTitle(),1,-200,200,1,-200,200);
1153  float hmin = (oName.Contains("PointRPTpcQ") ? 1e-4 : 1.0);
1154  htmp->Fill(0.,0.,hmin); htmp->SetMinimum(hmin);
1155  htmp->SetStats(kFALSE);
1156  htmp->Draw();
1157  hobj->SetMinimum(0.9*hmin);
1158  if (gROOT->GetVersionInt() < 52800) {
1159  hobj->Draw("Pol ZCol Same");
1160  } else {
1161  // lego plots always needed phi,r from x,y
1162  // (z)col plots, however, needed r,phi from x,y
1163  // Now, (z)col plots also need phi,r from x,y
1164  // https://sft.its.cern.ch/jira/browse/ROOT-2845
1165  FlipAxes(hobj)->Draw("Pol ZCol Same");
1166  }
1167  } else if ((chkdim == 2) &&
1168  (oName.EndsWith("SImpactTime"))) {
1169  hobj->SetMarkerStyle(7);
1170  ((TH2F*) hobj)->Rebin2D(100,1,0);
1171  hobj->SetXTitle("Time in run [sec]");
1172  hobj->SetYTitle("signed impact (sDCA) [cm]");
1173  ((TH2F*) hobj)->ProfileX()->Draw();
1174  } else if ((chkdim == 2) &&
1175  (oName.EndsWith("SvtLoc") ||
1176  oName.EndsWith("PVsDedx") ||
1177  oName.EndsWith("VtxPrXY") ||
1178  oName.EndsWith("SSD") ||
1179  oName.EndsWith("PointXYSvt") ||
1180  oName.Contains("TpcSector") ||
1181  oName.Contains("PointXYTpc") ||
1182  oName.Contains("SectorvsSensor") ||
1183  oName.Contains("LaddervsSensor"))) {
1184  if (oName.Contains("TpcSector")) {
1185  // method to suppress a single hot channel
1186  Double_t max1 = hobj->GetMaximum();
1187  Double_t max2 = hobj->GetMaximum(max1);
1188  if (max1/max2 > 5) hobj->SetBinContent(hobj->GetMaximumBin(),max2);
1189  }
1190  hobj->Draw("ZCol");
1191  } else if ((chkdim == 2) && (!hobj->InheritsFrom("StMultiH1F"))) {
1192  hobj->Draw("Col");
1193  if ((oName.EndsWith("trkGoodF"))||(oName.EndsWith("VtxSvtvsTpc"))) {
1194  ruler.SetLineColor(46);
1195  ruler.SetLineWidth(2);
1196  ruler.DrawLineNDC(0.1,0.1,0.9,0.9);
1197  }
1198  } else {
1199  if (oName.Contains("QaBbc") ||
1200  (oName.Contains("QaPmd") && !oName.Contains("Total")) ||
1201  (oName.Contains("QaFpd") && !oName.Contains("Sums"))) {
1202  hobj->SetBarOffset();
1203  }
1204  if (oName.Contains("TrigBits")) {
1205  hobj->SetLineWidth(1);
1206  } else {
1207  hobj->SetLineWidth(2);
1208  }
1209  if (oName.EndsWith("Mass")) hobj->Draw("e");
1210  else hobj->Draw();
1211  if (oName.BeginsWith("fcl_radial") && (hobj->GetEntries() > 0)) {
1212  //Fits to radial steps FTPCE+W/////05/14/08///nav+gvb
1213  hobj->GetXaxis()->SetRangeUser(6.5,9.0);
1214  hobj->Fit("pol0","","", 6.5, 7.2);
1215  double n1= hobj->GetFunction("pol0")->GetParameter(0);
1216  hobj->Fit("pol0","","",8.3,9.0);
1217  double n2= hobj->GetFunction("pol0")->GetParameter(0);
1218  fitFRS->SetParameters(n1, 7.85, 0.35, n2);
1219  hobj->Fit(fitFRS, "R");
1220 
1221  double rstep = fitFRS->GetParameter(1);
1222  double erstep = fitFRS->GetParError(1);
1223  float hmin = hobj->GetMinimum();
1224  float hmax = hobj->GetMaximum();
1225  ruler.SetLineColor(kBlack);
1226  ruler.SetLineWidth(2);
1227  ruler.DrawLine(7.8,hmin,7.8,hmax);
1228  ruler.SetLineColor(kGreen);
1229  ruler.SetLineWidth(3);
1230  ruler.DrawLine(rstep,hmin,rstep,hmax);
1231  ruler.SetLineWidth(1);
1232  ruler.DrawLine(rstep-erstep,hmin,rstep-erstep,hmax);
1233  ruler.DrawLine(rstep+erstep,hmin,rstep+erstep,hmax);
1234  }
1235 
1236 
1237  }
1238 
1239  if (oName.Contains("NullPrimVtx")) {
1240  int msdVtx = (int) (hobj->GetBinContent(hobj->FindBin(-1.)));
1241  int qstVtx = (int) (hobj->GetBinContent(hobj->FindBin(0.)));
1242  int goodVtx = (int) (hobj->GetBinContent(hobj->FindBin(1.)));
1243  int fndVtx = qstVtx + goodVtx;
1244  int totVtx = fndVtx + msdVtx;
1245  Float_t txtSiz = latex.GetTextSize();
1246  latex.SetTextSize(txtSiz*1.5);
1247  latex.SetTextAngle(90);
1248  latex.SetTextAlign(3);
1249  latex.SetTextColor(4);
1250  latex.DrawLatex(-0.8,0,Form(" missed: %d",msdVtx));
1251  latex.DrawLatex(0.2,0,Form(" questionable: %d",qstVtx));
1252  latex.DrawLatex(1.2,0,Form(" good: %d",goodVtx));
1253  latex.SetTextSize(txtSiz*2);
1254  latex.SetTextColor(2);
1255  latex.DrawLatex(-1.8,0,Form(" total: %d",totVtx));
1256  latex.SetTextAlign(1);
1257  latex.SetTextColor(kGreen+3);
1258  latex.DrawLatex(-1.1,0,Form(" found: %d",fndVtx));
1259  // restore
1260  latex.SetTextColor(1);
1261  latex.SetTextSize(txtSiz);
1262  LOG_INFO << (m_CurPrefix ? possiblePrefixes[m_CurPrefix] : "GE")
1263  << (analRepeat ? " Ref" : "")
1264  << " QA Events (found vtx/total) "
1265  << fndVtx << " / " << totVtx << endm;
1266  }
1267 
1268  if (oName.Contains("h1_inv_mass_cluster")) {
1269  ruler.SetLineColor(2);
1270  ruler.SetLineWidth(1);
1271  ruler.DrawLine(0.135,0.,0.135,hobj->GetMaximum());
1272  }
1273 
1274  if (oName.Contains("h2_cluster_dgg_vs_E1pE2")) {
1275  if (!fcsFunc1) {
1276  fcsFunc1= new TF1("Zgg=0","156.20/x",4,30);
1277  fcsFunc1->SetTitle("Z_{gg}=0");
1278  fcsFunc2= new TF1("Zgg=0.35","166.747/x",4,30);
1279  fcsFunc2->SetTitle("Z_{gg}=0.35");
1280  fcsFunc3= new TF1("Zgg=0.70","218.72/x",4,30);
1281  fcsFunc3->SetTitle("Z_{gg}=0.7");
1282  fcsFunc1->SetLineColor(2);
1283  fcsFunc2->SetLineColor(6);
1284  fcsFunc3->SetLineColor(28);
1285  }
1286  fcsFunc1->Draw("same");
1287  fcsFunc2->Draw("same");
1288  fcsFunc3->Draw("same");
1289  }
1290 
1291  if (oName.Contains("iTpcSector")) {
1292  // Draw RDO boundaries
1293  ruler.SetLineColor(1);
1294  ruler.SetLineWidth(1);
1295  // between RDOs 4-8, draw +/- (npads_row1+npads_row2)/2 * (pitch/2)
1296  float pitch = 0.67/2.0; // 6.7mm pitch
1297  ruler.DrawLine(-137*pitch,64.5,137*pitch,64.5);
1298  ruler.DrawLine(-123*pitch,56.5,123*pitch,56.5);
1299  ruler.DrawLine(-111*pitch,48.5,111*pitch,48.5);
1300  ruler.DrawLine( -97*pitch,40.5, 97*pitch,40.5);
1301  // between RDOs 1-2, outer X pads [X/2 at each end] are in RDO 1
1302  pitch = 0.50/2.0; // 5.0mm pitch
1303  int row_width = 70; int in_step1 = 52; int in_step2 = 54;
1304  float row1=10.5; float row2 = row1+1.0; float row3 = row1+2.0;
1305  ruler.DrawLine(-(row_width-in_step2)*pitch,row3,(row_width-in_step2)*pitch,row3);
1306  ruler.DrawLine(-(row_width-in_step2)*pitch,row2,-(row_width-in_step1)*pitch,row2);
1307  ruler.DrawLine((row_width-in_step2)*pitch,row2,(row_width-in_step1)*pitch,row2);
1308  ruler.DrawLine(-row_width*pitch,row1,-(row_width-in_step1)*pitch,row1);
1309  ruler.DrawLine((row_width-in_step1)*pitch,row1,row_width*pitch,row1);
1310  ruler.DrawLine(-(row_width-in_step1)*pitch,row1,-(row_width-in_step1)*pitch,row2);
1311  ruler.DrawLine((row_width-in_step1)*pitch,row1,(row_width-in_step1)*pitch,row2);
1312  ruler.DrawLine(-(row_width-in_step2)*pitch,row3,-(row_width-in_step2)*pitch,row2);
1313  ruler.DrawLine((row_width-in_step2)*pitch,row3,(row_width-in_step2)*pitch,row2);
1314  // between RDOs 2-3&4
1315  bool east = (atoi(&(oName.Data()[oName.Last('r')+1])) > 12);
1316  pitch = (east ? 0.50 : -0.50); // 5.0mm pitch, switch orientation for east vs. west
1317  float p01 = 46*pitch; float row01 = 22.5;
1318  float p02 = 36*pitch; float row02 = 22.5;
1319  float p03 = 36*pitch; float row03 = 21.5;
1320  float p04 = 39*pitch; float row04 = 21.5;
1321  float p05 = 39*pitch; float row05 = 20.5;
1322  float p06 = 19*pitch; float row06 = 20.5;
1323  float p07 = 19*pitch; float row07 = 22.5;
1324  float p08 = 9*pitch; float row08 = 22.5;
1325  float p09 = 9*pitch; float row09 = 23.5;
1326  float p10 = 2*pitch; float row10 = 23.5;
1327  float p11 = 2*pitch; float row11 = 24.5;
1328  ruler.DrawLine( p01,row01, p02,row02);
1329  ruler.DrawLine( p02,row02, p03,row03);
1330  ruler.DrawLine( p03,row03, p04,row04);
1331  ruler.DrawLine( p04,row04, p05,row05);
1332  ruler.DrawLine( p05,row05, p06,row06);
1333  ruler.DrawLine( p06,row06, p07,row07);
1334  ruler.DrawLine( p07,row07, p08,row08);
1335  ruler.DrawLine( p08,row08, p09,row09);
1336  ruler.DrawLine( p09,row09, p10,row10);
1337  ruler.DrawLine( p10,row10, p11,row11);
1338  ruler.DrawLine(-p01,row01,-p02,row02);
1339  ruler.DrawLine(-p02,row02,-p03,row03);
1340  ruler.DrawLine(-p03,row03,-p04,row04);
1341  ruler.DrawLine(-p04,row04,-p05,row05);
1342  ruler.DrawLine(-p05,row05,-p06,row06);
1343  ruler.DrawLine(-p06,row06,-p07,row07);
1344  ruler.DrawLine(-p07,row07,-p08,row08);
1345  ruler.DrawLine(-p08,row08,-p09,row09);
1346  ruler.DrawLine(-p09,row09,-p10,row10);
1347  ruler.DrawLine(-p10,row10,-p11,row11);
1348  ruler.DrawLine(-p11,row11, p11,row11);
1349  // between RDOs 3-4
1350  p01 = 0*pitch; row01 = 24.5;
1351  p02 = 0*pitch; row02 = 26.5;
1352  p03 = -7*pitch; row03 = 26.5;
1353  p04 = -7*pitch; row04 = 28.5;
1354  p05 = -8*pitch; row05 = 28.5;
1355  p06 = -8*pitch; row06 = 30.5;
1356  p07 = 10*pitch; row07 = 30.5;
1357  p08 = 10*pitch; row08 = 32.5;
1358  p09 = 11*pitch; row09 = 32.5;
1359  p10 = 11*pitch; row10 = 35.5;
1360  p11 = 10*pitch; row11 = 35.5;
1361  float p12 = 10*pitch; float row12 = 36.5;
1362  float p13 = 0*pitch; float row13 = 36.5;
1363  float p14 = 0*pitch; float row14 = 40.5;
1364  ruler.DrawLine(p01,row01,p02,row02);
1365  ruler.DrawLine(p02,row02,p03,row03);
1366  ruler.DrawLine(p03,row03,p04,row04);
1367  ruler.DrawLine(p04,row04,p05,row05);
1368  ruler.DrawLine(p05,row05,p06,row06);
1369  ruler.DrawLine(p06,row06,p07,row07);
1370  ruler.DrawLine(p07,row07,p08,row08);
1371  ruler.DrawLine(p08,row08,p09,row09);
1372  ruler.DrawLine(p09,row09,p10,row10);
1373  ruler.DrawLine(p10,row10,p11,row11);
1374  ruler.DrawLine(p11,row11,p12,row12);
1375  ruler.DrawLine(p12,row12,p13,row13);
1376  ruler.DrawLine(p13,row13,p14,row14);
1377  latex.SetTextAngle(0);
1378  latex.SetTextAlign(32);
1379  latex.DrawLatex(50,5,"RDO 1");
1380  latex.DrawLatex(50,18,"2");
1381  latex.DrawLatex(50,33,(east ? "4 , 3" : "3 , 4"));
1382  latex.DrawLatex(50,44,"5");
1383  latex.DrawLatex(50,52,"6");
1384  latex.DrawLatex(50,60,"7");
1385  latex.DrawLatex(50,68,"8");
1386 
1387  // Draw Anode guides
1388  ruler.SetLineColor(2);
1389  ruler.DrawLine(-52,10.5,-47,10.5);
1390  ruler.DrawLine(-52,20.5,-47,20.5);
1391  ruler.DrawLine(-52,30.5,-47,30.5);
1392  ruler.DrawLine(-52,40.5,-47,40.5);
1393  ruler.DrawLine(-52,48.1,-47,48.1);
1394  ruler.DrawLine(-52,56.1,-47,56.1);
1395  ruler.DrawLine(-52,64.1,-47,64.1);
1396  latex.SetTextAlign(12);
1397  latex.SetTextColor(2);
1398  latex.DrawLatex(-50, 5.1,"1 Anode");
1399  latex.DrawLatex(-50,15.1,"2");
1400  latex.DrawLatex(-50,25.1,"3");
1401  latex.DrawLatex(-50,35.1,"4");
1402  latex.DrawLatex(-50,44.1,"5");
1403  latex.DrawLatex(-50,52.1,"6");
1404  latex.DrawLatex(-50,60.1,"7");
1405  latex.DrawLatex(-50,68.1,"8");
1406  latex.SetTextColor(1);
1407  } else if (oName.Contains("TpcSector")) {
1408  // Draw RDO boundaries
1409  ruler.SetLineColor(1);
1410  ruler.SetLineWidth(1);
1411  // between RDOs 2-6, draw +/- (npads_row1+npads_row2)/2 * (pitch/2)
1412  float pitch = 0.67/2.0; // 6.7mm pitch
1413  ruler.DrawLine(-137*pitch,37.5,137*pitch,37.5);
1414  ruler.DrawLine(-123*pitch,29.5,123*pitch,29.5);
1415  ruler.DrawLine(-111*pitch,21.5,111*pitch,21.5);
1416  ruler.DrawLine( -97*pitch,13.5, 97*pitch,13.5);
1417  // between RDOs 1-2, outer 24(68) pads [12(34) at each end] are in RDO 1
1418  pitch = 0.335/2.0; // 3.35mm pitch
1419  int row_width = 134; int in_step = 68; float row1=6.5;
1420  //if (m_RunYear < 17) { row_width = 142; in_step = 24; row1=7.5; }
1421  float row2 = row1+1.0;
1422  ruler.DrawLine(-(row_width-in_step)*pitch,row2,(row_width-in_step)*pitch,row2);
1423  ruler.DrawLine(-row_width*pitch,row1,-(row_width-in_step)*pitch,row1);
1424  ruler.DrawLine((row_width-in_step)*pitch,row1,row_width*pitch,row1);
1425  ruler.DrawLine(-(row_width-in_step)*pitch,row1,-(row_width-in_step)*pitch,row2);
1426  ruler.DrawLine((row_width-in_step)*pitch,row1,(row_width-in_step)*pitch,row2);
1427  latex.SetTextAngle(0);
1428  latex.SetTextAlign(32);
1429  latex.DrawLatex(50,4,"RDO 1");
1430  latex.DrawLatex(50,10,"2");
1431  latex.DrawLatex(50,17,"3");
1432  latex.DrawLatex(50,25,"4");
1433  latex.DrawLatex(50,33,"5");
1434  latex.DrawLatex(50,41,"6");
1435 
1436  // Draw Anode guides
1437  ruler.SetLineColor(2);
1438  ruler.DrawLine(-52,2.9,-47,2.9);
1439  ruler.DrawLine(-52,6.2,-47,6.2);
1440  ruler.DrawLine(-52,9.4,-47,9.4);
1441  ruler.DrawLine(-52,13.5,-47,13.5);
1442  ruler.DrawLine(-52,21.1,-47,21.1);
1443  ruler.DrawLine(-52,29.1,-47,29.1);
1444  ruler.DrawLine(-52,37.1,-47,37.1);
1445  latex.SetTextAlign(12);
1446  latex.SetTextColor(2);
1447  latex.DrawLatex(-50,1.5,"1 Anode");
1448  latex.DrawLatex(-50,4.6,"2");
1449  latex.DrawLatex(-50,7.8,"3");
1450  latex.DrawLatex(-50,11.4,"4");
1451  latex.DrawLatex(-50,17.1,"5");
1452  latex.DrawLatex(-50,25.1,"6");
1453  latex.DrawLatex(-50,33.1,"7");
1454  latex.DrawLatex(-50,41.1,"8");
1455  latex.SetTextColor(1);
1456  }
1457 
1458  if (oName.Contains("PointRPTpc") ||
1459  oName.Contains("PointXYTpc") ) {
1460  // Draw sector boundaries and label
1461  int eastsec = (oName.Contains("TpcE") || oName.Contains("TpcQE") ? 12 : 0);
1462  ruler.SetLineColor(0);
1463  ruler.SetLineStyle(2);
1464  float sz = latex.GetTextSize();
1465  latex.SetTextAlign(32);
1466  latex.SetTextSize(0.032);
1467  int secn = (eastsec ? 21 : 13);
1468  float phistep = TMath::Pi()/12;
1469  for (float phi=phistep; phi<6.2; phi+=phistep) {
1470  float xsec = TMath::Cos(phi);
1471  float ysec = TMath::Sin(phi);
1472  ruler.DrawLine(50*xsec,50*ysec,199*xsec,199*ysec);
1473  phi+=phistep;
1474  xsec = TMath::Cos(phi);
1475  ysec = TMath::Sin(phi);
1476  latex.SetTextAngle(phi*180/TMath::Pi()+1); // +1 degree necessary to avoid PDF bug
1477  latex.DrawLatex(52*xsec,52*ysec,Form("%d",secn%12 + eastsec + 1));
1478  secn += (eastsec ? 1 : -1);
1479  }
1480  latex.SetTextSize(sz);
1481  ruler.SetLineStyle(1);
1482  }
1483 
1484  if (oName.EndsWith("QaPointPhiT")) {
1485  float hmin = hobj->GetMinimum() ;
1486  float hmax = hobj->GetMaximum() ;
1487  float hmid = hmin+0.12*(hmax-hmin);
1488  float sz = latex.GetTextSize();
1489  latex.SetTextSize(0.045);
1490  latex.SetTextColor(2);
1491  latex.SetTextAngle(90);
1492  latex.SetTextAlign(22);
1493  for (int secn = 1; secn < 13; secn++) {
1494  float phisec = 87 - secn*30;
1495  while (phisec < 1) phisec += 360;
1496  latex.DrawLatex(phisec,hmid,Form("%d / %d",secn,(23-secn)%12 + 13));
1497  }
1498  latex.SetTextSize(sz);
1499  latex.SetTextColor(1);
1500  latex.SetTextAngle(0);
1501  }
1502 
1503  if ((chkdim == 2) && (oName.Contains("TPC_charge"))) {
1504  TH2F* hobj_TPC_charge = (TH2F*) hobj;
1505 
1506  TProfile *prof_hobjTPC = (TProfile*) hobj_TPC_charge->ProfileX();
1507  prof_hobjTPC->SetMarkerStyle(20);
1508  prof_hobjTPC->SetMarkerSize(0.6);
1509  prof_hobjTPC->SetMarkerColor(6);
1510  prof_hobjTPC->SetLineColor(6);
1511 
1512  //landau fit
1513  static TF1 *flandau = 0;
1514  if (!flandau) flandau = new TF1("flandau", "[0]*TMath::Landau(x,[1],[2])",0,200);
1515  flandau->SetParameters(2e-3*(hobj->GetEntries()), 125, 30);
1516  hobj_TPC_charge->FitSlicesY(flandau);
1517  hobj->Draw("colz");
1518  TH1D *mean_landau = (TH1D*) (gDirectory->Get(Form("%s_1",hobj_TPC_charge->GetName())));
1519  if (mean_landau) {
1520  mean_landau->SetMarkerStyle(20);
1521  mean_landau->SetMarkerSize(0.6);
1522  mean_landau->SetMarkerColor(1);
1523  mean_landau->Draw("same p");
1524  } else {
1525  LOG_WARN << "TPC_charge Landau FitSlicesY failed for " << hobj->GetName() << endm;
1526  }
1527 
1528  //rms landau
1529  //TH1D *mean_landau2 = (TH1D*) (gDirectory->Get(Form("%s_2",hobj_TPC_charge_lan->GetName())));
1530  //if (mean_landau2) {
1531  // mean_landau2->SetMarkerStyle(20);
1532  // mean_landau2->SetMarkerSize(0.6);
1533  // mean_landau2->SetMarkerColor(2);
1534  // mean_landau2->Draw("same p");
1535  //}
1536 
1537  prof_hobjTPC->Draw("same p");
1538 
1539  //draw a legend
1540  TLegend *ilegend = new TLegend(0.15,0.80,0.38,0.90);
1541  ilegend->SetFillColor(0);
1542  ilegend->SetHeader("Legend");
1543  ilegend->SetMargin(0.25);
1544  ilegend->AddEntry(prof_hobjTPC,"Profile mean","pz");
1545  ilegend->AddEntry(mean_landau,"Landau MPV","pz");
1546  ilegend->Draw();
1547  }
1548 
1549  if (padAdvance) {if (gPad) gPad->Update();}
1550  else {if (!analRepeat) padCount--;}
1551 
1552  } // analRepeat for loop
1553 
1554  // Run reference analysis...(on first loop, before we forgot hobj)
1555  if (hobjR) {
1556  StHistUtilRef* huR = 0;
1557  if (m_refCuts) {
1558  // try: full name
1559  huR = (StHistUtilRef*) (m_refCuts->FindObject(oname));
1560  if (!huR) {
1561  // try: strip just maker from name
1562  Int_t tempint = -1;
1563  TString onamebase = StripPrefixes(oname,tempint,-1);
1564  huR = (StHistUtilRef*) (m_refCuts->FindObject(onamebase.Data()));
1565  if (!huR) {
1566  // try: strip just trigger type from name
1567  onamebase = StripPrefixes(oname,tempint,1);
1568  huR = (StHistUtilRef*) (m_refCuts->FindObject(onamebase.Data()));
1569  if (!huR) {
1570  // try: strip maker and trigger type from name
1571  onamebase = StripPrefixes(oname,tempint,0);
1572  huR = (StHistUtilRef*) (m_refCuts->FindObject(onamebase.Data()));
1573  }
1574  }
1575  }
1576  }
1577  double result = 0;
1578 
1579  // default to Kolm. max distance, no cut
1580  int mode = ( huR ? huR->Mode : 2 );
1581  double cut = ( huR ? huR->Cut : 0);
1582 
1583  // modes:
1584  switch (mode) {
1585  case (0) : // Chi2
1586  result = hobjO->Chi2Test(hobjR,(huR ? huR->Options() : "WW"));
1587  break;
1588  case (1) : // Kolmogorov probability
1589  // Note that Sumw2() seems to affect the way histograms are drawn,
1590  // but Kolmogorov test complains in current ROOT version (won't in
1591  // future versions). Don't know what to do for now.
1592  //if (hobjO->GetSumw2N() == 0) hobjO->Sumw2();
1593  //if (hobjR->GetSumw2N() == 0) hobjR->Sumw2();
1594  result = hobjO->KolmogorovTest(hobjR,(huR ? huR->Options() : ""));
1595  break;
1596  case (2) : // Kolmogorov maximum distance
1597  // Seems to work for both 1D and 2D
1598  TString analOpts = (huR ? huR->Options() : "");
1599  analOpts.ToUpper();
1600  if (! analOpts.Contains('M')) analOpts += 'M';
1601  result = 1.0 - hobjO->KolmogorovTest(hobjR,analOpts.Data());
1602  break;
1603  }
1604  bool analPass = (result >= cut);
1605 
1606  TString score = Form("Score: %4.2f (%s vs. %4.2f)",result,
1607  (analPass ? "PASS" : "FAIL"),cut);
1608 
1609  if (m_PrintMode & QAU1<<QAprintIndivRef)
1610  gPad->Print(Form("Ref_%s%s",oName.Data(),m_OutIndividuals.Data()));
1611  if (m_QAShiftMode)
1612  gPad->Print(Form("Ref_%s.png",oName.Data()));
1613 
1614  if (objPad) {
1615  objPad->cd();
1616  float sz = latex.GetTextSize();
1617  latex.SetTextSize(0.038);
1618  latex.SetTextAngle(90);
1619  latex.SetTextAlign(11);
1620  latex.SetTextColor(analPass ? kGreen+4 : kRed+2);
1621  latex.DrawTextNDC(0.999,0.001,score.Data());
1622  objPad->Update();
1623  latex.SetTextColor(1);
1624  latex.SetTextSize(sz);
1625  if (m_PrintMode & QAU1<<QAprintIndiv)
1626  gPad->Print(Form("%s%s",oName.Data(),m_OutIndividuals.Data()));
1627  if (m_QAShiftMode)
1628  gPad->Print(Form("%s.png",oName.Data()));
1629  }
1630 
1631 
1632  LOG_INFO << Form(" - %d. Reference Test (mode=%d) %s",
1633  histReadCounter,mode,score.Data()) << endm;
1634  if (strlen(m_refResultsFile)) {
1635  if (!R_ostr) R_ostr = new ofstream(m_refResultsFile);
1636  (*R_ostr) << m_CurPage << " " << curPad << " " << oName << " " << result << endl;
1637  }
1638  } else {
1639  if (m_PrintMode & QAU1<<QAprintIndiv)
1640  gPad->Print(Form("%s%s",oName.Data(),m_OutIndividuals.Data()));
1641  if (m_QAShiftMode)
1642  gPad->Print(Form("%s.png",oName.Data()));
1643  if (strlen(m_refResultsFile)) {
1644  if (!R_ostr) R_ostr = new ofstream(m_refResultsFile);
1645  (*R_ostr) << m_CurPage << " " << curPad << " " << oName << " 1.0" << endl;
1646  }
1647  }
1648 
1649  }
1650  }
1651 
1652 //NOTE! (13jan00,kt)
1653 //--> obj->Draw just appends the histogram to the list
1654 // --> you must update the current pad (gPad) or the whole big pad (graphPad)
1655 // to actually see the stupid thing
1656 
1657 // just ended actual loop over histograms !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1658  }
1659 
1660  if (C_ostr) delete C_ostr;
1661  if (R_ostr) delete R_ostr;
1662  if (root_ofile) delete root_ofile;
1663 
1664  CloseOutFile();
1665  return histCounter;
1666 }
1667 
1668 //_____________________________________________________________________________
1669 
1670 
1671 TList* StHistUtil::FindHists(const Char_t *dirName, const Char_t *withPrefix)
1672 {
1673 
1674 // NOTE - must have already used method SetPntrToMaker to get the
1675 // pointer m_PntrToMaker to an StMaker class!
1676 //
1677 
1678 // Method 1 ------------------------------------------------
1679 // Method FindHists -->
1680 // Find pointer to histograms under a Maker
1681 
1682  TList *dList=0;
1683 
1684  LOG_INFO << " Beg: FindHists, dList pointer = " << dList << endm;
1685 
1686 //---- First look under Maker for histograms ==>
1687 //They should show up in your Maker's directory, so search for them there,
1688 // i.e. MakerName/.hist is where they'd be
1689 // Note: Histograms is a method of StMaker
1690 //---- If you have a chain, you'll always have the .hist directory, so
1691 // have to check if there's really anything there (so use First method)
1692 
1693 //
1694  PathCopy(m_dirName,dirName);
1695  StMaker *temp = m_PntrToMaker->GetMaker(m_dirName);
1696 
1697  if (temp) {
1698  LOG_INFO << "FindHists - found pointer to maker" << endm;
1699  dList = temp->Histograms();
1700  }
1701 
1702 // Now check to see if any histograms exist here (look for something in
1703 // the list (test)
1704  TObject *test=0;
1705  if (dList) test = dList->First();
1706  if (test){
1707  LOG_INFO << " FindHists - found hist. in Maker-Branch " << endm;
1708  }
1709 
1710  LOG_INFO << " Mid: FindHists, dList pointer = " << dList << endm;
1711  LOG_INFO << " Mid: FindHists, test pointer = " << test << endm;
1712 
1713 // If you have the pointer but the hist. really aren't here, set
1714 // the pointer back to zero
1715  if (!test) dList = 0;
1716 
1717  LOG_INFO << " Mid2: FindHists, dList pointer = " << dList << endm;
1718  LOG_INFO << " Mid2: FindHists, test pointer = " << test << endm;
1719 
1720 
1721  if (!dList) {
1722 
1723 // Method 2 -----------------------------------------------------
1724 
1725 //-------------- Now try and see if they're in histBranch from output of bfc
1726 
1727 
1728  St_DataSet *hist=0;
1729  hist = m_PntrToMaker->GetDataSet("hist");
1730  if (hist) {
1731 // hist->ls(9);
1732 
1733 // must look in dirNameHist
1734 // use TString to append "Hist" to the dirName
1735 // += is overloaded operator of TString
1736 
1737  TString hBN(m_dirName);
1738  hBN += "Hist";
1739 
1740 //find particular branch
1741  St_DataSet *QAH = 0;
1742  QAH = hist->Find(hBN.Data());
1743 // or can create iterator and look over all branches
1744 
1745 //now get the list of histograms
1746  if (QAH) {
1747  dList = (TList *)QAH->GetObject();
1748  }
1749 
1750  }
1751 
1752 // now have we found them?
1753  if (dList){
1754  LOG_INFO << " FindHists - found hist. in histBranch, with name: "
1755  << m_dirName << endm;
1756  }
1757  else {
1758  LOG_INFO << " FindHists - histogram branch has not been found for branch --> "
1759  << m_dirName << endm;
1760  }
1761 
1762  }
1763 
1764  if (dList && (withPrefix || m_ListOfPrint)) dList = TrimListByPrefix(dList,withPrefix);
1765 
1766  LOG_INFO << " FindHists, dList pointer = " << dList << endm;
1767 
1768 
1769  return dList;
1770 }
1771 //_____________________________________________________________________________
1772 
1773 TList* StHistUtil::FindHists(TFile* histFile, const Char_t* withPrefix) {
1774  if (!histFile) return 0;
1775  TList* dList = histFile->GetList();
1776  if (dList->GetSize() == 0) {
1777  histFile->ReadAll();
1778  dList = histFile->GetList();
1779  }
1780 
1781  TObject* test = (dList ? dList->First() : 0);
1782  LOG_INFO << " Mid5: FindHists, dList pointer = " << dList << endm;
1783  LOG_INFO << " Mid5: FindHists, test pointer = " << test << endm;
1784  if (!test) dList = 0;
1785 
1786  if (dList && (withPrefix || m_ListOfPrint)) dList = TrimListByPrefix(dList,withPrefix);
1787  return dList;
1788 }
1789 //_____________________________________________________________________________
1790 
1791 TList* StHistUtil::TrimListByPrefix(TList* dList, const Char_t* withPrefix) {
1792  TList* dList2 = new TList;
1793 
1794  //Now want to loop over all histograms
1795  // Create an iterator
1796  TIter nextObj(dList);
1797  TObject *obj = 0;
1798  int withPrefixNumber = -1;
1799  int prefixNumber = -1;
1800  if (withPrefix) StripPrefixes(withPrefix,withPrefixNumber);
1801  while ((obj = nextObj())) {
1802  Bool_t addIt = kTRUE;
1803  if (withPrefix) {
1804  StripPrefixes(obj->GetName(),prefixNumber);
1805  if (prefixNumber != withPrefixNumber) addIt = kFALSE;
1806  }
1807  if (addIt && ((!m_ListOfPrint) ||
1808  (obj->InheritsFrom("TH1") &&
1809  m_ListOfPrint->FindObject(obj->GetName())))) dList2->AddLast(obj);
1810  }
1811  m_ItemsToClear->Add(dList2);
1812  return dList2;
1813 }
1814 //_____________________________________________________________________________
1815 
1816 
1817 Int_t StHistUtil::ListHists(const Char_t *dirName)
1818 {
1819 // Method ListHists -->
1820 // List of all histograms
1821 
1822  if (Debug()) {
1823  LOG_INFO << " **** Now in StHistUtil::ListHists **** " << endm;
1824  }
1825 
1826 // get the TList pointer to the histograms:
1827  TList* dirList = (m_PntrToMaker ? FindHists(dirName) : FindHists(m_PntrToPlainFile));
1828 
1829  if (!dirList) { LOG_INFO << " ListHists - histograms not available! " << endm; }
1830 
1831 //Now want to loop over all histograms
1832 // Create an iterator
1833  TIter nextObj(dirList);
1834  Int_t histReadCount = 0;
1835  TObject *obj = 0;
1836 
1837 // use = here instead of ==, because we are setting obj equal to nextObj and then seeing if it's T or F
1838  while ((obj = nextObj())) {
1839 
1840 // now check if obj is a histogram
1841  if (obj->InheritsFrom("TH1")) {
1842 
1843  histReadCount++;
1844 // \n means newline, \" means print a quote
1845 // LOG_INFO << Form(" %d. Have histogram Type %s, Name %s with Title=\"%s\"\n",histReadCount,obj->ClassName(),obj->GetName(),obj->GetTitle()) << endm;
1846  LOG_INFO << " ListHists: Hist No. " << histReadCount << ", Type: " << obj->ClassName()
1847  << ", Name: " << obj->GetName() << ", Title \"" << obj->GetTitle() << "\" "<< endm;
1848  }
1849  }
1850 
1851  LOG_INFO << " ListHists: Total No. Histograms Booked = " << histReadCount <<endm;
1852  return histReadCount;
1853 }
1854 
1855 
1856 //_____________________________________________________________________________
1857 
1858 Int_t StHistUtil::PrintInfoHists(TList *dirList, const Char_t *fname )
1859 {
1860 
1861  LOG_INFO << " **** Now in StHistUtil::PrintInfoHists **** " << endm;
1862  LOG_INFO << " output file = " << fname << endm;
1863 
1864  ofstream fout(fname);
1865 
1866  if (!dirList) { LOG_INFO << " PrintInfoHists - histograms not available! " << endm; }
1867 
1868  Int_t histInfoCount = 0;
1869 
1870  if (dirList){
1871 
1872 //Now want to loop over all histograms
1873 // Create an iterator
1874  TIter nextObj(dirList);
1875  TObject *obj = 0;
1876 
1877  LOG_INFO << " Hist #, Name, #Entries, Mean, RMS " << endm;
1878  fout << " Hist #, Name, #Entries, Mean, RMS " << endl;
1879 
1880 // use = instead of ==, because we are setting obj equal to nextObj and then seeing if it's T or F
1881 
1882  while ((obj = nextObj())) {
1883 
1884 // now check if obj is a histogram
1885  if (obj->InheritsFrom("TH1")) {
1886 
1887  histInfoCount++;
1888 
1889  LOG_INFO <<
1890  histInfoCount << " " <<
1891  obj->GetName() << " " <<
1892  ((TH1 *)obj)->GetEntries() << " " <<
1893  ((TH1 *)obj)->GetMean() << " " <<
1894  ((TH1 *)obj)->GetRMS() << " " <<
1895  endm;
1896 
1897  fout <<
1898  histInfoCount << " " <<
1899  obj->GetName() << " " <<
1900  ((TH1 *)obj)->GetEntries() << " " <<
1901  ((TH1 *)obj)->GetMean() << " " <<
1902  ((TH1 *)obj)->GetRMS() << " " <<
1903  endl;
1904 
1905  }
1906  }
1907  } // if dirList
1908 
1909  LOG_INFO << " PrintInfoHists: # hist read = " << histInfoCount <<endm;
1910 
1911  return histInfoCount;
1912 }
1913 
1914 
1915 //_____________________________________________________________________________
1916 
1917 
1918 Int_t StHistUtil::CopyHists(TList *dirList)
1919 {
1920  if (Debug()) {
1921  LOG_INFO << " **** Now in StHistUtil::CopyHists **** " << endm;
1922  }
1923 
1924  if (!dirList) { LOG_INFO << " StHistUtil::CopyHists - histogram Pointer not set! " << endm; }
1925 
1926 // create array of pointers to the new histograms I will create
1927 
1928  Int_t tempint,ijk=0;
1929  Int_t histCopyCount = 0;
1930 
1931  if (dirList){
1932  TIter nextObj(dirList);
1933  TObject *obj = 0;
1934  while ((obj = nextObj())) {
1935  if (obj->InheritsFrom("TH1") &&
1936  (!m_ListOfPrint || (m_ListOfPrint->FindObject(obj->GetName())))) {
1937  histCopyCount++;
1938  if (ijk >= maxHistCopy - 1){
1939  Int_t newMaxHistCopy = maxHistCopy * 4;
1940  TH1** temp1 = new TH1ptr[newMaxHistCopy];
1941  memset(temp1,0,newMaxHistCopy*sizeOfTH1Ptr);
1942  memcpy(temp1,newHist,maxHistCopy*sizeOfTH1Ptr);
1943  delete [] newHist;
1944  newHist = temp1;
1945  maxHistCopy = newMaxHistCopy;
1946  } // if ijk
1947  newHist[ijk] = ((TH1 *)obj->Clone());
1948  if (ignorePrefixes) {
1949  newHist[ijk]->SetName (StripPrefixes(newHist[ijk]->GetName (),tempint).Data());
1950  newHist[ijk]->SetTitle(StripPrefixes(newHist[ijk]->GetTitle(),tempint).Data());
1951  }
1952  ijk++;
1953  } // if obj
1954  } // while obj
1955  } // if dirList
1956 
1957  LOG_INFO << " ListHists: Total No. Histograms Copied = " <<
1958  histCopyCount <<endm;
1959 
1960 // Now see if we can find these copies:
1961  // Int_t imk = 0;
1962  //for (imk=0;imk<histCopyCount;imk++) {
1963  // if (newHist[imk]->InheritsFrom("TH1")) {
1964  // LOG_INFO << " !!! NEW Type: " << newHist[imk]->ClassName() <<
1965  // ", Name: " << newHist[imk]->GetName() <<
1966  // ", Title: " << newHist[imk]->GetTitle() <<
1967  // ", Max: " << ((TH1 *)newHist[imk])->GetMaximum() << endm;
1968  // }
1969  //}
1970 
1971  return histCopyCount;
1972 }
1973 
1974 //_____________________________________________________________________________
1975 
1976 // **** IMPORTANT! *****
1977 // THIS METHOD ASSUMES YOU HAVE ALREADY USED CopyHists TO PUT
1978 // HISTOGRAMS FROM 1 FILE INTO newHist array
1979 // -- this method is used in subsequent files!
1980 
1981 Int_t StHistUtil::AddHists(TList *dirList,Int_t numHistCopy)
1982 {
1983  if (Debug()) {
1984  LOG_INFO << " **** Now in StHistUtil::AddHists **** " << endm;
1985  }
1986  // LOG_INFO << " num hists to copy = " << numHistCopy << endm;
1987 
1988  if (!dirList) { LOG_INFO <<
1989  " StHistUtil::AddHists - histogram Pointer not set! " << endm; }
1990 
1991  Int_t histAddCount = 0;
1992  Int_t tempInt=0;
1993 
1994  if (dirList){
1995  if (numHistCopy < 0) numHistCopy = dirList->GetSize();
1996  TIter nextObj(dirList);
1997  TObject *obj = 0;
1998 
1999  while ((obj = nextObj())) {
2000  if (obj->InheritsFrom("TH1")) {
2001  TString oName = obj->GetName();
2002  if (ignorePrefixes) oName = StripPrefixes(oName.Data(),tempInt);
2003 // now want to add these histograms to the copied ones:
2004  Int_t tempint,imk = 0;
2005  Bool_t notfound = true;
2006  for (imk=0;imk<maxHistCopy;imk++) {
2007  if (newHist[imk]) {
2008  TString nName = newHist[imk]->GetName();
2009  if (ignorePrefixes) nName = StripPrefixes(nName.Data(),tempInt);
2010  if (! (nName.CompareTo(oName))) {
2011  //LOG_INFO << " ---- hist num to add --- " << imk << endm;
2012  newHist[imk]->Add((TH1 *)obj);
2013  histAddCount++;
2014  notfound = false;
2015  //LOG_INFO << " !!! Added histograms with Name: " << newHist[imk]->GetName() << endm;
2016  } // strcmp
2017  } else break; // ran out of existing hists
2018  } // loop over imk
2019 
2020  if (notfound) {
2021  // Hist doesn't exist yet, so let's add it
2022  if (imk >= maxHistCopy-1){
2023  Int_t newMaxHistCopy = maxHistCopy * 4;
2024  TH1** temp1 = new TH1ptr[newMaxHistCopy];
2025  memset(temp1,0,newMaxHistCopy*sizeOfTH1Ptr);
2026  memcpy(temp1,newHist,maxHistCopy*sizeOfTH1Ptr);
2027  delete [] newHist;
2028  newHist = temp1;
2029  maxHistCopy = newMaxHistCopy;
2030  } // if imk
2031  newHist[imk] = ((TH1 *)obj->Clone());
2032  if (ignorePrefixes) {
2033  newHist[imk]->SetName (StripPrefixes(newHist[imk]->GetName (),tempint).Data());
2034  newHist[imk]->SetTitle(StripPrefixes(newHist[imk]->GetTitle(),tempint).Data());
2035  }
2036  numHistCopy++;
2037  histAddCount++;
2038 
2039  } // notfound
2040  } // if obj inherits from th1
2041  } //while
2042  } //dirlist
2043 
2044  LOG_INFO << " StHistUtil::AddHists: Total No. Histograms Added = " <<
2045  histAddCount <<endm;
2046 
2047 
2048  return histAddCount;
2049 }
2050 
2051 //_____________________________________________________________________________
2052 
2053 
2054 Int_t StHistUtil::ExamineLogYList()
2055 {
2056 // Method ExamineLogYList
2057 // List of all histograms that will be drawn with logy scale
2058 
2059  if (Debug()) {
2060  LOG_INFO << " **** Now in StHistUtil::ExamineLogYList **** " << endm;
2061  }
2062 
2063 // m_ListOfLogY - is a list of log plots
2064 // construct a TObject
2065  TObject *obj = 0;
2066 // construct a TIter ==> () is an overloaded operator in TIter
2067  TIter nextObj(m_ListOfLogY);
2068  Int_t LogYCount = 0;
2069 
2070 // use = here instead of ==, because we are setting obj equal to nextObj and then seeing if it's T or F
2071  while ((obj = nextObj())) {
2072 
2073  if (Debug()) { LOG_INFO << " StHistUtil::ExamineLogYList has hist " << obj->GetName() << endm; }
2074  LogYCount++;
2075 
2076  }
2077 
2078  LOG_INFO << " Now in StHistUtil::ExamineLogYList, No. Hist. in LogY scale = " << LogYCount <<endm;
2079  return LogYCount;
2080 }
2081 
2082 //_____________________________________________________________________________
2083 
2084 
2085 Int_t StHistUtil::ExamineLogXList()
2086 {
2087 // Method ExamineLogXList
2088 // List of all histograms that will be drawn with logX scale
2089 
2090  if (Debug()) {
2091  LOG_INFO << " **** Now in StHistUtil::ExamineLogXList **** " << endm;
2092  }
2093 
2094 // m_ListOfLogX - is a list of log plots
2095 // construct a TObject
2096  TObject *obj = 0;
2097 // construct a TIter ==> () is an overloaded operator in TIter
2098  TIter nextObj(m_ListOfLogX);
2099  Int_t LogXCount = 0;
2100 
2101 // use = here instead of ==, because we are setting obj equal to nextObj and then seeing if it's T or F
2102  while ((obj = nextObj())) {
2103 
2104  if (Debug()) {
2105  LOG_INFO << " StHistUtil::ExamineLogXList has hist " << obj->GetName() << endm;
2106  }
2107  LogXCount++;
2108 
2109  }
2110 
2111  LOG_INFO << " Now in StHistUtil::ExamineLogXList, No. Hist. in LogX scale = " << LogXCount <<endm;
2112  return LogXCount;
2113 }
2114 
2115 //_____________________________________________________________________________
2116 
2117 
2118 Int_t StHistUtil::ExaminePrintList()
2119 {
2120 // Method ExaminePrintList
2121 // List of all histograms that will be drawn,printed
2122 
2123  if (Debug()) {
2124  LOG_INFO << " **** Now in StHistUtil::ExaminePrintList **** " << endm;
2125  }
2126 
2127 // m_ListOfPrint - is a list of hist to print,draw
2128 
2129 // check if there is a list
2130  if (!m_ListOfPrint){
2131  LOG_INFO << " no subset print list was setup - all hist in directory will be printed " << endm;
2132  // return PrintCount;
2133  return 0;
2134  }
2135 
2136 // construct a TObject
2137  TObject *obj = 0;
2138 
2139 // construct a TIter ==> () is an overloaded operator in TIter
2140  TIter nextObj(m_ListOfPrint);
2141  Int_t PrintCount = 0;
2142 
2143 // use = here instead of ==, because we are setting obj equal to nextObj and then seeing if it's T or F
2144  while ((obj = nextObj())) {
2145 
2146  if (Debug()) {
2147  LOG_INFO << " StHistUtil::ExaminePrintList has hist " << obj->GetName() << endm;
2148  }
2149  PrintCount++;
2150 
2151  }
2152 
2153  LOG_INFO << " Now in StHistUtil::ExaminePrintList, No. Hist. to Print,Draw = " << PrintCount <<endm;
2154  return m_ListOfPrint->GetSize();
2155 }
2156 
2157 //_____________________________________________________________________________
2158 
2159 
2160 Int_t StHistUtil::AddToLogYList(const Char_t *HistName){
2161 // Method AddToLogYList
2162 // making list of all histograms that we want drawn with LogY scale
2163 
2164  if (Debug()) {
2165  LOG_INFO << " **** Now in StHistUtil::AddToLogYList **** " << endm;
2166  }
2167 
2168 // Since I'm creating a new list, must delete it in the destructor!!
2169 //make a new TList on heap(persistant); have already defined m_ListOfLogY in header file
2170  if (!m_ListOfLogY) m_ListOfLogY = new TList;
2171 
2172 // the add method for TList requires a TObject input (also can use TObjString)
2173 // create TObjString on heap
2174  TObjString *HistNameObj = new TObjString(HistName);
2175 
2176 // - check if it's already on the list - use FindObject method of TList
2177  TObject *lobj = 0;
2178  lobj = m_ListOfLogY->FindObject(HistName);
2179 // now can use Add method of TList
2180  if (!lobj) {
2181  m_ListOfLogY->Add(HistNameObj);
2182  if (Debug()) {
2183  LOG_INFO << " StHistUtil::AddToLogYList: " << HistName <<endm;
2184  }
2185  } else {
2186  LOG_INFO << " StHistUtil::AddToLogYList: " << HistName << " already in list - not added" <<endm;
2187  }
2188 
2189 // return using a method of TList (inherits GetSize from TCollection)
2190  return m_ListOfLogY->GetSize();
2191 }
2192 
2193 
2194 //_____________________________________________________________________________
2195 
2196 
2197 Int_t StHistUtil::AddToLogXList(const Char_t *HistName){
2198 // Method AddToLogXList
2199 // making list of all histograms that we want drawn with LogX scale
2200 
2201  if (Debug()) {
2202  LOG_INFO << " **** Now in StHistUtil::AddToLogXList **** " << endm;
2203  }
2204 
2205 // Since I'm creating a new list, must delete it in the destructor!!
2206 //make a new TList on heap(persistant); have already defined m_ListOfLogX in header file
2207  if (!m_ListOfLogX) m_ListOfLogX = new TList;
2208 
2209 // the add method for TList requires a TObject input (also can use TObjString)
2210 // create TObjString on heap
2211  TObjString *HistNameObj = new TObjString(HistName);
2212 
2213 // - check if it's already on the list - use FindObject method of TList
2214  TObject *lobj = 0;
2215  lobj = m_ListOfLogX->FindObject(HistName);
2216 // now can use Add method of TList
2217  if (!lobj) {
2218  m_ListOfLogX->Add(HistNameObj);
2219  if (Debug()) {
2220  LOG_INFO << " StHistUtil::AddToLogXList: " << HistName <<endm;
2221  }
2222  } else {
2223  LOG_INFO << " StHistUtil::AddToLogXList: " << HistName << " already in list - not added" <<endm;
2224  }
2225 
2226 // return using a method of TList (inherits GetSize from TCollection)
2227  return m_ListOfLogX->GetSize();
2228 }
2229 
2230 
2231 //_____________________________________________________________________________
2232 
2233 
2234 Int_t StHistUtil::AddToPrintList(const Char_t *HistName){
2235 
2236 // Method AddToPrintList
2237 // making list of all histograms that we want drawn,printed
2238 
2239  if (Debug()) {
2240  LOG_INFO << " **** Now in StHistUtil::AddToPrintList **** " << endm;
2241  }
2242 
2243 // Since I'm creating a new list, must delete it in the destructor!!
2244 //make a new TList on heap(persistant); have already defined m_ListOfPrint in header file
2245  if (!m_ListOfPrint) m_ListOfPrint = new TList;
2246 
2247 // the add method for TList requires a TObject input (also can use TObjString)
2248 // create TObjString on heap
2249  TObjString *HistNameObj = new TObjString(HistName);
2250 
2251 // now can use Add method of TList
2252  if (!m_ListOfPrint->Contains(HistName)) {
2253  m_ListOfPrint->Add(HistNameObj);
2254  if (Debug()) {
2255  LOG_INFO << " StHistUtil::AddToPrintList: " << HistName <<endm;
2256  }
2257  } else {
2258  LOG_INFO << " StHistUtil::AddToPrintList: " << HistName << " already in list - not added" <<endm;
2259  }
2260 
2261 // return using a method of TList (inherits GetSize from TCollection)
2262  return m_ListOfPrint->GetSize();
2263 
2264 }
2265 
2266 //_____________________________________________________________________________
2267 
2268 Int_t StHistUtil::RemoveFromLogYList(const Char_t *HistName){
2269 // Method RemoveFromLogYList
2270 // remove hist from list that we want drawn with LogY scale
2271 
2272  if (Debug()) {
2273  LOG_INFO << " **** Now in StHistUtil::RemoveFromLogYList **** " << endm;
2274  }
2275 
2276 // check if list exists:
2277  if (m_ListOfLogY) {
2278 
2279 // the remove method for TList requires a TObject input
2280 // - check if it's on the list - use FindObject method of TList
2281  TObject *lobj = 0;
2282  lobj = m_ListOfLogY->FindObject(HistName);
2283 // now can use Remove method of TList
2284  if (lobj) {
2285  m_ListOfLogY->Remove(lobj);
2286  if (Debug()) {
2287  LOG_INFO << " RemoveLogYList: " << HistName << " has been removed from list" <<endm;
2288  }
2289  } else {
2290  LOG_INFO << " RemoveLogYList: " << HistName << " not on list - not removing" <<endm;
2291  }
2292 
2293  // return using a method of TList (inherits GetSize from TCollection)
2294  return m_ListOfLogY->GetSize();
2295  }
2296 
2297  LOG_INFO << " RemoveLogYList: " << HistName << " not on list - not removing" <<endm;
2298  return 0;
2299 }
2300 
2301 
2302 //_____________________________________________________________________________
2303 
2304 Int_t StHistUtil::RemoveFromLogXList(const Char_t *HistName){
2305 // Method RemoveFromLogXList
2306 // remove hist from list that we want drawn with LogX scale
2307 
2308  if (Debug()) {
2309  LOG_INFO << " **** Now in StHistUtil::RemoveFromLogXList **** " << endm;
2310  }
2311 
2312 // check if list exists:
2313  if (m_ListOfLogX) {
2314 
2315 // the remove method for TList requires a TObject input
2316 // - check if it's on the list - use FindObject method of TList
2317  TObject *lobj = 0;
2318  lobj = m_ListOfLogX->FindObject(HistName);
2319 // now can use Remove method of TList
2320  if (lobj) {
2321  m_ListOfLogX->Remove(lobj);
2322  if (Debug()) {
2323  LOG_INFO << " RemoveLogXList: " << HistName << " has been removed from list" <<endm;
2324  }
2325  } else {
2326  LOG_INFO << " RemoveLogXList: " << HistName << " not on list - not removing" <<endm;
2327  }
2328 
2329  // return using a method of TList (inherits GetSize from TCollection)
2330  return m_ListOfLogX->GetSize();
2331  }
2332 
2333  LOG_INFO << " RemoveLogXList: " << HistName << " not on list - not removing" <<endm;
2334  return 0;
2335 }
2336 
2337 
2338 //_____________________________________________________________________________
2339 
2340 Int_t StHistUtil::RemoveFromPrintList(const Char_t *HistName){
2341 // Method RemoveFromPrintList
2342 // remove hist from list that we want drawn,printed
2343 
2344  if (Debug()) {
2345  LOG_INFO << " **** Now in StHistUtil::RemoveFromPrintList **** " << endm;
2346  }
2347 
2348 // check if list exists:
2349  if (m_ListOfPrint) {
2350 
2351 // the remove method for TList requires a TObject input
2352 // - check if it's on the list - use FindObject method of TList
2353  TObject *lobj = 0;
2354  lobj = m_ListOfPrint->FindObject(HistName);
2355 // now can use Remove method of TList
2356  if (lobj) {
2357  m_ListOfPrint->Remove(lobj);
2358  if (Debug()) {
2359  LOG_INFO << " RemovePrintList: " << HistName << " has been removed from list" <<endm;
2360  }
2361  } else {
2362  LOG_INFO << " RemovePrintList: " << HistName << " not on list - not removing" <<endm;
2363  }
2364 
2365  // return using a method of TList (inherits GetSize from TCollection)
2366  return m_ListOfPrint->GetSize();
2367  }
2368 
2369  LOG_INFO << " RemovePrintList: " << HistName << " not on list - not removing" <<endm;
2370  return 0;
2371 }
2372 
2373 
2374 //_____________________________________________________________________________
2375 // Method SetDefaultLogYList
2376 // - create default list of histograms we want plotted in LogY scale
2377 
2378 void StHistUtil::SetDefaultLogYList(const Char_t *dirName)
2379 {
2380 // Method SetDefaultLogYList
2381 // - create default list of histograms we want plotted in LogY scale
2382 
2383  if (Debug()) {
2384  LOG_INFO << " **** Now in StHistUtil::SetDefaultLogYList **** " << endm;
2385  }
2386 
2387 
2388  PathCopy(m_dirName,dirName);
2389  TString type;
2390  if (!strcmp(m_dirName,"QA"))
2391  type = "Tab";
2392  else if (!strcmp(m_dirName,"EventQA"))
2393  type = "StE";
2394  else // default for now
2395  type = "StE";
2396 
2397  const Char_t* sdefList[] = {
2398  #include "St_QA_Maker/QAhlist_logy.h"
2399  };
2400 
2401  Int_t lengofList = sizeof(sdefList)/sizeOfCharPtr;
2402  Int_t numLog = 0;
2403  Int_t ilg = 0;
2404  for (ilg=0;ilg<lengofList;ilg++) {
2405  TString listString = sdefList[ilg];
2406  if (!(listString.BeginsWith("fcl") ||
2407  listString.BeginsWith("fms_qt_") ||
2408  listString.BeginsWith("fpd_channel_"))) {
2409  for (Int_t k=0; k<numOfPosPrefixes; k++) {
2410  ((listString = type) += possiblePrefixes[k]) += sdefList[ilg];
2411  numLog = AddToLogYList(listString.Data());
2412  }
2413  } else numLog = AddToLogYList(listString.Data());
2414  }
2415 
2416  LOG_INFO << " !!! StHistUtil::SetDefaultLogYList, # histogram put in list " << numLog << endm;
2417 
2418 }
2419 
2420 //_____________________________________________________________________________
2421 // Method SetDefaultLogXList
2422 // - create default list of histograms we want plotted in LogX scale
2423 
2424 void StHistUtil::SetDefaultLogXList(const Char_t *dirName)
2425 {
2426 // Method SetDefaultLogXList
2427 // - create default list of histograms we want plotted in LogX scale
2428 
2429  if (Debug()) {
2430  LOG_INFO << " **** Now in StHistUtil::SetDefaultLogXList **** " << endm;
2431  }
2432 
2433  PathCopy(m_dirName,dirName);
2434  TString type;
2435  if (!strcmp(m_dirName,"QA"))
2436  type = "Tab";
2437  else if (!strcmp(m_dirName,"EventQA"))
2438  type = "StE";
2439  else // default for now
2440  type = "StE";
2441 
2442  const Char_t* sdefList[] = {
2443  #include "St_QA_Maker/QAhlist_logx.h"
2444  };
2445 
2446  Int_t lengofList = sizeof(sdefList)/sizeOfCharPtr;
2447  Int_t numLog = 0;
2448  Int_t ilg = 0;
2449  for (ilg=0;ilg<lengofList;ilg++) {
2450  TString listString = sdefList[ilg];
2451  if (!(listString.BeginsWith("fcl") ||
2452  listString.BeginsWith("fms_qt_") ||
2453  listString.BeginsWith("fpd_channel_"))) {
2454  for (Int_t k=0; k<numOfPosPrefixes; k++) {
2455  ((listString = type) += possiblePrefixes[k]) += sdefList[ilg];
2456  numLog = AddToLogXList(listString.Data());
2457  }
2458  } else numLog = AddToLogXList(listString.Data());
2459  }
2460 
2461  LOG_INFO << " !!! StHistUtil::SetDefaultLogXList, # histogram put in list " << numLog << endm;
2462 
2463 }
2464 
2465 
2466 //_____________________________________________________________________________
2467 // Method SetDefaultPrintList
2468 // - create default list of histograms we want drawn,printed
2469 // - analType can be one of a number of predefined histogram lists,
2470 // or a file which has histogram names listed one per line
2471 // (files like $STAR/StRoot/St_QA_Maker/QAhlist*.h are properly
2472 // parsed as well, but histogram names are sufficient)
2473 
2474 void StHistUtil::SetDefaultPrintList(const Char_t *dirName, const Char_t *analType)
2475 {
2476 
2477  LOG_INFO << " **** Now in StHistUtil::SetDefaultPrintList **** " << endm;
2478 
2479  const Char_t **sdefList=0;
2480  Int_t lengofList = 0;
2481  bool mustDeleteList = false;
2482 
2483  PathCopy(m_dirName,dirName);
2484  TString type;
2485  if (!strcmp(m_dirName,"QA"))
2486  type = "Tab";
2487  else if (!strcmp(m_dirName,"EventQA"))
2488  type = "StE";
2489  else // default for now
2490  type = "StE";
2491 
2492 
2493 // If not analysis Type is set, then don't setup a list
2494  if ((!strcmp(analType,"")) || (!strcmp(analType,"All")) ) {
2495  LOG_INFO << " All histograms in directory will be printed/drawn, no list set" << endm;
2496  return;
2497  }
2498 
2499 // Cosmic Data Table QA list .................................................
2500  const Char_t* sdefList1[] = {
2501  #include "St_QA_Maker/QAhlist_QA_Cosmic.h"
2502  };
2503  if ((!strcmp(m_dirName,"QA")) && (!strcmp(analType,"Cosmic"))) {
2504  sdefList = sdefList1; lengofList = sizeof(sdefList1)/sizeOfCharPtr;
2505  }
2506 
2507 // Test Table QA list.........................................................
2508  const Char_t* sdefList2[] = {
2509  #include "St_QA_Maker/QAhlist_QA_TestQATable.h"
2510  };
2511  if ((!strcmp(m_dirName,"QA")) && (!strcmp(analType,"TestQATable"))) {
2512  sdefList = sdefList2; lengofList = sizeof(sdefList2)/sizeOfCharPtr;
2513  }
2514 
2515 // FTPC Table QA list.........................................................
2516  const Char_t* sdefList3[] = {
2517  #include "St_QA_Maker/QAhlist_QA_Ftpc.h"
2518  };
2519  if ((!strcmp(m_dirName,"QA")) && (!strcmp(analType,"Ftpc"))) {
2520  sdefList = sdefList3; lengofList = sizeof(sdefList3)/sizeOfCharPtr;
2521  }
2522 
2523 // FTPC Table QA list.........................................................
2524  const Char_t* sdefList4[] = {
2525  #include "St_QA_Maker/QAhlist_QA_MDC3.h"
2526  };
2527  if ((!strcmp(m_dirName,"FlowTag")) && (!strcmp(analType,"MDC3"))) {
2528  sdefList = sdefList4; lengofList = sizeof(sdefList4)/sizeOfCharPtr;
2529  }
2530 
2531 // St_QA_Maker histograms without svt and ftpc histograms.....................
2532  const Char_t* sdefList5[] = {
2533  #include "St_QA_Maker/QAhlist_QA_year1.h"
2534  };
2535  if ((!strcmp(m_dirName,"QA")) && (!strcmp(analType,"year1"))) {
2536  sdefList = sdefList5; lengofList = sizeof(sdefList5)/sizeOfCharPtr;
2537  }
2538 
2539 // St_QA_Maker histograms without the svt and ftpc histograms.................
2540  const Char_t* sdefList6[] = {
2541  #include "St_QA_Maker/QAhlist_EventQA_year1.h"
2542  };
2543  if ((!strcmp(m_dirName,"EventQA")) && (!strcmp(analType,"year1"))) {
2544  sdefList = sdefList6; lengofList = sizeof(sdefList6)/sizeOfCharPtr;
2545  }
2546 
2547 // St_QA_Maker histograms for QA shift........................................
2548  const Char_t* sdefList7[] = {
2549  #include "St_QA_Maker/QAhlist_QA_qa_shift.h"
2550  };
2551  if ((!strcmp(m_dirName,"QA")) && (!strcmp(analType,"qa_shift"))) {
2552  sdefList = sdefList7; lengofList = sizeof(sdefList7)/sizeOfCharPtr;
2553  }
2554 
2555 // St_QA_Maker histograms for QA shift........................................
2556  const Char_t* sdefList8[] = {
2557  #include "St_QA_Maker/QAhlist_EventQA_qa_shift.h"
2558  };
2559  if ((!strcmp(m_dirName,"EventQA")) && (!strcmp(analType,"qa_shift"))) {
2560  sdefList = sdefList8; lengofList = sizeof(sdefList8)/sizeOfCharPtr;
2561  }
2562 
2563 // St_QA_Maker histograms for tpcSectors......................................
2564  const Char_t* sdefList9[] = {
2565  #include "St_QA_Maker/QAhlist_tpcSectors.h"
2566  };
2567  if ((!strcmp(m_dirName,"EventQA")) && (!strcmp(analType,"tpcSectors"))) {
2568  sdefList = sdefList9; lengofList = sizeof(sdefList9)/sizeOfCharPtr;
2569  }
2570 
2571 // St_QA_Maker histograms for Svt.............................................
2572  const Char_t* sdefList10[] = {
2573  #include "St_QA_Maker/QAhlist_Svt.h"
2574  };
2575  if (!strcmp(analType,"Svt")) {
2576  sdefList = sdefList10; lengofList = sizeof(sdefList10)/sizeOfCharPtr;
2577  }
2578 
2579 // St_QA_Maker histograms for subsystems......................................
2580  const Char_t* sdefList11[] = {
2581  #include "St_QA_Maker/QAhlist_subsystems.h"
2582  };
2583  if (!strcmp(analType,"subsys")) {
2584  sdefList = sdefList11; lengofList = sizeof(sdefList11)/sizeOfCharPtr;
2585  }
2586 
2587  if (!sdefList) {
2588  // Try reading in a file as specified by analType
2589  ifstream analFile(analType);
2590  if (analFile.good()) {
2591  LOG_INFO << "Reading print list from: " << analType << endm;
2592  sdefList = new charptr[4096];
2593  mustDeleteList = true;
2594  char analBuffer[256];
2595  TString analString;
2596  Bool_t commenting = kFALSE;
2597  Int_t commentIdx = -1;
2598  while (analFile.getline(analBuffer,255)) {
2599  analString = analBuffer;
2600  if (commenting) {
2601  commentIdx = analString.Index("*/");
2602  if (commentIdx>=0) {
2603  analString.Remove(0,commentIdx+2);
2604  commenting = kFALSE;
2605  } else continue;
2606  }
2607  if (!commenting) {
2608  commentIdx = analString.Index("/*");
2609  if (commentIdx>=0) {
2610  analString.Remove(commentIdx);
2611  commenting = kTRUE;
2612  }
2613  }
2614  commentIdx = analString.Index("//");
2615  if (commentIdx>=0) analString.Remove(commentIdx);
2616  analString.Remove(TString::kBoth,' ').Remove(TString::kBoth,',').Remove(TString::kBoth,' ').Remove(TString::kBoth,'"');
2617  Int_t alen = analString.Length();
2618  if (alen<1) continue;
2619  Char_t* tempc = new Char_t[alen+1];
2620  strcpy(tempc,analString.Data());
2621  sdefList[lengofList] = tempc;
2622  lengofList++;
2623  }
2624  } else {
2625  LOG_WARN << "Could not find list of histograms specified by: " << analType << endm;
2626  }
2627  }
2628 
2629  Int_t numPrt = 0;
2630  Int_t ilg = 0;
2631  for (ilg=0;ilg<lengofList;ilg++) {
2632  TString ilgString = sdefList[ilg];
2633  if (mustDeleteList) delete [] sdefList[ilg];
2634  Bool_t addIt = kTRUE;
2635  if (ilgString.BeginsWith(":")) {
2636  Ssiz_t endDetSpec = ilgString.Index(":",1) + 1;
2637  TString detSpec = ilgString(0,endDetSpec);
2638  addIt = DetectorIn(detSpec.Data());
2639  if (addIt) ilgString.Remove(0,endDetSpec);
2640  }
2641  if (addIt) {
2642  TRegexp fcsPattern("^h[12]_.+"); Ssiz_t ext=0;
2643  if (!(ilgString.BeginsWith("fcl") ||
2644  ilgString.BeginsWith("fms_qt_") ||
2645  ilgString.BeginsWith("Z3A") ||
2646  ilgString.Contains("etof",TString::ECaseCompare::kIgnoreCase) ||
2647  ilgString.Contains("_matchCand_") ||
2648  ilgString.BeginsWith("G_primary") ||
2649  ilgString.Index(fcsPattern,&ext)==0 ||
2650  ilgString.BeginsWith("fpd_channel_"))) {
2651  for (Int_t k=0; k<numOfPosPrefixes; k++) {
2652  TString listString = type;
2653  (listString += possiblePrefixes[k]) += ilgString;
2654  numPrt = AddToPrintList(listString.Data());
2655  }
2656  } else numPrt = AddToPrintList(ilgString.Data());
2657  if (Debug()) {
2658  LOG_INFO << " !!! adding histogram " << ilgString << " to print list " << endm ;
2659  }
2660  }
2661  }
2662  if (mustDeleteList) delete [] sdefList;
2663 
2664  LOG_INFO << " !!! StHistUtil::SetDefaultPrintList, # histogram put in list " << numPrt << endm;
2665 
2666 }
2667 
2668 //_____________________________________________________________________________
2669 
2670 // Method Overlay1D
2671 // - takes two TH1F histograms and overlays them
2672 
2673 Int_t StHistUtil::Overlay1D(Char_t *dirName,Char_t *inHist1,
2674  Char_t *inHist2) {
2675 
2676  LOG_INFO << " **** Now in StHistUtil::Overlay1D **** " << endm;
2677 
2678  Int_t n1dHists = 0;
2679  PathCopy(m_dirName,dirName);
2680 
2681 // get the TList pointer to the histograms
2682  TList* dirList = (m_PntrToMaker ? FindHists(m_dirName) : FindHists(m_PntrToPlainFile));
2683 
2684 // check that directory exists
2685  if (!dirList)
2686  return kStErr;
2687 
2688  LOG_INFO << "Histogram directory exists -> Find and overlay histograms" << endm;
2689 // Now want to loop over all histograms
2690 // Create an iterator
2691  TIter nextObj(dirList);
2692  TObject *obj = 0;
2693 
2694 // temporary holder histograms
2695  TH1F *hist1f1 = new TH1F;
2696  TH1F *hist1f2 = new TH1F;
2697 
2698 // use = here instead of ==, because we are setting obj equal to nextObj
2699 // and then seeing if it's T or F
2700  while ((obj = nextObj())) {
2701 
2702 // now check if obj is a histogram and see if it matches input name
2703  if (obj->InheritsFrom("TH1")) {
2704  if (obj->GetName() == (TString)inHist1 ||
2705  obj->GetName() == (TString)inHist2) {
2706  LOG_INFO << " Found Histogram: Type '" << obj->ClassName() << "', Name '"
2707  << obj->GetName() << "', Title '" << obj->GetTitle() << "'"
2708  << endm;
2709 
2710 // check on type of histogram and make copies
2711  if (obj->ClassName() == (TString)"TH1F") {
2712  if (obj->GetName() == (TString)inHist1) {
2713  *hist1f1 = *(TH1F *)obj;
2714  n1dHists++;
2715  }
2716  if (obj->GetName() == (TString)inHist2) {
2717  *hist1f2 = *(TH1F *)obj;
2718  n1dHists++;
2719  }
2720  } else {
2721  LOG_INFO << " ERROR: histogram not of type TH1F !!!" << endm;
2722  }
2723  }
2724  }
2725  }
2726 
2727 // if the two histograms exist, overlay them
2728  if (n1dHists == 2) {
2729  hist1f1->SetLineColor(4);
2730  hist1f1->SetLineStyle(1);
2731  hist1f2->SetLineColor(2);
2732  hist1f2->SetLineStyle(2);
2733 
2734  hist1f1->SetStats(kFALSE);
2735  hist1f2->SetStats(kFALSE);
2736 
2737  hist1f1->SetTitle(hist1f1->GetTitle()+(TString)" and "+hist1f2->GetTitle());
2738  hist1f2->SetTitle(hist1f1->GetTitle());
2739 // create a new canvas
2740  TCanvas *newCanvas = new TCanvas("c1d","Combined 1D Histogram",600,780);
2741  newCanvas->Draw();
2742 
2743 // write title at top of canvas
2744  Ltitle = new TPaveLabel(0.1,0.96,0.9,1.0,m_GlobalTitle.Data(),"br");
2745  Ltitle->SetFillColor(18);
2746  Ltitle->SetTextFont(32);
2747  Ltitle->SetTextSize(0.5);
2748  Ltitle->Draw();
2749 
2750 // now put in date & time at bottom right of canvas
2751  TDatime HistTime;
2752  const Char_t *myTime = HistTime.AsString();
2753  TPaveLabel *Ldatetime = new TPaveLabel(0.7,0.01,0.95,0.03,myTime,"br");
2754  Ldatetime->SetTextSize(0.6);
2755  Ldatetime->Draw();
2756 
2757 // create a pad
2758  TPad *newPad = new TPad("p1d","Combined 1D Histogram",0.02,0.04,0.98,0.93);
2759  newPad->Draw();
2760  newPad->cd();
2761 
2762 // draw the histograms
2763  if (hist1f1->GetMaximum() >= hist1f2->GetMaximum()) {
2764  hist1f1->Draw();
2765  hist1f2->Draw("Same");
2766  }
2767  else {
2768  hist1f2->Draw();
2769  hist1f1->Draw("Same");
2770  }
2771 
2772 // make a legend
2773  TLegend *legend = new TLegend(0.75,0.85,0.98,0.95);
2774  legend->SetFillColor(0);
2775  legend->SetHeader("Legend");
2776  legend->SetMargin(0.25);
2777  legend->AddEntry(hist1f1,inHist1,"l");
2778  legend->AddEntry(hist1f2,inHist2,"l");
2779  legend->Draw();
2780 
2781  newCanvas->Update();
2782 
2783  return kStOk;
2784  }
2785 
2786  return kStErr;
2787 }
2788 
2789 //_____________________________________________________________________________
2790 
2791 // Method Overlay2D
2792 // - takes two TH2F histograms and overlays them
2793 
2794 Int_t StHistUtil::Overlay2D(Char_t *dirName,Char_t *inHist1,
2795  Char_t *inHist2) {
2796 
2797  LOG_INFO << " **** Now in StHistUtil::Overlay2D **** " << endm;
2798 
2799  Int_t n2dHists = 0;
2800  PathCopy(m_dirName,dirName);
2801 
2802 // get the TList pointer to the histograms
2803  TList* dirList = (m_PntrToMaker ? FindHists(m_dirName) : FindHists(m_PntrToPlainFile));
2804 
2805 // check that directory exists
2806  if (!dirList)
2807  return kStErr;
2808 
2809  LOG_INFO << "Histogram directory exists -> Find and overlay histograms" << endm;
2810 // Now want to loop over all histograms
2811 // Create an iterator
2812  TIter nextObj(dirList);
2813  TObject *obj = 0;
2814 
2815 // temporary holder histograms
2816  TH2F *hist2f1 = new TH2F;
2817  TH2F *hist2f2 = new TH2F;
2818 
2819 // use = here instead of ==, because we are setting obj equal to nextObj
2820 // and then seeing if it's T or F
2821  while ((obj = nextObj())) {
2822 
2823 // now check if obj is a histogram and see if it matches input name
2824  if (obj->InheritsFrom("TH1")) {
2825  if (obj->GetName() == (TString)inHist1 ||
2826  obj->GetName() == (TString)inHist2) {
2827  LOG_INFO << " Found Histogram: Type '" << obj->ClassName() << "', Name '"
2828  << obj->GetName() << "', Title '" << obj->GetTitle() << "'"
2829  << endm;
2830 
2831 // check on type of histogram and make copies
2832  if (obj->ClassName() == (TString)"TH2F") {
2833  if (obj->GetName() == (TString)inHist1) {
2834  *hist2f1 = *(TH2F *)obj;
2835  n2dHists++;
2836  }
2837  if (obj->GetName() == (TString)inHist2) {
2838  *hist2f2 = *(TH2F *)obj;
2839  n2dHists++;
2840  }
2841  } else {
2842  LOG_INFO << " ERROR: histogram is not of type TH2F !!!" << endm;
2843  }
2844  }
2845  }
2846  }
2847 
2848 // if the two histograms exist, overlay them
2849  if (n2dHists == 2) {
2850  hist2f1->SetLineColor(4);
2851  hist2f2->SetLineColor(2);
2852 
2853  hist2f1->SetStats(kFALSE);
2854  hist2f2->SetStats(kFALSE);
2855 
2856  hist2f1->SetTitle(hist2f1->GetTitle()+(TString)" and "+hist2f2->GetTitle());
2857  hist2f2->SetTitle(hist2f1->GetTitle());
2858 
2859 // create a new canvas and pad to write to
2860  TCanvas *newCanvas = new TCanvas("c2d","Combined 2D Histogram",600,780);
2861  newCanvas->Draw();
2862 
2863 // write title at top of canvas
2864  Ltitle = new TPaveLabel(0.1,0.96,0.9,1.0,m_GlobalTitle.Data(),"br");
2865  Ltitle->SetFillColor(18);
2866  Ltitle->SetTextFont(32);
2867  Ltitle->SetTextSize(0.5);
2868  Ltitle->Draw();
2869 
2870 // now put in date & time at bottom right of canvas
2871  TDatime HistTime;
2872  const Char_t *myTime = HistTime.AsString();
2873  TPaveLabel *Ldatetime = new TPaveLabel(0.7,0.01,0.95,0.03,myTime,"br");
2874  Ldatetime->SetTextSize(0.6);
2875  Ldatetime->Draw();
2876 
2877 // create a pad
2878  TPad *newPad = new TPad("p2d","Combined 2D Histogram",0.02,0.04,0.98,0.93);
2879  newPad->Draw();
2880  newPad->cd();
2881 
2882 // draw the histograms
2883  if (hist2f1->GetMaximum() >= hist2f2->GetMaximum()) {
2884  hist2f1->Draw("Box");
2885  hist2f2->Draw("BoxSame");
2886  }
2887  else {
2888  hist2f2->Draw("Box");
2889  hist2f1->Draw("BoxSame");
2890  }
2891 
2892 // make a legend
2893  TLegend *legend = new TLegend(0.75,0.85,0.98,0.95);
2894  legend->SetFillColor(0);
2895  legend->SetHeader("Legend");
2896  legend->SetMargin(0.25);
2897  legend->AddEntry(hist2f1,inHist1,"f");
2898  legend->AddEntry(hist2f2,inHist2,"f");
2899  legend->Draw();
2900 
2901  newCanvas->Update();
2902 
2903  return kStOk;
2904  }
2905 
2906  return kStErr;
2907 }
2908 
2909 //_____________________________________________________________________________
2910 
2911 // Method GetRunYear
2912 // - determines the run year from the filename
2913 // - assumes runnumber is first all digit token after 2 "_" delimiters
2914 // - assumes runyear is all but the last 6 digits of runnumber
2915 
2916 Int_t StHistUtil::GetRunYear(const Char_t *filename) {
2917 
2918  m_RunYear = 0;
2919  TString FileName = filename;
2920  TString delim = "_";
2921  TObjArray* tokens = FileName.Tokenize(delim);
2922  for (int tk=2; tk<tokens->GetEntries(); tk++) {
2923  TString& tok = ((TObjString*) (tokens->At(tk)))->String();
2924  if (tok.IsDigit()) {
2925  Ssiz_t loc = tok.Length()-6;
2926  if (loc>0) m_RunYear = atoi(tok.Remove(loc).Data());
2927  break;
2928  }
2929  }
2930  return m_RunYear;
2931 
2932 }
2933 
2934 //_____________________________________________________________________________
2935 
2936 // Method SetRefAnalysis
2937 // - Properly set input and output files for reference histogram analysis
2938 
2939 void StHistUtil::SetRefAnalysis(const Char_t* refOutFile, const Char_t* refResultsFile,
2940  const Char_t* refCutsFile, const Char_t* refInFile) {
2941 
2942  LOG_INFO << "StHistUtil: Will run in reference histogram analysis mode." << endm;
2943  m_analMode = kTRUE;
2944 
2945  if (refInFile && strlen(refInFile)) {
2946  LOG_INFO << "StHistUtil: Using reference histogram file " << refInFile << endm;
2947  m_refInFile = new TFile(refInFile);
2948  if (!m_refInFile) {LOG_ERROR << "file not found: " << refInFile << endm;}
2949  }
2950  if (refCutsFile && strlen(refCutsFile)) {
2951  LOG_INFO << "StHistUtil: Using reference cuts file " << refCutsFile << endm;
2952  m_refCuts = new TList;
2953  ifstream refCuts(refCutsFile);
2954  if (!refCuts.is_open()) {
2955  LOG_ERROR << "StHistUtil: Unable to open cuts file! Proceeding with no cuts..." << endm;
2956  return;
2957  }
2958  char buf_name[256];
2959  char buf_opts[64];
2960  while (refCuts.good()) {
2961  refCuts >> buf_name;
2962  if (!refCuts.good()) break;
2963  int mode;
2964  double cut;
2965  refCuts >> mode >> cut >> buf_opts;
2966  if (!refCuts.good()) break;
2967  if (buf_opts[0] == '!') buf_opts[0] = 0; // no options
2968  if (Debug()) {
2969  LOG_INFO << "StHistUtil: Loading cut : " << buf_name << " : " << mode
2970  << " : " << cut << " : " << buf_opts << " :" << endm;
2971  }
2972  m_refCuts->AddLast(new StHistUtilRef(buf_name,buf_opts,mode,cut));
2973  }
2974  }
2975 
2976  // refOutFile will not be used if no reference histograms are found
2977  PathCopy(m_refResultsFile,refResultsFile);
2978  // refOutFile will not be used if already writing hists to a ROOT file
2979  PathCopy(m_refOutFile,refOutFile);
2980 }
2981 
2982 //_____________________________________________________________________________
2983 
2984 void StHistUtil::SetDetectors(const Char_t *detectors) {
2985  // entering a null pointer uses all detector hists
2986  // entering a zero length string uses no detector hists
2987  if (detectors) {
2988  m_Detectors = detectors;
2989  // use colons as delimiters
2990  m_Detectors.ReplaceAll(" ",":");
2991  m_Detectors.ReplaceAll(",",":");
2992  m_Detectors.Prepend(":");
2993  m_Detectors.Append(":");
2994  while (m_Detectors.Index("::") >= 0) m_Detectors.ReplaceAll("::",":");
2995  LOG_INFO << "StHistUtil::SetDetectors(): using detectors " << m_Detectors << endm;
2996  } else {
2997  m_Detectors = "";
2998  LOG_INFO << "StHistUtil::SetDetectors(): using all detectors" << endm;
2999  }
3000 }
3001 
3002 //_____________________________________________________________________________
3003 
3004 Bool_t StHistUtil::DetectorIn(const Char_t *detector) {
3005  // detector should be passed with delimeters, e.g. ":tpc:"
3006  // semicolons should separate multiple possible detectors ("or")
3007  // commas should separate multiple required detectors ("and")
3008  // Example ":tpc,svt;tpx,svt:" is either tpc+svt or tpx+svt
3009  Bool_t isIn = kFALSE;
3010  if (m_Detectors.Length()) {
3011  Ssiz_t idx = 0;
3012  TString detOpts = detector;
3013  TString curDetSet = "";
3014  TString curDet = "";
3015  while (idx < detOpts.Length() && ! isIn) {
3016  Ssiz_t D1 = detOpts.Index(";",idx);
3017  Ssiz_t setLength = (D1 < idx ? detOpts.Length() : D1+1) - idx;
3018  curDetSet = detOpts(idx,setLength);
3019  Ssiz_t idx2 = 0;
3020  isIn = kTRUE;
3021  while (idx2 < curDetSet.Length() && isIn) {
3022  Ssiz_t D2 = curDetSet.Index(",",idx2);
3023  Ssiz_t detLength = (D2 < idx2 ? curDetSet.Length() : D2+1) - idx2;
3024  curDet = curDetSet(idx2,detLength);
3025  curDet.ReplaceAll(";",":");
3026  curDet.ReplaceAll(",",":");
3027  curDet.Prepend(":");
3028  curDet.Append(":");
3029  while (curDet.Index("::") >= 0) curDet.ReplaceAll("::",":");
3030  if (m_Detectors.Index(curDet.Data()) < 0) isIn = kFALSE;
3031  else idx2 += detLength;
3032  }
3033  idx += setLength;
3034  }
3035  } else {
3036  // set to use all detectors
3037  isIn = kTRUE;
3038  }
3039  return isIn;
3040 }
3041 
3042 //_____________________________________________________________________________
3043 
3044 TH1* StHistUtil::FlipAxes(TH1* hist) {
3045  if (!(hist->InheritsFrom("TH2"))) return hist;
3046  // For now, just converts whatever into TH2D
3047  // ...and there is no automatic garbage collection
3048  Int_t xbins = hist->GetNbinsX();
3049  Int_t ybins = hist->GetNbinsY();
3050  TH2D* newhist = new TH2D(Form("%s_flip",hist->GetName()),hist->GetTitle(),
3051  ybins,hist->GetYaxis()->GetXmin(),hist->GetYaxis()->GetXmax(),
3052  xbins,hist->GetXaxis()->GetXmin(),hist->GetXaxis()->GetXmax());
3053  for (int xbin=1; xbin<=xbins; xbin++) {
3054  for (int ybin=1; ybin<=ybins; ybin++) {
3055  newhist->SetBinContent(ybin,xbin,hist->GetBinContent(xbin,ybin));
3056  newhist->SetBinError(ybin,xbin,hist->GetBinError(xbin,ybin));
3057  }
3058  }
3059  newhist->SetMinimum(hist->GetMinimumStored());
3060  newhist->SetMaximum(hist->GetMaximumStored());
3061  return newhist;
3062 }
3063 
3064 //_____________________________________________________________________________
3065 
3066 void StHistUtil::PathCopy(char* destination, const char* source) {
3067  // carefully copy path strings to avoid buffer over-writes or over-reads
3068  if (source && strcmp(destination,source)) {
3069  if (strlen(source) < maxPathLen) {
3070  strncpy(destination,source,maxPathLen-1);
3071  destination[maxPathLen-1] = 0;
3072  } else {
3073  LOG_ERROR << " source path too long: " << source << endm;
3074  }
3075  }
3076 }
3077 
3078 //_____________________________________________________________________________
3079 
3080 //_____________________________________________________________________________
3081 
3082 
3083 ClassImp(StHistUtilRef)
3084 StHistUtilRef::StHistUtilRef(const char* name, const char* opts,
3085  const int mode, const double cut):
3086  TNamed(name,opts),Mode(mode),Cut(cut) {}
Definition: IO.h:20
Definition: Cut.h:18
Definition: QAH.h:34
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TDataSet.cxx:428
Definition: Stypes.h:44
Definition: Stypes.h:41
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362