ATLAS Offline Software
athena.py
Go to the documentation of this file.
1 #!/bin/sh
2 # Emacs, this is mostly -*-Python-*-
3 #
4 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 #
6 # athena.py is born as shell script to preload some optional libraries.
7 #
8 """date"
9 
10 # defaults
11 export USETCMALLOC=0
12 export USEIMF=0
13 export USEEXCTRACE=0
14 otherargs=()
15 # but use tcmalloc by default if TCMALLOCDIR is defined
16 if [ -n "$TCMALLOCDIR" ]; then
17  export USETCMALLOC=1
18 fi
19 
20 # parse LD_PRELOAD related command line arguments
21 for a in "$@"
22 do
23  case "$a" in
24  --leak-check*) USETCMALLOC=0;;
25  --delete-check*) USETCMALLOC=0;;
26  --stdcmalloc) USETCMALLOC=0;;
27  --tcmalloc) USETCMALLOC=1;;
28  --stdcmath) USEIMF=0;;
29  --imf) USEIMF=1;;
30  --exctrace) USEEXCTRACE=1;;
31  --preloadlib*) export ATHENA_ADD_PRELOAD=${a#*=};;
32  --drop-and-reload) ATHENA_DROP_RELOAD=1;;
33  *) otherargs+=("$a");;
34  esac
35 done
36 
37 
38 # Do the actual preloading via LD_PRELOAD and save the original value
39 export LD_PRELOAD_ORIG=${LD_PRELOAD}
40 source `which athena_preload.sh `
41 
42 # Now resurrect ourselves as python script
43 python_path=`which python`
44 "exec" "$python_path" "-tt" "$0" "$@";
45 
46 """
47 
48 # File: athena.py
49 # Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
50 # "
51 # This script allows you to run Athena from python.
52 #
53 # Debugging is supported with the '-d' option (hook debugger after running
54 # all user scripts, and just before calling initialize) and the --debug
55 # option (requires "conf", "init", or "exec" and will hook just before that
56 # stage). The hook will give you the gdb prompt, from where you can set
57 # break points, load additional shared libraries, or drop into interactive
58 # athena mode (if -i specified on the cli). Alternatively, you can start
59 # with gdb, like so:
60 #
61 # $ gdb python
62 # (gdb) run `which athena.py` [options] [<file1>.py [<file2>.py ...
63 #
64 # Usage of valgrind is supported, but it requires full paths and explicit
65 # arguments in its run, like so:
66 #
67 # $ valgrind `which python` `which athena.py` [options] [<file1>.py ...
68 #
69 # or, alternatively (valgrind 3.2.0 and up):
70 #
71 # $ valgrind --trace-children=yes `which athena.py` [options] [<file1>.py ...
72 #
73 # Note that any error messages/leaks that valgrind reports on python can be
74 # ignored, as valgrind is wrong (see the file Misc/README.valgrind in the
75 # python installation).
76 #
77 
78 __author__ = 'Wim Lavrijsen (WLavrijsen@lbl.gov)'
79 __doc__ = 'For details about athena.py, run "less `which athena.py`"'
80 
81 import sys, os
82 
83 
84 import AthenaCommon.AthOptionsParser as aop
85 aop.enable_athenaCLI()
86 opts = aop.parse(legacy_args=True)
87 
88 
89 if opts.scripts:
90  from AthenaCommon.Utils.unixtools import FindFile
91  path_list = ['./'] + os.environ.get('PYTHONPATH', '').split(os.pathsep)
92  file_path = FindFile( os.path.expanduser( os.path.expandvars(opts.scripts[0]) ),
93  path_list, os.R_OK )
94 
95  if file_path is not None:
96  with open(file_path) as f:
97  if f.readline().startswith('#!'): # shebang means CA mode
98  opts.CA = True
99 
100  if opts.CA:
101  sys.argv.remove(opts.scripts[0]) # drop script path from args
102  opts.scripts[0] = file_path # replace with resolved path
103 
104 elif opts.fromdb:
105  import pickle
106  with open(opts.fromdb, 'rb') as f:
107  try:
108  acc = pickle.load(f)
109  opts.CA = not isinstance(acc, dict) # legacy pkl is a dict
110  if not opts.CA:
111  del acc # legacy pkl is loaded in Execution.py
112  except ModuleNotFoundError:
113  pass # in case ComponentAccumulator class is not available in release
114 
115 
116 if 'LD_PRELOAD_ORIG' in os.environ:
117  os.environ['LD_PRELOAD'] = os.getenv('LD_PRELOAD_ORIG')
118  os.unsetenv('LD_PRELOAD_ORIG')
119 
120 
121 from AthenaCommon.Debugging import DbgStage
122 DbgStage.value = opts.debug
123 
124 
125 if not os.getcwd() in sys.path:
126  sys.path = [ os.getcwd() ] + sys.path
127 
128 if '' not in sys.path:
129  sys.path = [ '' ] + sys.path
130 
131 
132 
133 sys.ps1 = 'athena> '
134 sys.ps2 = '. ... '
135 
136 try:
137  import ctypes
138  from ctypes.util import find_library as ctypes_find_library
139  libc = ctypes.cdll.LoadLibrary( ctypes_find_library('c') )
140  libc.prctl( 15, b'athena.py', 0, 0, 0 )
141 except Exception:
142  pass # don't worry about it failing ...
143 
144 
145 
146 if not (opts.interactive or opts.debug):
147  # in batch there is no need for stdin
148  if sys.stdin and os.isatty( sys.stdin.fileno() ):
149  os.close( sys.stdin.fileno() )
150 else:
151  # Make sure ROOT gets initialized early, so that it shuts down last.
152  # Otherwise, ROOT can get shut down before Gaudi, leading to crashes
153  # when Athena components dereference ROOT objects that have been deleted.
154  import ROOT # noqa: F401
155 
156 
157 if opts.CA:
158  from AthenaCommon import ExitCodes
159  exitcode = 0
160  try:
161  if opts.scripts: # CA script
162  if not opts.tracelevel:
163  import runpy
164  runpy.run_path( opts.scripts[0], run_name='__main__' )
165  else:
166  from AthenaCommon.Debugging import traceExecution
167  traceExecution( opts.scripts[0], opts.tracelevel )
168 
169  elif opts.fromdb: # pickle
170  from AthenaCommon.AthOptionsParser import configureCAfromArgs
171  configureCAfromArgs( acc, opts )
172  sys.exit(acc.run(opts.evtMax).isFailure())
173 
174  except SystemExit as e:
175  # Failure in ComponentAccumulator.run() is very likely an algorithm error
176  exitcode = ExitCodes.EXE_ALG_FAILURE if e.code==1 else e.code
177 
178  # FIXME: change the print to log (requires ref updates)
179  #from AthenaCommon import Logging
180  #Logging.log.info( 'leaving with code %d: "%s"',
181  # e.code, ExitCodes.what(e.code) )
182  print( 'leaving with code %d: "%s"' % (exitcode, ExitCodes.what(exitcode)) )
183  sys.exit( exitcode )
184 
185 
186 else:
187  # logging and messages
188  from AthenaCommon.Logging import logging, log
189  _msg = log
190 
191  # test and set log level
192  try:
193  _msg.setLevel (getattr(logging, opts.loglevel))
194  except Exception:
195  aop._help_and_exit()
196 
197  # start profiler, if requested
198  if opts.profile_python:
199  import cProfile
200  # profiler is created and controlled programmatically b/c a CLI profiling of
201  # athena.py doesn't work (globals are lost from include() execfile() calls),
202  # and because this allows easy excluding of the (all C++) Gaudi run
203  cProfile._athena_python_profiler = cProfile.Profile()
204  cProfile._athena_python_profiler.enable()
205 
206  # Fill athena job properties
207  aop.fill_athenaCommonFlags(opts)
208 
209  # file inclusion and tracing
210  from AthenaCommon.Include import include
211  include.setShowIncludes(opts.showincludes)
212 
213  # pre-execution step
214  include( "AthenaCommon/Preparation.py" )
215 
216  # execution of user script and drop into batch or interactive mode ---------
217  include( "AthenaCommon/Execution.py" )
Logging
python.Debugging.traceExecution
def traceExecution(script, level)
Definition: Debugging.py:113
python.Utils.unixtools.FindFile
def FindFile(filename, pathlist, access)
helper -------------------------------------------------------------------—
Definition: unixtools.py:20
python.Include.include
include
Definition: Include.py:319
Trk::open
@ open
Definition: BinningType.h:40
python.AthOptionsParser.configureCAfromArgs
def configureCAfromArgs(acc, opts)
Definition: AthOptionsParser.py:119
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
Trk::split
@ split
Definition: LayerMaterialProperties.h:38