JsMVA
JPyInterface.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 ## @package JsMVA.JPyInterface
3 # JPyInterface is responsible for adding the drawing methods to TMVA
4 # and for creating the JavaScript outputs from objects.
5 # @authors Attila Bagoly <battila93@gmail.com>
6 
7 
8 from IPython.core.display import display, HTML
9 from string import Template
10 import ROOT
11 import DataLoader
12 import Factory
13 import types
14 
15 
16 ## Function inserter class
17 # This class contains the methods which are invoked by using jsmva magic, and will inject the new methods
18 # to TMVA::Factory, TMVA::DataLoader
19 class functions:
20 
21  ## Threaded functions
22  ThreadedFunctions = {
23  "MethodBase": ["GetInteractiveTrainingError", "ExitFromTraining", "TrainingEnded", "TrainMethod",
24  "GetMaxIter", "GetCurrentIter"]
25  }
26 
27  ## The method inserter function
28  # @param target which class to insert
29  # @param source module which contains the methods to insert
30  # @param args list of methods to insert
31  @staticmethod
32  def __register(target, source, *args):
33  for arg in args:
34  if hasattr(target, arg):
35  continue
36  setattr(target, arg, getattr(source, arg))
37 
38  ## This method change TMVA methods with new methods
39  # @param target which class to insert
40  # @param source module which contains the methods to insert
41  # @param args list of methods to insert
42  @staticmethod
43  def __changeMethod(target, source, *args):
44  def rewriter(originalFunction, newFunction):
45  def wrapper(*args, **kwargs):
46  kwargs["originalFunction"] = originalFunction
47  return newFunction(*args, **kwargs)
48  return wrapper
49  for arg in args:
50  if arg.find("CallOriginal")!=-1:
51  originalName = arg.replace("Change", "").replace("CallOriginal", "")
52  setattr(target, originalName, rewriter(getattr(target, originalName), getattr(source, arg)))
53  else:
54  setattr(target, arg.replace("Change", ""), getattr(source, arg))
55 
56  ## Get's special parameters from kwargs and converts to positional parameter
57  @staticmethod
58  def ConvertSpecKwargsToArgs(positionalArgumentsToNamed, *args, **kwargs):
59  # args[0] = self
60  args = list(args)
61  idx = 0
62  PositionalArgsEnded = False
63  for argName in positionalArgumentsToNamed:
64  if not PositionalArgsEnded:
65  if argName in kwargs:
66  if (idx + 1) != len(args):
67  raise AttributeError
68  PositionalArgsEnded = True
69  else:
70  idx += 1
71  if PositionalArgsEnded and argName not in kwargs:
72  raise AttributeError
73  if argName in kwargs:
74  args.append(kwargs[argName])
75  del kwargs[argName]
76  args = tuple(args)
77  return (args, kwargs)
78 
79  ## Converts object to TMVA style option string
80  @staticmethod
81  def ProcessParameters(optStringStartIndex, *args, **kwargs):
82  originalFunction = None
83  if optStringStartIndex != -10:
84  originalFunction = kwargs["originalFunction"]
85  del kwargs["originalFunction"]
86  OptionStringPassed = False
87  if (len(args) - 1) == optStringStartIndex:
88  opt = args[optStringStartIndex] + ":"
89  tmp = list(args)
90  del tmp[optStringStartIndex]
91  args = tuple(tmp)
92  OptionStringPassed = True
93  else:
94  opt = ""
95  for key in kwargs:
96  if type(kwargs[key]) == types.BooleanType:
97  if kwargs[key] == True:
98  opt += key + ":"
99  else:
100  opt += "!" + key + ":"
101  elif type(kwargs[key]) == types.ListType:
102  ss = ""
103  for o in kwargs[key]:
104  if type(o) == types.DictType:
105  sst = ""
106  for kk in o:
107  sst += kk + "=" + str(o[kk]) + ","
108  ss += sst[:-1] + "|"
109  elif key=="Layout":
110  ss += str(o) + ","
111  else:
112  ss += str(o) + ";"
113  opt += key + "=" + ss[:-1] + ":"
114  else:
115  opt += key + "=" + str(kwargs[key]) + ":"
116  tmp = list(args)
117  if OptionStringPassed or len(kwargs) > 0:
118  tmp.append(opt[:-1])
119  return (originalFunction, tuple(tmp))
120 
121  ## The method removes inserted functions from class
122  # @param target from which class to remove functions
123  # @param args list of methods to remove
124  @staticmethod
125  def __unregister(target, *args):
126  for arg in args:
127  if hasattr(target, arg):
128  delattr(target, arg)
129 
130  ## Reads all methods containing a selector from specified module
131  # @param module finding methods in this module
132  # @param selector if method in module contains this string will be selected
133  @staticmethod
134  def __getMethods(module, selector):
135  methods = []
136  for method in dir(module):
137  if method.find(selector)!=-1:
138  methods.append(method)
139  return methods
140 
141  ## This function will register all functions which name contains "Draw" to TMVA.DataLoader and TMVA.Factory
142  # from DataLoader and Factory modules
143  @staticmethod
144  def register():
145  functions.__register(ROOT.TMVA.DataLoader, DataLoader, *functions.__getMethods(DataLoader, "Draw"))
146  functions.__register(ROOT.TMVA.Factory, Factory, *functions.__getMethods(Factory, "Draw"))
147  functions.__changeMethod(ROOT.TMVA.Factory, Factory, *functions.__getMethods(Factory, "Change"))
148  functions.__changeMethod(ROOT.TMVA.DataLoader, DataLoader, *functions.__getMethods(DataLoader, "Change"))
149  for key in functions.ThreadedFunctions:
150  for func in functions.ThreadedFunctions[key]:
151  setattr(getattr(getattr(ROOT.TMVA, key), func), "_threaded", True)
152  functions.__register(ROOT.TMVA.Factory, Factory, "BookDNN")
153 
154  ## This function will remove all functions which name contains "Draw" from TMVA.DataLoader and TMVA.Factory
155  # if the function was inserted from DataLoader and Factory modules
156  @staticmethod
157  def unregister():
158  functions.__register(ROOT.TMVA.DataLoader, DataLoader, *functions.__getMethods(DataLoader, "Draw"))
159  functions.__register(ROOT.TMVA.Factory, Factory, *functions.__getMethods(Factory, "Draw"))
160 
161 
162 ## Class for creating the output scripts and inserting them to cell output
163 class JsDraw:
164  ## String containing the link to JavaScript files
165  #__jsMVASourceDir = "https://rawgit.com/qati/GSOC16/master/src/js"
166  __jsMVASourceDir = "http://localhost:8888/notebooks/GSOC/wd/src/js"
167  ## String containing the link to CSS files
168  #__jsMVACSSDir = "https://rawgit.com/qati/GSOC16/master/src/css"
169  __jsMVACSSDir = "http://localhost:8888/notebooks/GSOC/wd/src/css"
170 
171  ## Drawing are sizes
172  jsCanvasWidth = 800
173  jsCanvasHeight = 450
174 
175  ## id for drawing area
176  __divUID = 0
177 
178  ## Template containing HTML code with draw area and drawing JavaScript
179  __jsCode = Template("""
180 <div id="$divid" style="width: ${width}px; height:${height}px"></div>
181 <script>
182  require.config({
183  paths: {
184  'JsMVA':'$PATH/JsMVA.min'
185  }
186  });
187  require(['JsMVA'],function(jsmva){
188  jsmva.$funcName('$divid','$dat');
189  });
190 </script>
191 """)
192 
193  ## Template containing data insertion JavaScript code
194  __jsCodeForDataInsert = Template("""<script id="dataInserterScript">
195 require(['JsMVA'],function(jsmva){
196 jsmva.$funcName('$divid', '$dat');
197 var script = document.getElementById("dataInserterScript");
198 script.parentElement.parentElement.remove();
199 });
200 </script>""")
201 
202  ## Inserts the draw area and drawing JavaScript to output
203  # @param obj ROOT object (will be converted to JSON) or JSON string containing the data to be drawed
204  # @param jsDrawMethod the JsMVA JavaScrip object method name to be used for drawing
205  # @param objIsJSON obj is ROOT object or JSON
206  @staticmethod
207  def Draw(obj, jsDrawMethod='draw', objIsJSON=False):
208  if objIsJSON:
209  dat = obj
210  else:
211  dat = ROOT.TBufferJSON.ConvertToJSON(obj)
212  dat = str(dat).replace("\n","")
213  JsDraw.__divUID += 1
214  display(HTML(JsDraw.__jsCode.substitute({
215  'funcName': jsDrawMethod,
216  'divid':'jstmva_'+str(JsDraw.__divUID),
217  'dat': dat,
218  'PATH': JsDraw.__jsMVASourceDir,
219  'width': JsDraw.jsCanvasWidth,
220  'height': JsDraw.jsCanvasHeight
221  })))
222 
223  ## Inserts CSS file
224  # @param cssName The CSS file name. File must be in jsMVACSSDir!
225  @staticmethod
226  def InsertCSS(cssName):
227  display(HTML('<link rel="stylesheet" href="' + JsDraw.__jsMVACSSDir + '/' +cssName+ '"></link>'))
228 
229  ## Inserts the data inserter JavaScript code to output
230  # @param obj ROOT object (will be converted to JSON) or JSON string containing the data to be inserted
231  # @param dataInserterMethod the JsMVA JavaScrip object method name to be used for inserting the new data
232  # @param objIsJSON obj is ROOT object or JSON
233  @staticmethod
234  def InsertData(obj, dataInserterMethod="updateTrainingTestingErrors", objIsJSON=False):
235  if objIsJSON:
236  dat = obj
237  else:
238  dat = ROOT.TBufferJSON.ConvertToJSON(obj)
239  dat = str(dat).replace("\n", "")
240  display(HTML(JsDraw.__jsCodeForDataInsert.substitute({
241  'funcName': dataInserterMethod,
242  'divid': 'jstmva_'+str(JsDraw.__divUID),
243  'dat': dat
244  })))
245 
246  ## Draws a signal and background histogram to a newly created TCanvas
247  # @param sig signal histogram
248  # @param bkg background histogram
249  # @param title all labels
250  @staticmethod
251  def sbPlot(sig, bkg, title):
252  canvas = ROOT.TCanvas("csbplot", title["plot"], JsDraw.jsCanvasWidth, JsDraw.jsCanvasHeight)
253  sig.SetMaximum(ROOT.TMath.Max(sig.GetMaximum()*1.1,bkg.GetMaximum()*1.1))
254  sig.SetTitle(sig.GetTitle().replace("(Signal)",""))
255  sig.GetXaxis().SetTitle(title["xaxis"])
256  sig.GetYaxis().SetTitle(title["yaxis"])
257  sig.SetTitle(title["plot"])
258  bkg.SetFillColorAlpha(ROOT.kRed, 0.3)
259  sig.SetFillColor(ROOT.kBlue)
260  bkg.SetLineColor(ROOT.kRed)
261  sig.Draw("hist")
262  bkg.Draw("histsame")
263 
264  legend = ROOT.TLegend(1-canvas.GetLeftMargin()-0.39, 1-canvas.GetTopMargin()-0.15,
265  1-canvas.GetLeftMargin()-0.01, 1-canvas.GetTopMargin()-0.01)
266  legend.SetFillStyle(1)
267  legend.AddEntry(sig, "Signal", "F")
268  legend.AddEntry(bkg, "Background", "F")
269  legend.SetBorderSize(1)
270  legend.SetMargin(0.3)
271  legend.Draw()
272 
273  return (canvas, legend)
Function inserter class This class contains the methods which are invoked by using jsmva magic...
Definition: JPyInterface.py:19
def ConvertSpecKwargsToArgs(positionalArgumentsToNamed, args, kwargs)
Get&#39;s special parameters from kwargs and converts to positional parameter.
Definition: JPyInterface.py:58
Class for creating the output scripts and inserting them to cell output.
def InsertCSS(cssName)
Inserts CSS file.
def register()
This function will register all functions which name contains "Draw" to TMVA.DataLoader and TMVA...
def unregister()
This function will remove all functions which name contains "Draw" from TMVA.DataLoader and TMVA...
def sbPlot(sig, bkg, title)
Draws a signal and background histogram to a newly created TCanvas.
def Draw(obj, jsDrawMethod='draw', objIsJSON=False)
Inserts the draw area and drawing JavaScript to output.
def InsertData(obj, dataInserterMethod="updateTrainingTestingErrors", objIsJSON=False)
Inserts the data inserter JavaScript code to output.
def ProcessParameters(optStringStartIndex, args, kwargs)
Converts object to TMVA style option string.
Definition: JPyInterface.py:81