ATLAS Offline Software
ShowerShapeRegression.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 __author__ = 'Christopher Bock - LMU'
4 
5 
7  def __init__(self, root_file_name='ISF_HitAnalysispion.root', base_output_folder='RegressionOutput'):
8  """ Most of the important settings are configured/set within this function.
9 
10  TODO: Make these options configurable via an external options file to ease the use of the script.
11  TODO: Make remaining hardcoded options configurable here.
12  """
13 
14  self.neuron_type = 'tanh' # linear does not work when fitting the efrac without log, seems to cause huge troubles somewhere
15 
16  self.log_efrac = False
17 
18  self.num_neurons = 10
19  self.root_file_name = root_file_name
20  self.base_output_folder = base_output_folder
21 
23 
25 
26  self.etaphi_nbins = [400, 400]
27  self.etaphi_xrange = [-0.4, 0.4]
28  self.etaphi_yrange = [-0.4, 0.4]
29 
30  self.cumulative_etaphi_nbins = [400, 400]
31  self.cumulative_etaphi_xrange = [-0.4, 0.4]
32  self.cumulative_etaphi_yrange = [-0.4, 0.4]
33 
34  self.equidistant_binning = False
35 
36  # self.etaphi_nbins = [200, 200]
37  # self.etaphi_xrange = [-0.2, 0.2]
38  # self.etaphi_yrange = [-0.2, 0.2]
39  #
40  # self.cumulative_etaphi_nbins = [200, 200]
41  # self.cumulative_etaphi_xrange = [-0.2, 0.2]
42  # self.cumulative_etaphi_yrange = [-0.2, 0.2]
43 
45 
48 
49  self.layer_names = ["PreSamplerB", "EMB1", "EMB2", "EMB3",
50  "PreSamplerE", "EME1", "EME2", "EME3",
51  "HEC0", "HEC1", "HEC2", "HEC3",
52  "TileBar0", "TileBar1", "TileBar2",
53  "TileGap1", "TileGap2", "TileGap3",
54  "TileExt0", "TileExt1", "TileExt2",
55  "FCAL0", "FCAL1", "FCAL2"]
56 
57  self.selected_layer = 13
58 
59  # Trees needed for regression
61 
62  from array import array
63  self.cum_eta_array = array('f', [0.])
64  self.cum_phi_array = array('f', [0.])
65  self.cum_r_array = array('f', [0.])
66  self.cum_efrac_array = array('f', [0.])
67 
68  self.regression_method = 'MLP'
69  #self.regression_method = 'FDA_GA'
70 
71  self.base_file_name = 'no_name'
72  self.mlp_base_file_name = 'no_name'
73  self.obtain_output_names()
74 
75  self.do_regression = True
76 
78  import ROOT
79  self.cum_distribution_trees = ROOT.TTree('cumulative_distributions',
80  'Cumulative eta phi energy fraction distributions')
81 
82  self.cum_distribution_trees.Branch('d_eta', self.cum_eta_array, 'd_eta/F')
83  self.cum_distribution_trees.Branch('d_phi', self.cum_phi_array, 'd_phi/F')
84  self.cum_distribution_trees.Branch('r', self.cum_r_array, 'r/F')
85  self.cum_distribution_trees.Branch('energy_fraction', self.cum_efrac_array, 'energy_fraction/F')
86 
87  pass
88 
89  def fill_regression_tree(self, cumulative_histogram):
90  """ Uses the supplied histogram to fill the regression tree with values. Depending on self.log_efrac the trees
91  are either filled with the logarithm of the energy fraction or with just the energy fraction.
92  """
93  import math
94 
95  n_bins_x = cumulative_histogram.GetNbinsX()
96  n_bins_y = cumulative_histogram.GetNbinsY()
97  from past.builtins import xrange # Temporary workaround for python2/3 compatibility - should really use range for python3
98  for x in xrange(n_bins_x + 1):
99  eta_value = cumulative_histogram.GetXaxis().GetBinCenter(x)
100  for y in xrange(n_bins_y + 1):
101  value = cumulative_histogram.GetBinContent(x, y)
102  if value <= 0:
103  continue
104 
105  phi_value = cumulative_histogram.GetYaxis().GetBinCenter(y)
106  r_value = math.sqrt(phi_value*phi_value + eta_value*eta_value)
107 
108  if self.log_efrac:
109  self.cum_efrac_array[0] = math.log(value)
110  else:
111  self.cum_efrac_array[0] = value
112 
113  self.cum_eta_array[0] = eta_value
114  self.cum_phi_array[0] = phi_value
115  self.cum_r_array[0] = r_value
116 
117  self.cum_distribution_trees.Fill()
118 
119  pass
120 
121  def run_regression(self):
122  import ROOT
123 
124  output_file = ROOT.TFile("%s.root" % self.mlp_base_file_name, "RECREATE")
125 
126  factory = ROOT.TMVA.Factory(self.mlp_base_file_name, output_file, "!V:!Silent:!Color:DrawProgressBar")
127 
128  factory.AddVariable("d_eta")
129  factory.AddVariable("d_phi")
130  factory.AddVariable("r")
131 
132  factory.AddTarget("energy_fraction")
133 
134  factory.AddRegressionTree(self.cum_distribution_trees, 1.0)
135 
136  cut = ROOT.TCut('')
137 
138  factory.PrepareTrainingAndTestTree(cut, 'nTrain_Regression=0:nTest_Regression=0:SplitMode=Random:NormMode=NumEvents:!V')
139 
140  # Default: HiddenLayers=N+20
141  factory.BookMethod(ROOT.TMVA.Types.kMLP, "MLP",
142  "!H:!V:VarTransform=Norm:NeuronType=%s:NCycles=20000:HiddenLayers=N+%i:TestRate=6:TrainingMethod=BFGS:Sampling=0.3:SamplingEpoch=0.8:ConvergenceImprove=1e-6:ConvergenceTests=15:!UseRegulator"
143  % (self.neuron_type, self.num_neurons))
144 
145  factory.TrainAllMethods()
146  factory.TestAllMethods()
147  factory.EvaluateAllMethods()
148 
149  output_file.Close()
150 
151  pass
152 
153  def run(self):
154  """ This function iterates over all events and calls for each event the process_entry function. The event loop
155  breaks either once process_entry returns false or once all events in the input file have been processed.
156  """
157  import ROOT
158 
159  print('--------------------------------------------')
160  print('Welcome to ShowerShapeRegressor.py')
161  print('Using %i neurons of type %s using log of efrac: %s' % (self.num_neurons, self.neuron_type,
162  str(self.log_efrac)))
163  print('--------------------------------------------')
164 
165  self.obtain_output_names()
166 
167  f = ROOT.TFile(self.root_file_name) # noqa: F841
168  chain = ROOT.gDirectory.Get('ISF_HitAnalysis/CaloHitAna')
169  entries = chain.GetEntriesFast()
170 
171  for current_entry in range(entries):
172  print(' Loading entry: %i' % current_entry)
173  j = chain.LoadTree(current_entry)
174  if j < 0:
175  break
176 
177  # copy next entry into memory and verify
178  bites_read = chain.GetEntry(current_entry)
179  if bites_read <= 0:
180  continue
181 
182  if not self.process_entry(chain, current_entry):
183  break
184 
185  if len(self.eta_phi_efrac_hists) > 0:
186  self.create_output()
187 
188  pass
189 
190  def process_entry(self, chain, event_number):
191  """ This processes a single event in the chain. It first checks whether this event should be processed by
192  calling the take_event_into_account function. If this function returns true processing of this event continues
193  else the event will be skipped.
194  Only a single layer (self.selected_layer) will be processed. A histogram will be filled with the energy
195  distribution vs eta and phi. Corrections by the track to calo extrapolator will be applied here. Once all
196  events have been finished the histogram will be divided by its integral.
197  Once the desired number of events (self.cumulated_events_threshold) has been reached the self.create_output()
198  function will be called.
199  """
200  import ROOT
201 
202  if not self.take_event_into_account(chain, event_number):
203  return True
204 
205  num_hits = len(chain.HitX)
206 
207  eta_phi_efrac_dist = ROOT.TH2D('eta_phi_efrac_dist_%i' % event_number, 'eta vs phi vs efrac',
211  for i in range(num_hits):
212  layer_id = chain.HitSampling[i]
213 
214  if not layer_id == self.selected_layer:
215  continue
216 
217  pos = ROOT.TVector3(chain.HitX[i], chain.HitY[i], chain.HitZ[i])
218  eta = pos.PseudoRapidity()
219  phi = pos.Phi()
220 
221  eta_correction = chain.TTC_entrance_eta[0][layer_id]
222  phi_correction = chain.TTC_entrance_phi[0][layer_id]
223 
224  if eta_correction < -900:
225  eta_correction = 0
226  print('no valid eta_correction found')
227 
228  if phi_correction < -900:
229  phi_correction = 0
230  print('no valid phi_correction found')
231 
232  d_eta = eta - eta_correction
233  d_phi = self.phi_mpi_pi(phi - phi_correction)
234 
235  eta_phi_efrac_dist.Fill(d_eta, d_phi, chain.HitE[i])
236 
237  self.cumulated_events += 1
238 
239  if eta_phi_efrac_dist.Integral() > 0:
240  eta_phi_efrac_dist.Scale(1.0/eta_phi_efrac_dist.Integral())
241 
242  self.eta_phi_efrac_hists.append(eta_phi_efrac_dist)
244  self.create_output()
245  return False
246 
247  return True
248 
249  def take_event_into_account(self, chain, event_number):
250  """ This function is used to filter events.
251  """
252  if chain.TruthE[0] < self.truth_energy_threshold:
253  print(' Pion does not pass energy threshold of %f skipping process_entry!' %
255  return False
256 
257  return True
258 
259  def create_output(self):
260  """ This function creates the average shower shape from all the energy fraction distributions and plots it. In
261  case self.do_regression is set to True, it will initialize the input trees used by TMVA (using
262  self.initialize_cumulative_trees), it will fill them (using self.fill_regression_tree) and run the regression
263  by calling self.run_regression. Once TMVA finished, regression test/control plots and our shower shape control
264  plots will be created.
265  """
266  import ROOT
267 
268  cumulative_histogram = self.create_eta_phi_histogram(self.base_file_name, 'cumulative eta vs phi vs efrac')
269 
270  if self.equidistant_binning:
271  for hist in self.eta_phi_efrac_hists:
272  cumulative_histogram.Add(hist)
273 
274  if cumulative_histogram.Integral() > 0:
275  cumulative_histogram.Scale(1.0/cumulative_histogram.Integral())
276  else:
277  # first fill the cumulative histogram
278  x_axis = self.eta_phi_efrac_hists[0].GetXaxis()
279  n_bins_x = x_axis.GetNbins()
280 
281  y_axis = self.eta_phi_efrac_hists[0].GetYaxis()
282  n_bins_y = y_axis.GetNbins()
283  for x_bin in range(n_bins_x + 1):
284  x_center = x_axis.GetBinCenter(x_bin)
285  for y_bin in range(n_bins_y + 1):
286  y_center = x_axis.GetBinCenter(y_bin)
287  for hist in self.eta_phi_efrac_hists:
288  value = hist.GetBinContent(x_bin, y_bin)
289  cumulative_histogram.Fill(x_center, y_center, value)
290 
291  # now calculate the PDF
292  x_axis = cumulative_histogram.GetXaxis()
293  n_bins_x = x_axis.GetNbins()
294 
295  y_axis = cumulative_histogram.GetYaxis()
296  n_bins_y = y_axis.GetNbins()
297  for x_bin in range(n_bins_x + 1):
298  x_bin_width = x_axis.GetBinWidth(x_bin)
299  for y_bin in range(n_bins_y + 1):
300  y_bin_width = y_axis.GetBinWidth(y_bin)
301  area = x_bin_width*y_bin_width
302 
303  cumulative_content = cumulative_histogram.GetBinContent(x_bin, y_bin) / area
304  cumulative_histogram.SetBinContent(x_bin, y_bin, cumulative_content)
305 
306  if cumulative_histogram.Integral() > 0:
307  cumulative_histogram.Scale(1.0/cumulative_histogram.Integral())
308 
309  from os import path
310  cumulative_etaphi_file_name = path.join(self.base_output_folder, 'cumulative_eta_phi',
311  'average_shower_%s.pdf' % self.base_file_name)
312  cumulative_etaphi_root_file_name = path.join(self.base_output_folder, 'cumulative_eta_phi',
313  '%s.root' % self.base_file_name)
314 
315  root_file = ROOT.TFile(cumulative_etaphi_root_file_name, 'RECREATE')
316  root_file.cd()
317  self.plot_root_hist2d(cumulative_histogram.Clone(), cumulative_etaphi_file_name, '#eta', '#phi',
318  root_file=root_file)
319  root_file.Write()
320  root_file.Close()
321 
322  if self.do_regression:
323  if cumulative_histogram.Integral() > 0:
324  cumulative_histogram.Scale(1.0/cumulative_histogram.Integral())
325 
327  self.fill_regression_tree(cumulative_histogram)
328 
329  self.run_regression()
331  self.shower_test_plot_tmva(cumulative_histogram)
332  self.shower_test_plot_tmva(cumulative_histogram, False)
333  self.shower_test_plot_getrandom2(cumulative_histogram)
334 
335  for hist in self.eta_phi_efrac_hists:
336  hist.Delete()
337 
338  self.eta_phi_efrac_hists = []
339  self.cumulated_events = 0
340 
341  return
342 
343  """
344  =========================================== Output Folder Functions ===============================================
345  The following are functions used to create the output folders and to obtain the names of the outputs.
346  ===================================================================================================================
347  """
348 
349  @staticmethod
350  def check_folder(folder):
351  import os
352  from os import path
353  if not path.exists(folder):
354  print('Output folder %s does not exist, will try to create it.' % folder)
355  os.makedirs(folder)
356  if not path.exists(folder):
357  raise Exception('ERROR: Could not create output folder!')
358  else:
359  print('Basic output folder successfully created :)')
360 
362  from os import path
364  self.check_folder(path.join(self.base_output_folder, 'cumulative_eta_phi'))
365  pass
366 
368  ext = ''
369  if self.log_efrac:
370  ext = '_logEfrac'
371 
372  eq_bin = ''
373  if self.equidistant_binning:
374  eq_bin = '_eqbin'
375 
376  self.base_file_name = 'Evts%i_Lay%i_E%i_eta%.2f_PID%i%s' \
377  % (self.cumulated_events_threshold, self.selected_layer, 50, 0.20, 211, eq_bin)
378  self.mlp_base_file_name = 'NN_reg%s_%s_NNeur%i_NT%s_%s' % (ext, self.regression_method, self.num_neurons,
379  self.neuron_type, self.base_file_name)
380 
381  """
382  =============================================== Plot Functions ====================================================
383  The following functions areused to create the plots. The "plot_regression_control_plots" function is a
384  reimplementation of a similar function found in TMVA's examples. It searches for TMVA's control plots inside the
385  root file and plots them.
386  ===================================================================================================================
387  """
388 
389  def create_eta_phi_histogram(self, name, title):
390  """ This is a helper function to create the eta phi histograms either with equidistant or non-equidistant
391  binning depending on the settings. Please use this function to avoid code duplication.
392  """
393 
394  import ROOT
395  if self.equidistant_binning:
396  eta_phi_histogram = ROOT.TH2D(name, title,
400  else:
401  import array
402  x_binning = [-0.4, -0.1, -0.05, -0.04, -0.03, -0.02, -0.016, -0.014, -0.012, -0.01, -0.008, -0.006,
403  -0.004, -0.002, 0, 0.002, 0.004, 0.006, 0.008, 0.01, 0.012, 0.014, 0.016, 0.02, 0.03, 0.04,
404  0.05, 0.1, 0.4]
405  y_binning = x_binning
406 
407  eta_phi_histogram = ROOT.TH2D(name, title,
408  len(x_binning) - 1, array.array('d', x_binning),
409  len(y_binning) - 1, array.array('d', y_binning))
410 
411  return eta_phi_histogram
412 
413  def shower_test_plot_getrandom2(self, histogram):
414  """ This function uses the input histogram's GetRandom2 function to draw random numbers according to the
415  distribution found in the input histogram and fills 50000 entries into a new histogram and in the end prints
416  it to a file.
417  """
418  import ROOT
419  from os import path
420  ROOT.gROOT.SetBatch(True)
421 
422  ROOT.gStyle.SetNumberContours(999)
423 
424  d_eta = ROOT.Double(0)
425  d_phi = ROOT.Double(0)
426 
427  eta_phi_efrac_dist = self.create_eta_phi_histogram('shower_test_plot',
428  'eta vs phi vs efrac - using TH2F::GetRandom2')
429 
430  accepted_points = 0
431  accepted_points_target = 50000
432  while accepted_points < accepted_points_target:
433  histogram.GetRandom2(d_eta, d_phi)
434 
435  eta_phi_efrac_dist.Fill(d_eta, d_phi, 1)
436  accepted_points += 1
437 
438  if eta_phi_efrac_dist.Integral() > 0:
439  eta_phi_efrac_dist.Scale(1.0/eta_phi_efrac_dist.Integral())
440  self.plot_root_hist2d(eta_phi_efrac_dist,
441  path.join(self.base_output_folder, '%s_th2f.pdf' % self.mlp_base_file_name), '#eta', '#phi')
442  self.difference_to_reference(histogram, eta_phi_efrac_dist,
443  path.join(self.base_output_folder, '%s_th2f_diff.pdf' % self.mlp_base_file_name),
444  '#eta', '#phi')
445 
446  self.difference_to_reference(histogram, eta_phi_efrac_dist,
447  path.join(self.base_output_folder, '%s_th2f_diff_inf.pdf' % self.mlp_base_file_name),
448  '#eta', '#phi', inverted_ratio=True)
449 
450  pass
451 
452  def shower_test_plot_tmva(self, reference, randomize_pos=True):
453  """ This function uses the NN obtained by TMVA to plot the fitted shower shape and the ratio to the reference.
454  In case randomize_pos is set to true (which is the default), random positions (flat distributed) in the eta-phi
455  plane will drawn. The NN will be evaluated there and the value will be filled into the output histogram. This
456  method is faster than drawing a third random number and accepting the point based on whether this rnd number is
457  greater than the NN at this point or not.
458  If randomize_pos is set to false, a histogram will be filled by evaluating the NN at each point and filling the
459  value into the histogram.
460  """
461  import ROOT
462  import math
463  ROOT.gROOT.SetBatch(True)
464 
465  ROOT.gStyle.SetNumberContours(999)
466 
467  reader = ROOT.TMVA.Reader('!Color')
468 
469  from array import array
470  d_eta = array('f', [0.])
471  d_phi = array('f', [0.])
472  r = array('f', [0])
473  reader.AddVariable('d_eta', d_eta)
474  reader.AddVariable('d_phi', d_phi)
475  reader.AddVariable('r', r)
476 
477  from os import path
478  base_weight_name = self.mlp_base_file_name
479  method_name = self.regression_method
480  weight_file = path.join('weights', '%s_%s.weights.xml' % (base_weight_name, method_name))
481  reader.BookMVA(self.regression_method, weight_file)
482 
483  ext = ''
484  if randomize_pos:
485  ext = ' rnd pos'
486 
487  eta_phi_efrac_dist = self.create_eta_phi_histogram('shower_test_plot', 'eta vs phi vs efrac - using %s%s' %
488  (self.regression_method, ext))
489  if randomize_pos:
490  accepted_points = 0
491  accepted_points_target = 50000
492  while accepted_points < accepted_points_target:
493  d_eta[0] = ROOT.gRandom.Rndm() - 0.5
494  d_phi[0] = ROOT.gRandom.Rndm() - 0.5
495  r[0] = math.sqrt(d_eta[0]*d_eta[0] + d_phi[0]*d_phi[0])
496 
497  value = reader.EvaluateRegression(self.regression_method)[0]
498 
499  if self.log_efrac:
500  value = math.exp(value)
501 
502  eta_phi_efrac_dist.Fill(d_eta[0], d_phi[0], value)
503  accepted_points += 1
504  else:
505  x_axis = reference.GetXaxis()
506  y_axis = reference.GetYaxis()
507  n_bins_x = x_axis.GetNbins()
508  n_bins_y = y_axis.GetNbins()
509  for x in range(n_bins_x + 1):
510  d_eta[0] = x_axis.GetBinCenter(x)
511  for y in range(n_bins_y + 1):
512  d_phi[0] = y_axis.GetBinCenter(y)
513  r[0] = math.sqrt(d_eta[0]*d_eta[0] + d_phi[0]*d_phi[0])
514 
515  value = reader.EvaluateRegression(self.regression_method)[0]
516 
517  if self.log_efrac:
518  value = math.exp(value)
519 
520  eta_phi_efrac_dist.Fill(d_eta[0], d_phi[0], value)
521 
522  if eta_phi_efrac_dist.Integral() > 0:
523  eta_phi_efrac_dist.Scale(1.0/eta_phi_efrac_dist.Integral())
524 
525  if randomize_pos:
526  ext = '_rnd'
527 
528  self.plot_root_hist2d(eta_phi_efrac_dist,
529  path.join(self.base_output_folder, '%s%s.pdf' % (self.mlp_base_file_name, ext)),
530  '#eta', '#phi')
531  self.difference_to_reference(reference, eta_phi_efrac_dist,
532  path.join(self.base_output_folder, '%s%s_diff.pdf' %
533  (self.mlp_base_file_name, ext)), '#eta', '#phi')
534 
535  self.difference_to_reference(reference, eta_phi_efrac_dist,
536  path.join(self.base_output_folder, '%s%s_diff_inv.pdf' %
537  (self.mlp_base_file_name, ext)), '#eta', '#phi', inverted_ratio=True)
538 
539  pass
540 
541  def plot_regression_control_plots(self, file_name=None, show_target=False, compare_to_train=False):
542  """ This is a pythonic translation of the deviations function found in the TMVA examples.
543  """
544  import ROOT
545  ROOT.gROOT.SetBatch(True)
546 
547  #ROOT.TMVA.TMVAGlob.Initialize(True)
548  ROOT.gStyle.SetNumberContours(999)
549 
550  if not file_name:
551  file_name = '%s.root' % self.mlp_base_file_name
552  input_file = ROOT.TFile(file_name)
553 
554  current_canvas = 0
555  for key in input_file.GetListOfKeys():
556  print('Key: %s' % key.GetName())
557 
558  if 'Method_' not in key.GetName():
559  continue
560  if not ROOT.gROOT.GetClass(key.GetClassName()).InheritsFrom('TDirectory'):
561  continue
562 
563  method_name = key.GetName().replace('Method_', '')
564 
565  print('Now plotting control plots for method %s' % method_name)
566 
567  directory = key.ReadObj()
568 
569  for sub_method in directory.GetListOfKeys():
570  print('sub_method: %s' % sub_method.GetName())
571 
572  if not ROOT.gROOT.GetClass(sub_method.GetClassName()).InheritsFrom('TDirectory'):
573  continue
574 
575  sub_method_name = sub_method.GetName()
576 
577  print('Now plotting control plots for sub-method %s' % sub_method_name)
578 
579  sub_directory = sub_method.ReadObj()
580 
581  for plot_key in sub_directory.GetListOfKeys():
582  print('plot_key: %s' % plot_key.GetName())
583 
584  plot_obj = plot_key.ReadObj()
585  if isinstance(plot_obj, ROOT.TH2F):
586  plot_name = plot_key.GetName()
587  if '_reg_' not in plot_name:
588  continue
589 
590  if not ((show_target and '_tgt' in plot_name) or
591  (not show_target and ('_tgt' not in plot_name))):
592  continue
593 
594  if not ((compare_to_train and 'train' in plot_name) or
595  (not compare_to_train and 'test' in plot_name)):
596  continue
597 
598  inortarg = 'input'
599  type_string = 'test'
600  if show_target:
601  inortarg = 'target'
602 
603  if compare_to_train:
604  type_string = 'training'
605 
606  canvas = ROOT.TCanvas('canvas_%i' % current_canvas,
607  'Regression output deviation versus %s for method %s' % (inortarg,
608  method_name), 800, 600)
609 
610  canvas.SetRightMargin(0.10)
611 
612  plot_obj.SetTitle('Output deviation for method: %s (%s sample)' % (sub_method_name,
613  type_string))
614  plot_obj.Draw('colz')
615 
616  line = ROOT.TLine(plot_obj.GetXaxis().GetXmin(), 0, plot_obj.GetXaxis().GetXmax(), 0)
617  line.SetLineStyle(2)
618  line.Draw()
619 
620  canvas.Update()
621 
622  import os
623  output_name = os.path.join(self.base_output_folder, '%s_dev_%s_%s_%s_%i.pdf' %
624  (self.mlp_base_file_name, method_name, inortarg, type_string,
625  current_canvas))
626  #ROOT.TMVAGlob.imgconv(canvas, output_name)
627  canvas.Print(output_name, 'pdf')
628 
629  current_canvas += 1
630 
631  pass
632 
633  @staticmethod
634  def plot_root_hist2d(histogram, file_name='root_hist2d.pdf', x_label='X-Axis', y_label='Y-Axis',
635  z_label='Probability', logscale=False, normalize=False, root_file=None):
636  import ROOT
637  ROOT.gROOT.SetBatch(True)
638  ROOT.gStyle.SetOptStat(1)
639 
640  from os import path
641  ext = path.splitext(path.basename(file_name))[1]
642 
643  canv = ROOT.TCanvas('canvas', 'test', 0, 0, 600, 600)
644  #canv.SetTopMargin(0.05)
645  #canv.SetLeftMargin(0.13)
646  canv.SetRightMargin(0.15)
647  #canv.SetBottomMargin(0.035)
648 
649  if logscale:
650  canv.SetLogz()
651 
652  if normalize:
653  integral = histogram.Integral()
654  if integral > 0:
655  histogram.Scale(1.0 / integral)
656 
657  histogram.GetXaxis().SetTitle(x_label)
658  histogram.GetYaxis().SetTitle(y_label)
659  histogram.GetZaxis().SetTitle(z_label)
660 
661  # histogram.GetYaxis().SetLabelSize(0.06)
662  # histogram.GetYaxis().SetLabelOffset(0.0015)
663  #
664  # histogram.GetYaxis().SetTitleSize(0.06)
665  # histogram.GetYaxis().SetTitleOffset(0.85)
666 
667  histogram.Draw('COLZ')
668 
669  canv.Update()
670  canv.Print(file_name, ext)
671 
672  if root_file:
673  histogram.SetDirectory(root_file)
674  histogram.Write()
675 
676  pass
677 
678  """
679  ========================================== Utility Functions ======================================================
680  The following section will contain utility functions to ease some repetitive tasks. Those functions should be self-
681  explanatory.
682  ===================================================================================================================
683  """
684 
685  def difference_to_reference(self, reference, histogram, output_name, x_label, y_label, inverted_ratio=False):
686  if inverted_ratio:
687  clone = reference.Clone(reference.GetName() + 'diff_to_ref_clone')
688  base = histogram
689  else:
690  clone = histogram.Clone(histogram.GetName() + 'diff_to_ref_clone')
691  base = reference
692 
693  clone.Add(base, -1.0)
694  clone.Divide(base)
695 
696  if inverted_ratio:
697  z_label = 'reference - output / output'
698  else:
699  z_label = 'output - reference / reference'
700 
701  self.plot_root_hist2d(clone, output_name, x_label, y_label, z_label, logscale=True)
702 
703  pass
704 
705  def get_layer_name(self, layer_id):
706  if layer_id < 0 or layer_id >= len(self.layer_names):
707  return 'Unknown'
708  else:
709  return self.layer_names[layer_id]
710 
711  @staticmethod
712  def phi_mpi_pi(phi):
713  import ROOT
714  pi = ROOT.TMath.Pi()
715  while phi >= pi:
716  phi -= pi
717  while phi < -pi:
718  phi += pi
719  return phi
720 
721 
722 def run_reg(neuron_type, num_neurons):
723  plotter = ShowerShapeRegressor()
724 
725  plotter.cumulated_events_threshold = 1000
726 
727  plotter.neuron_type = neuron_type
728  plotter.num_neurons = num_neurons
729 
730  plotter.log_efrac = True
731 
732  plotter.run()
733 
734  return
735 
736 
737 if __name__ == "__main__":
738 
739  #for nn in [5, 10, 15]:
740  #for nt in ['tanh', 'radial', 'sigmoid']:
741  run_reg('tanh', 5)
742 
743  import time
744  from distutils import archive_util
745  # make_zipfile automagically adds the .zip extension
746  archive_util.make_zipfile('reg_out_%s' % (time.strftime("%y-%m-%d_%H-%M")),
747  'RegressionOutput')
748  archive_util.make_zipfile('weights_%s' % (time.strftime("%y-%m-%d_%H-%M")),
749  'weights')
xrange
void xrange(TH1 *h, bool symmetric)
Definition: computils.cxx:515
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
ShowerShapeRegression.ShowerShapeRegressor.plot_regression_control_plots
def plot_regression_control_plots(self, file_name=None, show_target=False, compare_to_train=False)
Definition: ShowerShapeRegression.py:541
ShowerShapeRegression.ShowerShapeRegressor.create_eta_phi_histogram
def create_eta_phi_histogram(self, name, title)
Definition: ShowerShapeRegression.py:389
ShowerShapeRegression.ShowerShapeRegressor
Definition: ShowerShapeRegression.py:6
ShowerShapeRegression.ShowerShapeRegressor.plot_root_hist2d
def plot_root_hist2d(histogram, file_name='root_hist2d.pdf', x_label='X-Axis', y_label='Y-Axis', z_label='Probability', logscale=False, normalize=False, root_file=None)
Definition: ShowerShapeRegression.py:634
ShowerShapeRegression.ShowerShapeRegressor.log_efrac
log_efrac
Definition: ShowerShapeRegression.py:16
ShowerShapeRegression.ShowerShapeRegressor.base_output_folder
base_output_folder
Definition: ShowerShapeRegression.py:20
ShowerShapeRegression.ShowerShapeRegressor.check_folder
def check_folder(folder)
Definition: ShowerShapeRegression.py:350
ShowerShapeRegression.ShowerShapeRegressor.difference_to_reference
def difference_to_reference(self, reference, histogram, output_name, x_label, y_label, inverted_ratio=False)
Definition: ShowerShapeRegression.py:685
ShowerShapeRegression.ShowerShapeRegressor.cumulative_etaphi_yrange
cumulative_etaphi_yrange
Definition: ShowerShapeRegression.py:32
ShowerShapeRegression.ShowerShapeRegressor.regression_method
regression_method
Definition: ShowerShapeRegression.py:68
ShowerShapeRegression.ShowerShapeRegressor.initialize_cumulative_trees
def initialize_cumulative_trees(self)
Definition: ShowerShapeRegression.py:77
ShowerShapeRegression.ShowerShapeRegressor.do_regression
do_regression
Definition: ShowerShapeRegression.py:75
ShowerShapeRegression.ShowerShapeRegressor.shower_test_plot_tmva
def shower_test_plot_tmva(self, reference, randomize_pos=True)
Definition: ShowerShapeRegression.py:452
ShowerShapeRegression.ShowerShapeRegressor.cum_efrac_array
cum_efrac_array
Definition: ShowerShapeRegression.py:66
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
ShowerShapeRegression.ShowerShapeRegressor.layer_names
layer_names
Definition: ShowerShapeRegression.py:49
ShowerShapeRegression.ShowerShapeRegressor.take_event_into_account
def take_event_into_account(self, chain, event_number)
Definition: ShowerShapeRegression.py:249
ShowerShapeRegression.ShowerShapeRegressor.cumulated_events
cumulated_events
Definition: ShowerShapeRegression.py:46
ShowerShapeRegression.ShowerShapeRegressor.truth_energy_threshold
truth_energy_threshold
Definition: ShowerShapeRegression.py:22
ShowerShapeRegression.ShowerShapeRegressor.cumulated_events_threshold
cumulated_events_threshold
Definition: ShowerShapeRegression.py:47
ShowerShapeRegression.ShowerShapeRegressor.cum_distribution_trees
cum_distribution_trees
Definition: ShowerShapeRegression.py:60
ShowerShapeRegression.ShowerShapeRegressor.process_entry
def process_entry(self, chain, event_number)
Definition: ShowerShapeRegression.py:190
ShowerShapeRegression.ShowerShapeRegressor.cum_r_array
cum_r_array
Definition: ShowerShapeRegression.py:65
ShowerShapeRegression.ShowerShapeRegressor.selected_layer
selected_layer
Definition: ShowerShapeRegression.py:57
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
ShowerShapeRegression.run_reg
def run_reg(neuron_type, num_neurons)
Definition: ShowerShapeRegression.py:722
ShowerShapeRegression.ShowerShapeRegressor.shower_test_plot_getrandom2
def shower_test_plot_getrandom2(self, histogram)
Definition: ShowerShapeRegression.py:413
ShowerShapeRegression.ShowerShapeRegressor.fill_regression_tree
def fill_regression_tree(self, cumulative_histogram)
Definition: ShowerShapeRegression.py:89
ShowerShapeRegression.ShowerShapeRegressor.__init__
def __init__(self, root_file_name='ISF_HitAnalysispion.root', base_output_folder='RegressionOutput')
Definition: ShowerShapeRegression.py:7
ShowerShapeRegression.ShowerShapeRegressor.cumulative_etaphi_nbins
cumulative_etaphi_nbins
Definition: ShowerShapeRegression.py:30
array
ShowerShapeRegression.ShowerShapeRegressor.equidistant_binning
equidistant_binning
Definition: ShowerShapeRegression.py:34
ShowerShapeRegression.ShowerShapeRegressor.create_output
def create_output(self)
Definition: ShowerShapeRegression.py:259
ShowerShapeRegression.ShowerShapeRegressor.root_file_name
root_file_name
Definition: ShowerShapeRegression.py:19
ShowerShapeRegression.ShowerShapeRegressor.run_regression
def run_regression(self)
Definition: ShowerShapeRegression.py:121
ShowerShapeRegression.ShowerShapeRegressor.etaphi_nbins
etaphi_nbins
Definition: ShowerShapeRegression.py:26
ShowerShapeRegression.ShowerShapeRegressor.eta_phi_efrac_hists
eta_phi_efrac_hists
Definition: ShowerShapeRegression.py:44
ShowerShapeRegression.ShowerShapeRegressor.obtain_output_names
def obtain_output_names(self)
Definition: ShowerShapeRegression.py:367
ShowerShapeRegression.ShowerShapeRegressor.neuron_type
neuron_type
Definition: ShowerShapeRegression.py:14
ShowerShapeRegression.ShowerShapeRegressor.phi_mpi_pi
def phi_mpi_pi(phi)
Definition: ShowerShapeRegression.py:712
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
ShowerShapeRegression.ShowerShapeRegressor.cum_phi_array
cum_phi_array
Definition: ShowerShapeRegression.py:64
ShowerShapeRegression.ShowerShapeRegressor.num_neurons
num_neurons
Definition: ShowerShapeRegression.py:18
ShowerShapeRegression.ShowerShapeRegressor.check_output_folders
def check_output_folders(self)
Definition: ShowerShapeRegression.py:361
ShowerShapeRegression.ShowerShapeRegressor.base_file_name
base_file_name
Definition: ShowerShapeRegression.py:71
str
Definition: BTagTrackIpAccessor.cxx:11
ShowerShapeRegression.ShowerShapeRegressor.cumulative_etaphi_xrange
cumulative_etaphi_xrange
Definition: ShowerShapeRegression.py:31
ShowerShapeRegression.ShowerShapeRegressor.mlp_base_file_name
mlp_base_file_name
Definition: ShowerShapeRegression.py:72
ShowerShapeRegression.ShowerShapeRegressor.cum_eta_array
cum_eta_array
Definition: ShowerShapeRegression.py:63
ShowerShapeRegression.ShowerShapeRegressor.run
def run(self)
Definition: ShowerShapeRegression.py:153
ShowerShapeRegression.ShowerShapeRegressor.etaphi_xrange
etaphi_xrange
Definition: ShowerShapeRegression.py:27
ShowerShapeRegression.ShowerShapeRegressor.etaphi_yrange
etaphi_yrange
Definition: ShowerShapeRegression.py:28
ShowerShapeRegression.ShowerShapeRegressor.get_layer_name
def get_layer_name(self, layer_id)
Definition: ShowerShapeRegression.py:705