CMS 3D CMS Logo

helperFunctions.py
Go to the documentation of this file.
1 from __future__ import print_function
2 import os
3 import re
4 import ROOT
5 import sys
6 from TkAlExceptions import AllInOneError
7 import six
8 
9 ####################--- Helpers ---############################
10 def replaceByMap(target, the_map):
11  """This function replaces `.oO[key]Oo.` by `the_map[key]` in target.
12 
13  Arguments:
14  - `target`: String which contains symbolic tags of the form `.oO[key]Oo.`
15  - `the_map`: Dictionary which has to contain the `key`s in `target` as keys
16  """
17 
18  result = target
19  for key in the_map:
20  lifeSaver = 10e3
21  iteration = 0
22  while ".oO[" in result and "]Oo." in result:
23  for key in the_map:
24  try:
25  result = result.replace(".oO["+key+"]Oo.",the_map[key])
26  except TypeError: #try a dict
27  try:
28  for keykey, value in six.iteritems(the_map[key]):
29  result = result.replace(".oO[" + key + "['" + keykey + "']]Oo.", value)
30  result = result.replace(".oO[" + key + '["' + keykey + '"]]Oo.', value)
31  except AttributeError: #try a list
32  try:
33  for index, value in enumerate(the_map[key]):
34  result = result.replace(".oO[" + key + "[" + str(index) + "]]Oo.", value)
35  except TypeError:
36  raise TypeError("Something is wrong in replaceByMap! Need a string, dict, or list, but the_map(%s)=%s!"%(repr(key), repr(the_map[key])))
37  iteration += 1
38  if iteration > lifeSaver:
39  problematicLines = ""
40  for line in result.splitlines():
41  if ".oO[" in result and "]Oo." in line:
42  problematicLines += "%s\n"%line
43  msg = ("Oh Dear, there seems to be an endless loop in "
44  "replaceByMap!!\n%s\n%s"%(problematicLines, the_map))
45  raise AllInOneError(msg)
46  return result
47 
48 
49 def getCommandOutput2(command):
50  """This function executes `command` and returns it output.
51 
52  Arguments:
53  - `command`: Shell command to be invoked by this function.
54  """
55 
56  child = os.popen(command)
57  data = child.read()
58  err = child.close()
59  if err:
60  raise RuntimeError('%s failed w/ exit code %d' % (command, err))
61  return data
62 
63 
64 def castorDirExists(path):
65  """This function checks if the directory given by `path` exists.
66 
67  Arguments:
68  - `path`: Path to castor directory
69  """
70 
71  if path[-1] == "/":
72  path = path[:-1]
73  containingPath = os.path.join( *path.split("/")[:-1] )
74  dirInQuestion = path.split("/")[-1]
75  try:
76  rawLines = getCommandOutput2("rfdir /"+containingPath).splitlines()
77  except RuntimeError:
78  return False
79  for line in rawLines:
80  if line.split()[0][0] == "d":
81  if line.split()[8] == dirInQuestion:
82  return True
83  return False
84 
85 def replacelast(string, old, new, count = 1):
86  """Replace the last occurances of a string"""
87  return new.join(string.rsplit(old,count))
88 
89 fileExtensions = ["_cfg.py", ".sh", ".root"]
90 
91 def addIndex(filename, njobs, index = None):
92  if index is None:
93  return [addIndex(filename, njobs, i) for i in range(njobs)]
94  if njobs == 1:
95  return filename
96 
97  fileExtension = None
98  for extension in fileExtensions:
99  if filename.endswith(extension):
100  fileExtension = extension
101  if fileExtension is None:
102  raise AllInOneError(fileName + " does not end with any of the extensions "
103  + str(fileExtensions))
104  return replacelast(filename, fileExtension, "_" + str(index) + fileExtension)
105 
106 def parsecolor(color):
107  try: #simplest case: it's an int
108  return int(color)
109  except ValueError:
110  pass
111 
112  try: #kRed, kBlue, ...
113  color = str(getattr(ROOT, color))
114  return int(color)
115  except (AttributeError, ValueError):
116  pass
117 
118  if color.count("+") + color.count("-") == 1: #kRed+5, kGreen-2
119  if "+" in color: #don't want to deal with nonassociativity of -
120  split = color.split("+")
121  color1 = parsecolor(split[0])
122  color2 = parsecolor(split[1])
123  return color1 + color2
124 
125  if "-" in color:
126  split = color.split("-")
127  color1 = parsecolor(split[0])
128  color2 = parsecolor(split[1])
129  return color1 - color2
130 
131  raise AllInOneError("color has to be an integer, a ROOT constant (kRed, kBlue, ...), or a two-term sum or difference (kGreen-5)!")
132 
133 def parsestyle(style):
134  try: #simplest case: it's an int
135  return int(style)
136  except ValueError:
137  pass
138 
139  try: #kStar, kDot, ...
140  style = str(getattr(ROOT,style))
141  return int(style)
142  except (AttributeError, ValueError):
143  pass
144 
145  raise AllInOneError("style has to be an integer or a ROOT constant (kDashed, kStar, ...)!")
146 
148  result = [cls]
149  for subcls in cls.__subclasses__():
150  result += recursivesubclasses(subcls)
151  return result
152 
153 def cache(function):
154  cache = {}
155  def newfunction(*args, **kwargs):
156  try:
157  return cache[args, tuple(sorted(six.iteritems(kwargs)))]
158  except TypeError:
159  print(args, tuple(sorted(six.iteritems(kwargs))))
160  raise
161  except KeyError:
162  cache[args, tuple(sorted(six.iteritems(kwargs)))] = function(*args, **kwargs)
163  return newfunction(*args, **kwargs)
164  newfunction.__name__ = function.__name__
165  return newfunction
166 
167 def boolfromstring(string, name):
168  """
169  Takes a string from the configuration file
170  and makes it into a bool
171  """
172  #try as a string, not case sensitive
173  if string.lower() == "true": return True
174  if string.lower() == "false": return False
175  #try as a number
176  try:
177  return str(bool(int(string)))
178  except ValueError:
179  pass
180  #out of options
181  raise ValueError("{} has to be true or false!".format(name))
182 
183 
184 def pythonboolstring(string, name):
185  """
186  Takes a string from the configuration file
187  and makes it into a bool string for a python template
188  """
189  return str(boolfromstring(string, name))
190 
191 def cppboolstring(string, name):
192  """
193  Takes a string from the configuration file
194  and makes it into a bool string for a C++ template
195  """
196  return pythonboolstring(string, name).lower()
197 
198 conddbcode = None
199 def conddb(*args):
200  """
201  Wrapper for conddb, so that you can run
202  conddb("--db", "myfile.db", "listTags"),
203  like from the command line, without explicitly
204  dealing with all the functions in CondCore/Utilities.
205  getcommandoutput2(conddb ...) doesn't work, it imports
206  the wrong sqlalchemy in CondCore/Utilities/python/conddblib.py
207  """
208  global conddbcode
209  from tempfile import mkdtemp, NamedTemporaryFile
210 
211  if conddbcode is None:
212  conddbfile = getCommandOutput2("which conddb").strip()
213  tmpdir = mkdtemp()
214  getCommandOutput2("2to3 -f print -o " + tmpdir + " -n -w " + conddbfile)
215 
216  with open(os.path.join(tmpdir, "conddb")) as f:
217  conddb = f.read()
218 
219  conddbcode = conddb.replace("sys.exit", "sysexit")
220 
221  def sysexit(number):
222  if number != 0:
223  raise AllInOneError("conddb exited with status {}".format(number))
224  namespace = {"sysexit": sysexit, "conddboutput": ""}
225 
226  bkpargv = sys.argv
227  sys.argv[1:] = args
228  bkpstdout = sys.stdout
229  try:
230  with NamedTemporaryFile(bufsize=0) as sys.stdout:
231  exec(conddbcode, namespace)
232  namespace["main"]()
233  with open(sys.stdout.name) as f:
234  result = f.read()
235  finally:
236  sys.argv[:] = bkpargv
237  sys.stdout = bkpstdout
238 
239  return result
240 
241 
242 def clean_name(s):
243  """Transforms a string into a valid variable or method name.
244 
245  Arguments:
246  - `s`: input string
247  """
248 
249  # Remove invalid characters
250  s = re.sub(r"[^0-9a-zA-Z_]", "", s)
251 
252  # Remove leading characters until we find a letter or underscore
253  s = re.sub(r"^[^a-zA-Z_]+", "", s)
254 
255  return s
Definition: vlib.h:256
def parsestyle(style)
def pythonboolstring(string, name)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
def getCommandOutput2(command)
def cppboolstring(string, name)
def addIndex(filename, njobs, index=None)
def replacelast(string, old, new, count=1)
def cache(function)
def replaceByMap(target, the_map)
— Helpers —############################
def boolfromstring(string, name)
def parsecolor(color)
def castorDirExists(path)
def recursivesubclasses(cls)
#define str(s)