Crombie Tools
__init__.py
Go to the documentation of this file.
1 """ @package CrombieTools
2 1;95;0cBase package module of everything used through python.
3 
4 This contains a useful functions for compiling objects while loading
5 them into ROOT and for creating directories from environment variables
6 loaded by submodules. There are also several submodules contained in
7 the package.
8 @todo Set up a central FileConfigReader python class that other config readers inherit from
9 @author Daniel Abercrombie <dabercro@mit.edu>
10 """
11 
12 try:
13  import ROOT
14  ROOT.PyConfig.IgnoreCommandLineOptions = True
15 except:
16  ROOT = None
17 
18 import os
19 import re
20 
21 __all__ = ['AnalysisTools', 'CommonTools', 'PlotTools', 'SkimmingTools', 'Parallelization']
22 
23 if ROOT:
24  ROOT.gROOT.SetBatch(True)
25 
26 """Location of CrombieTools package, based on environment."""
27 CrombieDir = os.environ['CROMBIEPATH'] + '/old'
28 
29 if CrombieDir == '':
30  print('#########################################################')
31  print('# #')
32  print('# CROMBIEPATH variable is not set! #')
33  print('# You have not successfully installed CrombieTools. #')
34  print('# Run CrombieTools/install.sh or read #')
35  print('# CrombieTools/README.md to troubleshoot. #')
36  print('# #')
37  print('#########################################################')
38  exit(1)
39 
40 if ROOT:
41  for package in __all__:
42  if os.path.exists(CrombieDir + '/' + package + '/interface'):
43  ROOT.gSystem.AddIncludePath('-I' + CrombieDir + '/' + package + '/interface/')
44 
45 if ROOT:
46  ROOT.gROOT.LoadMacro(CrombieDir + '/PlotTools/interface/KinematicFunctions.h')
47 
48 """Key -- Class to load : Value -- List of classes that must be loaded first."""
49 dependencies = { 'FlatSkimmer' : ['GoodLumiFilter'],
50  'PlotFitParameters' : ['Plot2D'],
51  'TmvaClassifier' : ['TreeContainer'],
52  'FitTools' : ['HistAnalysis'],
53  'TwoScaleFactorCorrector' : ['Corrector'],
54  'FormulaCorrector' : ['Corrector'],
55  'CorrectorApplicator' : ['Corrector'],
56  'TMVACorrector' : ['Corrector']
57  }
58 
59 loadAddOn = '+'
60 """Add characters after LoadMacro command. Modified if CrombieTools.debug is imported"""
61 
62 def Load(className):
63  """ Loads a class from Crombie Tools into ROOT.
64 
65  @param className is the name of a class in the Crombie Tools package.
66  @returns the function pointer for the constructor, except in the case of PlotUtils.
67  In that case, 0 is returned. It would be much better to import what
68  you need from CrombieTools.PlotTools.PlotUtils.
69  """
70 
71  if not className in dir(ROOT):
72  if type(dependencies.get(className)) is list:
73  for depend in dependencies[className]:
74  Load(depend)
75 
76  toLoad = ''
77  for package in __all__:
78  checkFile = CrombieDir + '/' + package + '/src/' + className + '.cc'
79  if os.path.exists(checkFile):
80  toLoad = checkFile
81  break
82 
83  if toLoad == '':
84  print('')
85  print('Can\'t find class: ' + className)
86  print('in CrombieTools... Exiting.')
87  exit(1)
88 
89  ROOT.gROOT.LoadMacro(toLoad + loadAddOn)
90 
91  if className in ['PlotUtils']:
92  return 0
93 
94  return getattr(ROOT, className)
95 
96 def DirFromEnv(envVar, default='tmp_dir'):
97  """Creates a directory stored in an environment variable.
98 
99  Generally does not need to be called by the user. Multiple submodules make use of this command.
100  @param envVar is the name of the environment variable containing a directory name.
101  @param default is the default value of the directory location if the environment variable is not filled.
102  """
103 
104  import LoadConfig
105 
106  directory = os.environ.get(envVar, default)
107 
108  if not os.path.exists(directory):
109  os.makedirs(directory)
110 
111 def Nminus1Cut(inCut, varToRemove, returnCuts=False):
112  """ A function for getting N - 1 plots.
113 
114  Given a cutstring and a variable name, all comparison expressions with that variable are removed.
115  @param inCut is the full cutstring
116  @param varToRemove is the variable to remove from the cutstring (usually a variable being plotted).
117  @param returnCuts sets whether to return the cuts values (True) or the new cuts string (False).
118  @returns a version of the cutstring without any comparisons to varToRemove or the cuts values.
119  @todo I want this to ignore cuts next to an '||'? Or I have the weird '&&' veto thing... That's trickier to fix
120  """
121  holdCut = str(inCut)
122  # First match the expression with the variable. It has to be to the left of the comparison operator.
123  # (This is a feature, not a bug. We want to be immune to the automatic n-1 cut sometimes.)
124  matches = re.findall(r'(?<!\w)' + re.escape(varToRemove) + r'(?!\w)\s*[=<>]+\s*-?[0-9\.]+', holdCut)
125  cutList = []
126  for match in matches:
127  # Get the number out of the matched expression so that we can draw lines where the cuts should go
128  cutMatch = re.search(r'(?<!\w)-?[\d\.]+(?!\w)$', match)
129  if cutMatch:
130  cutList.append(float(cutMatch.group()))
131  holdCut = holdCut.replace(match, '(1)', 1)
132 
133  if returnCuts:
134  return cutList
135  else:
136  return holdCut.replace(' && (1)', '')