Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeDrawArgsParser.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Marek Biskup 24/01/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TTreeDrawArgsParser
13 A class that parses all parameters for TTree::Draw().
14 See TTree::Draw() for the format description.
15 */
16 
17 #include "TTreeDrawArgsParser.h"
18 #include "TDirectory.h"
19 
20 
21 Int_t TTreeDrawArgsParser::fgMaxDimension = 4;
22 Int_t TTreeDrawArgsParser::fgMaxParameters = 9;
23 
24 
25 ClassImp(TTreeDrawArgsParser);
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 /// Constructor - cleans all the class variables.
29 
30 TTreeDrawArgsParser::TTreeDrawArgsParser()
31 {
32  ClearPrevious();
33 }
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Destructor.
37 
38 TTreeDrawArgsParser::~TTreeDrawArgsParser()
39 {
40 }
41 
42 ////////////////////////////////////////////////////////////////////////////////
43 /// return fgMaxDimension (cannot be inline)
44 
45 Int_t TTreeDrawArgsParser::GetMaxDimension()
46 {
47  return fgMaxDimension;
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// Resets all the variables of the class.
52 
53 void TTreeDrawArgsParser::ClearPrevious()
54 {
55  fExp = "";
56  fSelection = "";
57  fOption = "";
58  fDimension = -1;
59  int i;
60  for (i = 0; i < fgMaxDimension; i++) {
61  fVarExp[i] = "";
62  }
63  fAdd = kFALSE;
64  fName = "";
65  fNoParameters = 0;
66  for (i = 0; i < fgMaxParameters; i++) {
67  fParameterGiven[i] = kFALSE;
68  fParameters[i] = 0;
69  }
70  fShouldDraw = kTRUE;
71  fOriginal = 0;
72  fDrawProfile = kFALSE;
73  fOptionSame = kFALSE;
74  fEntryList = kFALSE;
75  fOutputType = kUNKNOWN;
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Parse expression [var1 [:var2 [:var3] ...]],
80 /// number of variables cannot be greater than fgMaxDimension.
81 ///
82 /// A colon which is followed by (or that follows) another semicolon
83 /// is not regarded as a separator.
84 ///
85 /// If there are more separating : than fgMaxDimension - 1 then
86 /// all characters after (fgMaxDimension - 1)th colon is put into
87 /// the last variable.
88 ///
89 /// - `fDimension := <number of variables>`
90 /// - `fVarExp[0] := <first variable string>`
91 /// - `fVarExp[1] := <second variable string>`
92 /// ..
93 /// Returns kFALSE in case of an error.
94 
95 Bool_t TTreeDrawArgsParser::SplitVariables(TString variables)
96 {
97  fDimension = 0;
98  if (variables.Length() == 0)
99  return kTRUE;
100 
101  int prev = 0;
102  int i;
103  for (i = 0; i < variables.Length() && fDimension < fgMaxDimension; i++) {
104  if (variables[i] == ':'
105  && !( (i > 0 && variables[i - 1] == ':')
106  || (i + 1 < variables.Length() && variables[i + 1] == ':') ) ) {
107  fVarExp[fDimension] = variables(prev, i - prev);
108  prev = i+1;
109  fDimension++;
110  }
111  }
112  if (fDimension < fgMaxDimension && i != prev)
113  fVarExp[fDimension++] = variables(prev, i - prev);
114  else
115  return kFALSE;
116 
117  return kTRUE;
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Syntax:
122 ///
123 /// [' '*][[\+][' '*]name[(num1 [, [num2] ] [, [num3] ] ...)]]
124 ///
125 /// num's are floating point numbers
126 /// sets the fileds fNoParameters, fParameterGiven, fParameters, fAdd, fName
127 /// to appropriate values.
128 ///
129 /// Returns kFALSE in case of an error.
130 
131 Bool_t TTreeDrawArgsParser::ParseName(TString name)
132 {
133  name.ReplaceAll(" ", "");
134 
135  if (name.Length() != 0 && name[0] == '+') {
136  fAdd = kTRUE;
137  name = name (1, name.Length() - 1);
138  }
139  else
140  fAdd = kFALSE;
141  Bool_t result = kTRUE;
142 
143  fNoParameters = 0;
144  for (int i = 0; i < fgMaxParameters; i++)
145  fParameterGiven[i] = kFALSE;
146 
147  if (char *p = (char*)strstr(name.Data(), "(")) {
148  fName = name(0, p - name.Data());
149  p++;
150  char* end = p + strlen(p);
151 
152  for (int i = 0; i < fgMaxParameters; i++) {
153  char* q = p;
154  while (p < end && *p != ',' && *p != ')')
155  p++;
156  TString s(q, p - q);
157  if (sscanf(s.Data(), "%lf", &fParameters[i]) == 1) {
158  fParameterGiven[i] = kTRUE;
159  fNoParameters++;
160  }
161  if (p == end) {
162  Error("ParseName", "expected \')\'");
163  result = kFALSE;
164  break;
165  }
166  else if (*p == ')')
167  break;
168  else if (*p == ',')
169  p++;
170  else {
171  Error("ParseName", "impossible value for *q!");
172  result = kFALSE;
173  break;
174  }
175  }
176  }
177  else { // if (char *p = strstr(name.Data(), "("))
178  fName = name;
179  }
180  return result;
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Split variables and parse name and parameters in brackets.
185 
186 Bool_t TTreeDrawArgsParser::ParseVarExp()
187 {
188  char* gg = (char*)strstr(fExp.Data(), ">>");
189  TString variables;
190  TString name;
191 
192  if (gg) {
193  variables = fExp(0, gg - fExp.Data());
194  name = fExp(gg+2 - fExp.Data(), fExp.Length() - (gg + 2 - fExp.Data()));
195  }
196  else {
197  variables = fExp;
198  name = "";
199  }
200  Bool_t result = SplitVariables(variables) && ParseName(name);
201  if (!result) {
202  Error("ParseVarExp", "error parsing variable expression");
203  return kFALSE;
204  }
205  return result;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Check if options contain some data important for choosing the type of the
210 /// drawn object.
211 
212 Bool_t TTreeDrawArgsParser::ParseOption()
213 {
214  fOption.ToLower();
215 
216  if (fOption.Contains("goff")) {
217  fShouldDraw = kFALSE;
218  }
219  if (fOption.Contains("prof")) {
220  fDrawProfile = kTRUE;
221  }
222  if (fOption.Contains("same")) {
223  fOptionSame = kTRUE;
224  }
225  if (fOption.Contains("entrylist")){
226  fEntryList = kTRUE;
227  }
228  return true;
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Parses parameters from TTree::Draw().
233 /// - varexp - Variable expression; see TTree::Draw()
234 /// - selection - selection expression; see TTree::Draw()
235 /// - option - Drawing option; see TTree::Draw
236 
237 Bool_t TTreeDrawArgsParser::Parse(const char *varexp, const char *selection, Option_t *option)
238 {
239  ClearPrevious();
240 
241  // read the data provided and fill class fields
242  fSelection = selection;
243  fExp = varexp;
244  fOption = option;
245  Bool_t success = ParseVarExp();
246  success &= ParseOption();
247 
248  if (!success)
249  return kFALSE;
250 
251  // if the name was specified find the existing histogram
252  if (fName != "") {
253  fOriginal = gDirectory->Get(fName);
254  }
255  else
256  fOriginal = 0;
257 
258  DefineType();
259 
260  return kTRUE;
261 }
262 
263 ////////////////////////////////////////////////////////////////////////////////
264 /// Put the type of the draw result into fOutputType and return it.
265 
266 TTreeDrawArgsParser::EOutputType TTreeDrawArgsParser::DefineType()
267 {
268  if (fDimension == 0){
269  if (fEntryList)
270  return fOutputType = kENTRYLIST;
271  else
272  return fOutputType = kEVENTLIST;
273  }
274  if (fDimension == 2 && fDrawProfile)
275  return fOutputType = kPROFILE;
276  if (fDimension == 3 && fDrawProfile)
277  return fOutputType = kPROFILE2D;
278 
279  if (fDimension == 2) {
280  Bool_t graph = kFALSE;
281 // GG 9Mar2014: fixing ROOT-5337; should understand why it was like this, but we move to TSelectorDraw
282 // and this will disappear
283 // Int_t l = fOption.Length();
284 // if (l == 0 || fOption.Contains("same")) graph = kTRUE;
285  if (fOption.Contains("same")) graph = kTRUE;
286  if (fOption.Contains("p") || fOption.Contains("*") || fOption.Contains("l")) graph = kTRUE;
287  if (fOption.Contains("surf") || fOption.Contains("lego") || fOption.Contains("cont")) graph = kFALSE;
288  if (fOption.Contains("col") || fOption.Contains("hist") || fOption.Contains("scat")) graph = kFALSE;
289  if (fOption.Contains("box")) graph = kFALSE;
290  if (graph)
291  return fOutputType = kGRAPH;
292  else
293  return fOutputType = kHISTOGRAM2D;
294  }
295  if (fDimension == 3) {
296  if (fOption.Contains("col"))
297  return fOutputType = kLISTOFGRAPHS;
298  else
299  return fOutputType = kHISTOGRAM3D;
300 // GG 9Mar2014: fixing ROOT-5337; should understand why it was like this, but we move to TSelectorDraw
301 // and this will disappear
302 // return fOutputType = kPOLYMARKER3D;
303  }
304  if (fDimension == 1)
305  return fOutputType = kHISTOGRAM1D;
306  if (fDimension == 4)
307  return fOutputType = kLISTOFPOLYMARKERS3D;
308  return kUNKNOWN;
309 }
310 
311 ////////////////////////////////////////////////////////////////////////////////
312 /// Returns appropriate TSelector class name for proof for the object that is to be drawn
313 /// assumes that Parse() method has been called before.
314 
315 TString TTreeDrawArgsParser::GetProofSelectorName() const
316 {
317  switch (fOutputType) {
318  case kUNKNOWN:
319  return "";
320  case kEVENTLIST:
321  return "TProofDrawEventList";
322  case kENTRYLIST:
323  return "TProofDrawEntryList";
324  case kPROFILE:
325  return "TProofDrawProfile";
326  case kPROFILE2D:
327  return "TProofDrawProfile2D";
328  case kGRAPH:
329  return "TProofDrawGraph";
330  case kPOLYMARKER3D:
331  return "TProofDrawPolyMarker3D";
332  case kLISTOFGRAPHS:
333  return "TProofDrawListOfGraphs";
334  case kHISTOGRAM1D:
335  case kHISTOGRAM2D:
336  case kHISTOGRAM3D:
337  return "TProofDrawHist";
338  case kLISTOFPOLYMARKERS3D:
339  return "TProofDrawListOfPolyMarkers3D";
340  default:
341  return "";
342  }
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// returns *num*-th parameter from brackets in the expression
347 /// in case of an error (wrong number) returns 0.0
348 /// num - number of parameter (counted from 0)
349 
350 Double_t TTreeDrawArgsParser::GetParameter(Int_t num) const
351 {
352  if (num >= 0 && num <= fgMaxParameters && fParameterGiven[num])
353  return fParameters[num];
354  else {
355  Error("GetParameter","wrong arguments");
356  return 0.0;
357  }
358 }
359 
360 ////////////////////////////////////////////////////////////////////////////////
361 /// - num - parameter number
362 /// - def - default value of the parameter
363 /// returns the value of *num*-th parameter from the brackets in the variable expression
364 /// if the parameter of that number wasn't specified returns *def*.
365 
366 Double_t TTreeDrawArgsParser::GetIfSpecified(Int_t num, Double_t def) const
367 {
368  if (num >= 0 && num <= fgMaxParameters && fParameterGiven[num])
369  return fParameters[num];
370  else
371  return def;
372 }
373 
374 ////////////////////////////////////////////////////////////////////////////////
375 /// returns kTRUE if the *num*-th parameter was specified
376 /// otherwise returns fFALSE
377 /// in case of an error (wrong num) prints an error message and
378 /// returns kFALSE.
379 
380 Bool_t TTreeDrawArgsParser::IsSpecified(int num) const
381 {
382  if (num >= 0 && num <= fgMaxParameters)
383  return fParameterGiven[num];
384  else
385  Error("Specified", "wrong parameter %d; fgMaxParameters: %d", num, fgMaxParameters);
386  return kFALSE;
387 }
388 
389 ////////////////////////////////////////////////////////////////////////////////
390 /// Returns the *num*-th variable string
391 /// in case of an error prints an error message and returns an empty string.
392 
393 TString TTreeDrawArgsParser::GetVarExp(Int_t num) const
394 {
395  if (num >= 0 && num < fDimension)
396  return fVarExp[num];
397  else
398  Error("GetVarExp", "wrong Parameters %d; fDimension = %d", num, fDimension);
399  return "";
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Returns the variable string, i.e. [var1[:var2[:var2[:var4]]]].
404 
405 TString TTreeDrawArgsParser::GetVarExp() const
406 {
407  if (fDimension <= 0)
408  return "";
409  TString exp = fVarExp[0];
410  for (int i = 1; i < fDimension; i++) {
411  exp += ":";
412  exp += fVarExp[i];
413  }
414  return exp;
415 }
416 
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// Returns the desired plot title.
420 
421 TString TTreeDrawArgsParser::GetObjectTitle() const
422 {
423  if (fSelection != "")
424  return Form("%s {%s}", GetVarExp().Data(), fSelection.Data());
425  else
426  return GetVarExp();
427 }
428