10"""Interactive python commands for plotting from a tuple-like object.
11This module provides in python functionality similar to TTree::Draw
12and TTree::Scan. The major conceptual differences are:
14 - All expressions are written in python (and not the specialized
15 TTree::Draw language).
16 - This can be applied to any type of object providing a simple loop
17 interface (explained below), not just to TTree's. (A TTree will work;
18 there is also a wrapper for the Athena event loop.)
20In addition, this style of query may be somewhat
21easier to type interactively.
27Here are some examples of plotting commands to give you the flavor:
30 d tt.ele_pt$i; 50 0 100*gev
32 d tt[100:1000].muo$i.pt() if abs(muo.eta)<2
33 d tt.(ele$i+ele$j).m() if $i<$j; same
36To use these commands, you can pass them as strings to pydraw.cmd:
38 from pydraw import cmd
41Alternatively, if you execute the cmdhook function, you can type them
44 from pydraw import cmdhook
48(Note that this second form doesn't work in general for code that's read
55The general syntax for drawing a histogram looks like this:
57 d TUPLESPEC.[STMT@ ...]EXPR[:EXPR] [if EXPR] [; HISTSPEC]
59These pieces are explained in more detail below.
65The object on which the draw operation is to be performed is given
66by TUPLESPEC. This should be the name of some object in the python
67global dictionary. Note that if the expression for the tuple
68itself contains a period or brackets, you'll need to enclose it in parentheses:
70 d (trees.tt[1])[:100].ele_pt$i
72Optionally, this can include a slice-like notation
73to restrict the rows to which the draw applies:
75 tuple[i:j] --- process rows i <= n < j
76 tuple[:j] --- process rows n < j
77 tuple[i:] --- process rows n >= i
78 tuple[i] --- process row i
80i and j can be expressions as well.
82The tuple object should contain a method like this:
84 def loop (self, func, looplo, loophi)
86This function should loop over rows [looplo, loophi) and
87call func on each. func will take two arguments, the first
88being the row number and the second being the event object
89(which may just be the tuple itself).
91If a method named loop is not available, but GetEntry and GetEntries
92methods are available, then those will be used instead.
93Similarly, if size and seekEvent are available, a wrapper
94appropriate for the Athena event loop will be used.
96Thus, you can make plots from within Athena like this:
98 d theApp.ElectronAODCollection$i.eta()
104Once a tuple is specified, one then needs to specify what to plot.
105This is done with an arbitrary python expression, with some extensions.
107To plot a simple numeric variable from the tuple, just give its name.
112will plot the variable `foo' from each row of the tuple. You can of course
113also use more complicated expressions:
117In the common case, though, the members of the tuple will be vectors
118of numbers of objects over which you want to iterate. You can iterate
119plotting over such a vector by specifying a dummy index. This is an
120identifier starting with a dollar sign:
124(Making the dummy indices explicit was a deliberate change from the
125implicit iteration of root/paw. Such implicit iteration sometimes
126caused confusion about just what was being iterated over, and also
127when people needed to distinguish between accessing attributes
128of a container and attributes of the contained objects.)
130This will automatically step $i over the contents of the vector pt_e,
131plotting each one. The vector being iterated over may contain objects
136Note that the limits of the iteration are handled automatically.
137The index $i can also be used in contexts other than that of an index.
138For example, to limit the iteration in the above example to the first
139four items, one can use:
141 d tt.ele$i.pt() if $i<4
143(This uses a selection clause. This is to be described later, but the meaning
146If a dummy index is used for more than one vector, the iteration limit
147will be taken from whichever vector is smaller. For example:
151will iterate min(len(ele),len(muo)) times.
153Multiple dummy indices may be used. In that case, all possible index
154combinations are used (a simple nested loop). If there is a symmetry
155involved, a selection clause may be used to eliminate duplicates.
156For example (given an appropriate ele definition), this will plot the
157invariant masses of all electron pairs:
159 d tt.(ele$i+ele$j).m() if $i>$j
161One can also reference individual elements of a vector using the
162notation $N. Here, the indexing is 1-based (so $1 is the first element).
163Example: to plot the pt of the leading electron
167Note that one can do something similar just using standard python
172This, however, will crash if ele is empty; if the $N form is used,
173an implicit selection is added to ensure that the index is in range.
174Thus, the proper equivalent of the $N-form example is:
176 d tt.ele[0].pt() if len(ele)>0
178You can also use $nCONT as an abbreviation for len(CONT):
180 d tt.ele[0].pt() if $nele>0
182Names used in expressions will be looked up first in the tuple object,
183then in the global dictionary. Note that the lookup in the tuple happens
184before looping starts, so all needed variables must already be present
185in the tuple. If you want to refer to the tuple object itself,
186you can use the special variable `_ev'. (This can be changed by assigning
187a string to pydraw._evtvar.)
189Multiple expressions may be given, separated by `:'. For drawing histograms,
190you can give two expressions, for the x and y axis expressions. For scanning
191tuples (see below), you give the list of expressions to be scanned.
197You can select items to be filled using a boolean expression, set off
200 d tt.ele$i.pt() if abs(ele$i.eta())<2
202All dummy variables are common between the variable expressions
209You can specify arbitrary Python expressions to be executed before looping
210starts. These come before the variables expressions, and are delimited
211with `@'. This is useful mostly for defining short aliases for tuple
212variables. For example:
214 d tt.ele=ElectronAODCollection@ele$i.eta() if ele$i.pt()>100*gev
217Histogram specifications
218------------------------
220Histogram specifications follow a semicolon. They can have the forms:
224 NX XLO XHI OPTIONS...
225 NX XLO XHI NY YLO YHI OPTIONS...
228For the first form, specifying ! reuses the same histogram that was used
231For the second form, specifying >>NAME looks in the global dictionary
232for a histogram NAME and uses that.
234Otherwise, a new histogram is created. The binning for this histogram
235may be specified by NX XLO XHI and NY YLO YHI.
237Plotting options may also be given. The special option `prof' means
238to create a profile histogram. Otherwise, root drawing options may
239be used. This package uses PyAnalysisUtils.draw_obj to draw the
240histograms, so the extra options supported by that function may
241also be used. See draw_obj.py for details.
243The last histogram to have been drawn is available is pydraw.last_hist.
249The scan command is very similar to draw:
251 scan TUPLESPEC.[STMT@ ...]EXPR[:EXPR] [if EXPR]
253Instead of drawing a histogram, scan prints out a table of the expression
256The formatting of the data printed by scan is currently pretty rudimentary.
257This should probably be improved.
263There is also a loop command:
265 loop TUPLESPEC.[STMT@ ...]EXPR[:EXPR] [if EXPR]
267Loop will evaluate the given expressions in the same manner as draw and scan,
268but the results of this are ignored. So it only makes sense to use loop
269to evaluate expressions for their side effects. This can be used,
270for example, to call a function that fills some large set of histograms.
276The general interface to execute one of these commands is the `cmd' function,
277which takes the command as a string:
279 from pydraw import cmd
282Each command is also implemented by a single function, which may be called
283directly. The command name should not be included in this case:
285 from pydraw import draw
288Finally, if you call the function cmdhook(), then you can give the commands
289directly on the python command line:
291 from pydraw import cmdhook
298 - No way to specify an event weight when filling a histogram using
301 - Hoist selection code out of the dummy index loops, when they don't
302 depend on the index? For example,
306 gets implemented like:
312 but it would be more efficient to pull the selection out of the loop.
314 - In an expr like d em.foo$i if em.bar$i>1
315 then foo always gets evaluated even if the condition is false.
330from io
import StringIO
331from PyAnalysisUtils.draw_obj
import draw_obj, get_canvas
335 ScatterH2 = ROOT.RootUtils.ScatterH2
336except AttributeError:
337 ScatterH2 = ROOT.TH2F
338 print (
"WARNING: RootUtils::ScatterH2 not available; using TH2F instead")
344 h.SetBit (ROOT.TH1.kCanRebin)
346 return h.TestBit (ROOT.TH1.kCanRebin)
347except AttributeError:
349 h.GetXaxis().SetCanExtend(
True)
351 return h.GetXaxis().CanExtend()
359_globals = sys.modules[
'__main__'].__dict__
363_idchars = string.ascii_letters + string.digits +
'_'
372 """Name a string safe to use as a histogram name.
374 Root does bad things if you put / in a histogram name, so we remove them.
376 >>> print (_sanitize_hname('foo'))
378 >>> print (_sanitize_hname('foo/bar'))
381 return s.replace (
'/',
' DIV ')
385 """Transform tokens back into Python source code.
387 Each element returned by the iterable must be a token sequence
388 with at least two elements, a token number and token value.
390 Unlike tokenize.untokenize(), this does not handle multiple lines.
391 It also tries not to add unneeded spaces.
394 >>> from tokenize import generate_tokens, untokenize
395 >>> from io import StringIO
396 >>> def untokenize1(tt):
398 ... if tt[-1][0]==0: tt=tt[:-1]
399 ... return untokenize(tt)
400 >>> untokenize1(generate_tokens(StringIO('1+1').readline))
402 >>> _untokenize(generate_tokens(StringIO('1+1').readline))
404 >>> untokenize1(generate_tokens(StringIO('foo$i>2*h').readline))
406 >>> _untokenize(generate_tokens(StringIO('foo$i>2*h').readline))
411 toks_append = toks.append
413 toknum, tokval = tok[:2]
414 tokval = tokval.strip()
415 if toknum
in (token.NAME, token.NUMBER):
417 tokval =
' ' + tokval
426 """Look for NEEDLE in HAYSTACK (token-based. Return pair (HEAD, TAIL).
428 HAYSTACK and NEEDLE are both strings. Look for a token in HAYSTACK with
429 a value matching NEEDLE that is outside of any paired delimiters.
430 Also ignores things in strings.
431 If IGNORE_DELIM is True, then we do find things inside delimiters
432 (strings are still ignored).
434 Returns a pair (HEAD, TAIL) of the pieces of the string before and
435 after NEEDLE. If there is no match, returns (HAYSTACK, None).
436 Note that whitespace and formatting in HEAD and TAIL may differ
437 from the original string.
440 >>> _find_outer ("head.tail1.tail2", ".")
441 ('head', 'tail1.tail2')
442 >>> _find_outer ("(head.tail1).tail2", ".")
443 ('(head.tail1)', 'tail2')
444 >>> _find_outer ("[a for a in foo if good(a)] if bar", "if")
445 ('[a for a in foo if good(a)]', 'bar')
446 >>> _find_outer ("(a [b {c . d } ] ) . e", ".")
447 ('(a [b {c . d } ] )', 'e')
448 >>> _find_outer ("a.b", ";")
450 >>> _find_outer ("a '$' b", '$')
452 >>> _find_outer ("a $ b", '$')
454 >>> _find_outer ("(head.tail1).tail2", ".", True)
455 ('(head', 'tail1).tail2')
456 >>> _find_outer ('a; 1 -1 1', ';')
459 tlist = tokenize.generate_tokens (StringIO(haystack).readline)
462 for (i, (tnum, val, a, b, c))
in enumerate (tlist):
463 if tnum != token.STRING
and not pend
and val == needle:
466 return (haystack[:col1].
strip(),
467 haystack[col2:].
strip())
475 elif pend
and val == pend[-1]:
477 head.append ((tnum, val))
478 return (haystack,
None)
482 """Split HAYSTACK at the delimiters NEEDLE, as in _find_outer.
485 >>> _split_outer ("a,(b,c),d", ",")
487 >>> _split_outer ("a,,b", ",")
489 >>> _split_outer ("a", ",")
491 >>> #_split_outer ("", ",")
496 (head, tail) = _find_outer (haystack, needle)
507 """Wrapper for TTree, supplying a loop method.
509 This class wraps a TTree class and provides a loop method
510 that will work with pydraw.
514 """Make a wrapper for a tree."""
518 def loop (self, f, looplo=0, loophi=sys.maxsize):
519 """Call f(i,tree) on rows [looplo, loophi)"""
521 loophi = min (loophi, tree.GetEntries())
522 getentry = tree.GetEntry
523 for i
in range(looplo, loophi):
530 """Wrapper for the Athena event loop, supplying a loop method.
532 This class wraps an application manager object and provides a loop method
533 that will work with pydraw.
536 from AthenaPython
import PyAthena
538 from AthenaCommon.AppMgr
import theApp
541 self.
_sg = PyAthena.py_svc(
'StoreGateSvc')
545 def loop (self, f, looplo=0, loophi=sys.maxsize):
546 """Call f(i,tree) on rows [looplo, loophi)"""
547 loophi = min (loophi, self.
_app.size())
548 getentry = self.
_app.seekEvent
549 for i
in range(looplo, loophi):
556 if not v.startswith(
'_'):
558 raise AttributeError()
562 """Holds information about a dummy loop variable.
565 name - The name of the dummy variable.
566 ids - Set of loop identifiers (`foo' in `foo$i') with which
567 this dummy has been used.
568 explicit - Set to true if this variable is ever used on its own
573 """Initialize given the name."""
580 """Return the iterator variable for this dummy and loop identifier ID.
582 return "_it_%s_%s" % (self.
name, id)
585 """Return the dummy variable name for this dummy."""
586 return "_dum_" + self.
name
589 """Notice this this dummy is used with loop identifier ID.
591 Return the iterator variable.
597 """Return the list of loop identifiers with which we've been used."""
598 return list (self.
ids)
602 """Holds information used to implement a draw/scan/loop command.
604 Pass the draw string to the constructor. See the file-level comments
605 for details on the syntax of this. This will define the
606 following attributes:
608 errstr - If set to a string, there was an error.
609 Should be None if everything's ok.
610 tuple - The name of the tuple object.
611 tuple_o - Tuple object.
612 lo - The lower bound for row iteration.
613 hi - The upper bound for row iteration.
614 stmts - List of additional statements.
615 exprs - List of draw expressions.
616 sel - Selection expression or None.
617 sel_orig - Untransformed selection expression or None.
618 expr_orig- Untransformed plotting expression.
619 histspec - The text following `;', split into space-separated words.
622 _iddict - Map from loop identifiers (`foo' in `foo$i')
623 to temp variables used to reference
624 them in the loop function.
625 _limdict - Map from loop identifiers (`foo' in `foo$2')
626 to the largest explicit index seen.
627 _loopdict - Map of loop dummy variable names to _Loopvar instances.
631 """Initialize from a draw string. See above for more details."""
642 except Exception
as e:
651 """Parse a draw string. See above for more details."""
667 self.
errstr =
"Empty draw string."
671 (tuple, s) = _find_outer (s,
'.')
673 self.
errstr =
"Missing period in tuple specification."
704 if hasattr (self.
tuple_o,
'loop'):
707 elif (hasattr (self.
tuple_o,
'GetEntry')
and
708 hasattr (self.
tuple_o,
'GetEntries')):
711 elif (hasattr (self.
tuple_o,
'size')
and
712 hasattr (self.
tuple_o,
'seekEvent')):
718 " doesn't have a correct interface.")
726 """Parse the range part of a draw string.
728 See above for more details.
729 Fills self.tuple, self.lo, self.hi.
733 (tuple, tail) = _find_outer (tuple,
'[')
735 g = copy.copy (_globals)
737 pos = tail.find (
':')
738 pos2 = tail.find (
']')
742 slo = tail[:pos2].
strip()
744 lo = int (eval (slo, g))
747 slo = tail[:pos].
strip()
749 lo = int (eval (slo, g))
750 shi = tail[pos+1:pos2].
strip()
752 hi = int (eval (shi, g))
754 if tuple[0] ==
'(' and tuple[-1] ==
')':
755 tuple = tuple[1:-1].
strip()
763 """Given a loop identifier (`foo' in `foo$i'), return the identifier
764 used to reference it in loop functions.
774 """Handle an explicit index reference; i.e., `foo$2'.
776 S1 and S2 are pieces of the string before and after the `$'.
777 Returns the modified string.
780 while pos2 < len(s2)
and s2[pos2]
in string.digits:
789 s = (
"[%d]" % (i-1)) + s2[pos2:]
791 while pos2 >= 0
and s1[pos2]
in _idchars:
798 s = s1[:pos2] + self.
_mung_id (id) + s
804 """Handle a length reference; i.e., `$nfoo'.
806 S1 and S2 are pieces of the string before and after the `$'.
807 Returns the modified string.
810 while pos2 < len(s2)
and s2[pos2]
in _idchars:
813 s = s1 + (
" len(%s)" % self.
_mung_id(id)) + s2[pos2:]
818 """Handle use of a dummy loop variable, such as foo$i.
820 S1 and S2 are pieces of the string before and after the `$'.
821 Returns the modified string.
826 while pos2 < len(s2)
and s2[pos2]
in _idchars:
829 self.
errstr =
"Bad loop var"
840 if len(s1) > 0
and s1[-1]
in _idchars:
843 while pos3 >= 0
and s1[pos3]
in _idchars:
846 assert (len(s1) - pos3 >= 1)
850 s = s1[:pos3] + ll.add_id(id) + s2[pos2:]
855 s = s1 + (
"%s" % ll.dumname()) + s2[pos2:]
861 """Process $ constructions in string S.
863 Returns the modified string.
869 (s1, s2) = _find_outer (s[pos:],
'$',
True)
874 if s2[0]
in string.digits:
876 elif (s2[0] ==
'n' and
877 (
not (len(s1) > 0
and s1[-1]
in _idchars)
or
878 s1.endswith (
' and')
or
879 s1.endswith (
' or')
or
880 s1.endswith (
'not'))):
882 elif s2[0]
in string.ascii_letters:
887 pos = pos + len(s1)+1
893 """Perform id substitution in S.
895 For identifiers in S that are attributes of our tuple,
896 replace them with references to the tuple attribute
899 Returns the modified string.
904 tlist = tokenize.generate_tokens (StringIO(s).readline)
907 for tnum, val, a, b, c
in tlist:
908 if tnum == token.NAME
and not afterDot:
909 if hasattr (self.
tuple_o, val):
912 out.append ((tnum, val))
915 if tnum == token.OP
and val ==
'.':
919 return _untokenize (out)
923 """Process $ constructions and id substitution in string S.
925 Returns the modified string.
932 """Create the text for the function to process this query.
934 PAYLOAD is the payload expression to plug in.
935 EXTARGS is an additional string to add to the end of the
936 function's argument list (to set default values, for example).
937 Returns the function definition as a string.
942 limsel =
' and '.join ([
"len(%s)>=%d" % (self.
_iddict[p[0]], p[1])
947 sel = limsel +
" and (" + sel +
")"
949 ftext =
"def _loopfunc(_i, %s%s):\n" % (_evtvar, extargs)
950 for (id1, id2)
in sorted(self.
_iddict.items()):
951 ftext +=
" %s = %s.%s\n" % (id2, _evtvar, id1)
954 for (i,l)
in sorted(self.
_loopdict.items()):
955 ids = sorted(l.get_ids())
958 vars = l.itname (ids[0])
961 vars =
"(" +
','.join([l.itname (id)
for id
in ids]) +
")"
962 lists = (
"zip(" +
','.join([self.
_iddict[id]
for id
in ids])
965 vars =
"(%s,%s)" % (l.dumname(), vars)
966 lists =
"enumerate(%s)" % lists
967 ftext +=
' '*indent +
"for %s in %s:\n" % (vars, lists)
971 ftext +=
' '*indent + s +
'\n'
973 if sel
and sel !=
'1':
974 ftext +=
' '*indent +
"if (%s):\n" % sel
977 ftext +=
' '*indent +
"%s\n" % payload
986 """Holds the results of _get_bins. Defined attributes:
996 """Parse bin specifications from split list of arguments ARGS.
997 NDIM is 1 or 2, and AXIS is 0 or 1, for the x or y axis.
1000 >>> from PyAnalysisUtils import pydraw
1001 >>> pydraw._globals = globals()
1003 >>> ROOT.gPad.Range(0, 1,2,3)
1004 >>> b = _get_bins (["50", "10", "100"], 1, 0)
1005 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1007 >>> b = _get_bins ([], 1, 0)
1008 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1010 >>> b = _get_bins (["!", "10"], 1, 0)
1011 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1013 >>> b = _get_bins (["!", "!", "10"], 1, 0)
1014 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1017 >>> b = _get_bins (["50", "0", "2*scale"], 1, 0)
1018 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1020 >>> b = _get_bins ([], 2, 0)
1021 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1023 >>> b = _get_bins ([], 2, 1)
1024 >>> print (b.nbins, b.lo, b.hi, b.rebin)
1026 >>> b = _get_bins ([], 2, 2)
1027 Traceback (most recent call last):
1032 g = copy.copy (_globals)
1037 if len(args) >= 1
and args[0] !=
'!' and len(args[0]) > 0:
1038 bins.nbins = int (eval (args[0], g))
1043 if len(args) >= 2
and args[1] !=
'!' and len(args[1]) > 0:
1044 bins.lo = float (eval (args[1], g))
1047 if len(args) >= 3
and args[2] !=
'!' and len(args[2]) > 0:
1048 bins.hi = float (eval (args[2], g))
1051 if bins.hi <= bins.lo:
1054 bins.hi = bins.lo + 1
1056 bins.lo = ROOT.gPad.GetUxmin()
1057 bins.hi = ROOT.gPad.GetUxmax()
1059 bins.lo = ROOT.gPad.GetUymin()
1060 bins.hi = ROOT.gPad.GetUymax()
1068 """Create a new histogram from options.
1070 NDIM is the dimensionality of the histogram (1 or 2).
1071 ARGS is a list of the arguments given to specify the histogram.
1072 HNAME and HTITLE are the histogram name and title, respectively.
1077 xbins = _get_bins (args, ndim, 0)
1082 ybins = _get_bins (args[3:], ndim, 1)
1083 rebin = rebin
or ybins.rebin
1088 for i
in range (0, len(args)):
1089 if args[i][0]
in string.ascii_letters:
1090 for j
in range (i, len(args)):
1091 if ndim == 2
and args[j].lower() ==
"prof":
1094 options =
' '.join (args[i:])
1098 hold = ROOT.gROOT.FindObject (hname)
1100 ROOT.gROOT.Remove (hold)
1104 hist = ROOT.TProfile (hname, htitle, xbins.nbins, xbins.lo, xbins.hi)
1106 hist.SetMinimum (ybins.lo)
1107 hist.SetMaximum (ybins.hi)
1109 hist = ROOT.TH1F (hname, htitle, xbins.nbins, xbins.lo, xbins.hi)
1111 hist = ScatterH2 (hname, htitle,
1112 xbins.nbins, xbins.lo, xbins.hi,
1113 ybins.nbins, ybins.lo, ybins.hi)
1114 if hasattr (hist,
'scatter'):
1121 return (hist, options)
1125 """Process a draw command.
1127 ARG is the command arguments (without the command word itself).
1128 See the header comments for the command syntax.
1140 if len (c.exprs) == 1:
1142 payload =
"_hfill (%s)" % c.exprs[0]
1145 payload =
"_hfill ((%s),(%s))" % (c.exprs[0], c.exprs[1])
1148 htitle =
"%s.%s" % (c.tuple, c.expr_orig)
1150 htitle = htitle +
'{%s}' % c.sel_orig
1154 if len(c.histspec) >= 1
and c.histspec[0] ==
"!" and last_hist
is not None:
1156 options =
' '.join (c.histspec[1:])
1157 elif len(c.histspec) >= 1
and c.histspec[0][:2] ==
'>>':
1158 hname = c.histspec[0][2:]
1159 hist = _globals.get (hname)
1160 options =
' '.join (c.histspec[1:])
1162 (hist, options) = _get_hist (ndim, c.histspec,
1170 g = copy.copy (_globals)
1171 g[
'_hfill'] = hist.Fill
1172 ftext = c._make_func (payload,
', _hfill = _hfill')
1176 c.tuple_o.loop (g[
'_loopfunc'], c.lo, c.hi)
1179 if _hasCanRebin (hist):
1180 hist.LabelsDeflate (
"X")
1182 hist.LabelsDeflate (
"Y")
1185 draw_obj (hist, options)
1190 """Helper to print out one row of a scan.
1192 I is the row number and ARGS is a tuple of the column values."""
1196 if isinstance(a, int):
1205 """Process a scan command.
1207 ARG is the command arguments (without the command word itself).
1208 See the header comments for the command syntax.
1217 payload =
"_print (_i, %s)" % \
1218 ','.join ([
'(%s)'%e
for e
in c.exprs])
1222 g = copy.copy (_globals)
1223 g[
'_print'] = _scan_print
1224 ftext = c._make_func (payload,
', _print = _print')
1228 c.tuple_o.loop (g[
'_loopfunc'], c.lo, c.hi)
1234 """Process a loop command.
1236 ARG is the command arguments (without the command word itself).
1237 See the header comments for the command syntax.
1246 payload =
"(%s,)" %
','.join (c.exprs)
1250 g = copy.copy (_globals)
1251 ftext = c._make_func (payload)
1255 c.tuple_o.loop (g[
'_loopfunc'], c.lo, c.hi)
1262_cmddict = {
'd': draw,
1270 """Process a command S.
1272 Returns True if the command was handled, False otherwise.
1273 See the header comments for the command syntax.
1276 ssplit = s.split (
None, 1)
1283 func = _cmddict.get (cmd)
1302if '_orig_ehook' not in globals():
1307 """Exception hook used by pydraw to process drawing commands."""
1310 if isinstance (value, SyntaxError):
1317 ROOT.gInterpreter.EndOfLineAction()
1321 _orig_ehook (exctype, value, traceb)
1325 """Enable entering drawing commands directly at the python prompt."""
1330 if _orig_ehook
is None:
1331 _orig_ehook = sys.excepthook
1334 sys.excepthook = _excepthook
loop(self, f, looplo=0, loophi=sys.maxsize)
_mung_expr_dollar(self, s)
_mung_index(self, s1, s2)
_make_func(self, payload, extargs='')
loop(self, f, looplo=0, loophi=sys.maxsize)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
_get_bins(args, ndim, axis)
_get_hist(ndim, args, hname, htitle)
_split_outer(haystack, needle)
_find_outer(haystack, needle, ignore_delim=False)
_excepthook(exctype, value, traceb)