ATLAS Offline Software
Loading...
Searching...
No Matches
athena.py
Go to the documentation of this file.
1#!/bin/sh
2# Emacs, this is mostly -*-Python-*-
3#
4# Copyright (C) 2002-2026 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
11export USETCMALLOC=0
12export USEIMF=0
13export USEEXCTRACE=0
14export USEEXCABORT=1
15otherargs=()
16# but use tcmalloc by default if TCMALLOCDIR is defined
17if [ -n "$TCMALLOCDIR" ]; then
18 export USETCMALLOC=1
19fi
20
21# parse LD_PRELOAD related command line arguments
22for a in "$@"
23do
24 case "$a" in
25 --stdcmalloc) USETCMALLOC=0;;
26 --tcmalloc) USETCMALLOC=1;;
27 --stdcmath) USEIMF=0;;
28 --imf) USEIMF=1;;
29 --exctrace) USEEXCTRACE=1;;
30 --no-excabort) USEEXCABORT=0;;
31 --preloadlib*) export ATHENA_ADD_PRELOAD=${a#*=};;
32 --drop-and-reload) ATHENA_DROP_RELOAD=1;;
33 *) otherargs+=("$a");;
34 esac
35done
36
37
38# Do the actual preloading via LD_PRELOAD and save the original value
39export LD_PRELOAD_ORIG=${LD_PRELOAD}
40source `which athena_preload.sh `
41
42# Now resurrect ourselves as python script
43python_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
81import sys, os
82
83
84import AthenaCommon.AthOptionsParser as aop
85aop.enable_athenaCLI()
86opts = aop.parse(legacy_args=True)
87
88
89from PyUtils.Helpers import ROOTSetup
90ROOTSetup(batch = not opts.interactive)
91
92
93if opts.scripts:
94 from AthenaCommon.Utils.unixtools import FindFile
95 path_list = ['./'] + os.environ.get('PYTHONPATH', '').split(os.pathsep)
96 file_path = FindFile( os.path.expanduser( os.path.expandvars(opts.scripts[0]) ),
97 path_list, os.R_OK )
98
99 if file_path is not None:
100 with open(file_path) as f:
101 if f.readline().startswith('#!'): # shebang means CA mode
102 opts.CA = True
103
104 if opts.CA:
105 sys.argv.remove(opts.scripts[0]) # drop script path from args
106 opts.scripts[0] = file_path # replace with resolved path
107
108elif opts.fromdb:
109 import pickle
110 with open(opts.fromdb, 'rb') as f:
111 try:
112 acc = pickle.load(f)
113 opts.CA = not isinstance(acc, dict) # legacy pkl is a dict
114 if not opts.CA:
115 del acc # legacy pkl is loaded in Execution.py
116 except ModuleNotFoundError:
117 pass # in case ComponentAccumulator class is not available in release
118
119
120if 'LD_PRELOAD_ORIG' in os.environ:
121 os.environ['LD_PRELOAD'] = os.getenv('LD_PRELOAD_ORIG')
122 os.unsetenv('LD_PRELOAD_ORIG')
123
124
125from AthenaCommon.Debugging import DbgStage
126DbgStage.value = opts.debug
127
128
129if not os.getcwd() in sys.path:
130 sys.path = [ os.getcwd() ] + sys.path
131
132if '' not in sys.path:
133 sys.path = [ '' ] + sys.path
134
135
136
137sys.ps1 = 'athena> '
138sys.ps2 = '. ... '
139
140try:
141 import ctypes
142 from ctypes.util import find_library as ctypes_find_library
143 libc = ctypes.cdll.LoadLibrary( ctypes_find_library('c') )
144 libc.prctl( 15, b'athena.py', 0, 0, 0 )
145except Exception:
146 pass # don't worry about it failing ...
147
148
149
150if not (opts.interactive or opts.debug):
151 # in batch there is no need for stdin
152 if sys.stdin and os.isatty( sys.stdin.fileno() ):
153 os.close( sys.stdin.fileno() )
154else:
155 # Make sure ROOT gets initialized early, so that it shuts down last.
156 # Otherwise, ROOT can get shut down before Gaudi, leading to crashes
157 # when Athena components dereference ROOT objects that have been deleted.
158 import ROOT # noqa: F401
159
160
161if opts.CA:
162 from AthenaCommon import ExitCodes
163 exitcode = 0
164 try:
165 if opts.scripts: # CA script
166 if not opts.tracelevel:
167 import runpy
168 runpy.run_path( opts.scripts[0], run_name='__main__' )
169 else:
170 from AthenaCommon.Debugging import traceExecution
171 traceExecution( opts.scripts[0], opts.tracelevel )
172
173 elif opts.fromdb: # pickle
174 from AthenaCommon.AthOptionsParser import configureCAfromArgs
175 configureCAfromArgs( acc, opts )
176 sys.exit(acc.run(opts.evtMax).isFailure())
177
178 except SystemExit as e:
179 # Failure in ComponentAccumulator.run() is very likely an algorithm error
180 exitcode = ExitCodes.EXE_ALG_FAILURE if e.code==1 else e.code
181
182 from AthenaCommon import Logging
183 Logging.log.info( 'leaving with code %d: "%s"',
184 exitcode, ExitCodes.what(exitcode) )
185 sys.exit( exitcode )
186
187
188else:
189 # logging and messages
190 from AthenaCommon.Logging import logging, log
191 _msg = log
192
193 # test and set log level
194 try:
195 _msg.setLevel (getattr(logging, opts.loglevel))
196 except Exception:
197 aop._help_and_exit()
198
199 # start profiler, if requested
200 if opts.profile_python:
201 import cProfile
202 # profiler is created and controlled programmatically b/c a CLI profiling of
203 # athena.py doesn't work (globals are lost from include() execfile() calls),
204 # and because this allows easy excluding of the (all C++) Gaudi run
205 cProfile._athena_python_profiler = cProfile.Profile()
206 cProfile._athena_python_profiler.enable()
207
208 # Fill athena job properties
209 aop.fill_athenaCommonFlags(opts)
210
211 # file inclusion and tracing
212 from AthenaCommon.Include import include
213 include.setShowIncludes(opts.showincludes)
214
215 # pre-execution step
216 include( "AthenaCommon/Preparation.py" )
217
218 # execution of user script and drop into batch or interactive mode ---------
219 include( "AthenaCommon/Execution.py" )
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179