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