ATLAS Offline Software
general.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 """
4 Utility module for things not specific to DQ
5 """
6 
7 from __future__ import with_statement
8 
9 from contextlib import contextmanager
10 from logging import getLogger; log = getLogger("DQUtils.general")
11 
12 from time import time, mktime, strptime, strftime, gmtime
13 from six.moves import getoutput
14 
15 def get_package_version(package_name, default_prefix="DataQuality"):
16  """
17  Returns package version as determined from "cmt show versions"
18  """
19  if "/" not in package_name and default_prefix:
20  package_name = "/".join([default_prefix, package_name])
21  output = getoutput("cmt show versions %s" % package_name).split("\n")
22  output = list(map(str.strip, output))
23  return " ".join(output[0].split()[1:])
24 
25 @contextmanager
26 def kgrind_profile(filename="profile.kgrind"):
27  """
28  Generate kcachegrind profile information for a call.
29 
30  Example use:
31 
32  with kgrind_profile() as p:
33  p.run("main()")
34  """
35  from cProfile import Profile
36  p = Profile()
37  try:
38  yield p
39  finally:
40  from .ext.lsprofcalltree import KCacheGrind
41  with open(filename,"w") as fd:
42  KCacheGrind(p).output(fd)
43 
44 def daemonize(function, delay, error_args=None, **kwargs):
45  """
46  Run a daemon which executes `function` every `delay` seconds.
47  """
48  from time import sleep
49  try:
50  while True:
51  log.info("Sleeping for %i seconds..", delay)
52  sleep(delay)
53 
54  log.info("Current time: %s", strftime("%d/%m/%Y %H:%M:%S"))
55 
56  function(**kwargs)
57  except Exception:
58  if error_args is not None:
59  import sys
60  send_error_email(sys.exc_info(), **error_args)
61  raise
62 
63 def send_error_email(exception_info, from_, subject, body):
64  """
65  Send an error email containing `exception_info`
66  TODO: Doesn't contain complete information
67  """
68  import smtplib
69  import traceback
70 
71  from email.mime.text import MIMEText
72  from getpass import getuser
73  from socket import gethostname
74 
75  exceptionType, exceptionValue, exceptionTraceback = exception_info
76 
77  user, host = getuser(), gethostname()
78 
79  extra_info = ["Was running as user '%s' on machine '%s'" % (user, host),
80  #"Code located at: %s" % code
81  ]
82 
83  msg = MIMEText("\n\n".join(body + extra_info +
84  traceback.format_tb(exceptionTraceback)))
85 
86  msg['Subject'] = subject
87  msg['From'] = from_
88 
89  to = [
90  #"Peter Waller <peter.waller@cern.ch>",
91  "Peter Onyisi <peter.onyisi@cern.ch>"
92  ]
93 
94  #operations = ("Data Quality Operations "
95  # "<hn-atlas-data-quality-operations@cern.ch>")
96 
97  msg['To'] = ", ".join(to)
98  #msg['Cc'] = operations; to.append(operations)
99 
100  s = smtplib.SMTP()
101  s.connect()
102  s.sendmail(from_, to, msg.as_string())
103  s.quit()
104 
105  log.error("Error email sent.")
106 
107 def all_equal(*inputs):
108  """
109  Returns true if all input arguments are equal (must be hashable)
110  """
111  return len(set(inputs)) == 1
112 
113 def all_permutations(input_list):
114  """
115  Generate all permutations of `input_list`
116  """
117  if len(input_list) <= 1:
118  yield input_list
119  else:
120  for perm in all_permutations(input_list[1:]):
121  for i in range(len(perm)+1):
122  yield perm[:i] + input_list[0:1] + perm[i:]
123 
124 # Taken from:
125 # http://caolanmcmahon.com/flatten_for_python
126 def flattened(l):
127  result = _flatten(l, lambda x: x)
128  while type(result) is list and len(result) and callable(result[0]):
129  if result[1] != []:
130  yield result[1]
131  result = result[0]([])
132  yield result
133 
134 def _flatten(l, fn, val=[]):
135  if type(l) is not list:
136  return fn(l)
137  if len(l) == 0:
138  return fn(val)
139  return [lambda x: _flatten(l[0], lambda y: _flatten(l[1:],fn,y), x), val]
140 
141 @contextmanager
142 def silence(log_level=None, logger=None):
143  """
144  Turn down the logging verbosity temporarily
145  """
146  if log_level is None:
147  log_level = log.WARNING
148 
149  if logger is None:
150  logger = log.getLogger()
151 
152  orig_level = logger.level
153  logger.setLevel(log_level)
154 
155  try:
156  yield
157  finally:
158  logger.setLevel(orig_level)
159 
160 @contextmanager
161 def timer(name):
162  "A context manager which spits out how long the block took to execute"
163  start = time()
164  try:
165  yield
166  finally:
167  end = time()
168  log.debug("Took %.2f to %s", end - start, name)
169 
170 def interleave(*args):
171  return [item for items in zip(*args) for item in items]
172 
173 def date_to_nanounix(date_string):
174  """
175  Returns number of nanoseconds between unix epoch and date in the form
176  'dd/mm/yyyy'
177  """
178  return int(mktime(strptime(date_string, "%d/%m/%Y")) * 1e9)
179 
180 def nanounix_to_date(nanounix):
181  """
182  Returns a string representation of `nanounix` nanoseconds
183  since the unix epoch
184  """
185  sub_second = "%03i" % ((nanounix % int(1e9)) / 1e6)
186  try:
187  return strftime("%Y%m%d:%H%M%S.", gmtime(nanounix / 1e9)) + sub_second
188  except ValueError:
189  return "[BadTime: %s]" % int(nanounix)
190 
dso-stats.getoutput
def getoutput(cmd)
Definition: dso-stats.py:22
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.general.get_package_version
def get_package_version(package_name, default_prefix="DataQuality")
Definition: general.py:15
python.general.all_equal
def all_equal(*inputs)
Definition: general.py:107
python.general.kgrind_profile
def kgrind_profile(filename="profile.kgrind")
Definition: general.py:26
python.general.timer
def timer(name)
Definition: general.py:161
python.general._flatten
def _flatten(l, fn, val=[])
Definition: general.py:134
python.getCurrentFolderTag.fn
fn
Definition: getCurrentFolderTag.py:65
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.general.interleave
def interleave(*args)
Definition: general.py:170
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.general.silence
def silence(log_level=None, logger=None)
Definition: general.py:142
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
merge.output
output
Definition: merge.py:17
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.general.daemonize
def daemonize(function, delay, error_args=None, **kwargs)
Definition: general.py:44
python.general.nanounix_to_date
def nanounix_to_date(nanounix)
Definition: general.py:180
python.general.date_to_nanounix
def date_to_nanounix(date_string)
Definition: general.py:173
python.general.all_permutations
def all_permutations(input_list)
Definition: general.py:113
Trk::open
@ open
Definition: BinningType.h:40
python.general.flattened
def flattened(l)
Definition: general.py:126
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.CaloCondLogger.getLogger
def getLogger(name="CaloCond")
Definition: CaloCondLogger.py:16
python.general.send_error_email
def send_error_email(exception_info, from_, subject, body)
Definition: general.py:63