Page MenuHomeHEPForge

rivet
No OneTemporary

#! /usr/bin/env python
import sys, os, time
import logging, signal
from optparse import OptionParser, OptionGroup
## Make "sorted" a builtin function on Python < 2.4
if 'sorted' not in dir(__builtins__):
def sorted(iterable, cmp=None, key=None, reverse=None):
rtn = iterable
rtn.sort(cmp)
return rtn
## Add logging.log if needed
if 'log' not in dir(logging):
def _logit(level, msg):
l = logging.getLogger()
l.log(level, msg)
logging.log = _logit
## Change dlopen status to GLOBAL for Rivet lib
try:
import ctypes
sys.setdlopenflags(sys.getdlopenflags() | ctypes.RTLD_GLOBAL)
except:
import dl
sys.setdlopenflags(sys.getdlopenflags() | dl.RTLD_GLOBAL)
## Try to rename the process on Linux
try:
import ctypes
libc = ctypes.cdll.LoadLibrary('libc.so.6')
libc.prctl(15, 'rivet', 0, 0, 0)
except Exception:
pass
## Try to use Psyco optimiser
try:
import psyco
psyco.full()
except ImportError:
pass
## Get version from rivet-config
version = "HEAD"
try:
version = commands.getoutput("rivet-config --version")
except:
pass
## Description / usage message
usage="""Run Rivet analyses on inputted events from file or Unix pipe
Examples:
%prog [options] <hepmcfile>
my_generator -o myfifo & \ %prog [options] myfifo
agile-runmc <genname> -n 100k | %prog [options]
ENVIRONMENT:
* RIVET_ANALYSIS_PATH: list of paths to be searched for plugin
analysis libraries at runtime
* RIVET_REF_PATH: list of paths to be searched for reference
data files
* RIVET_INFO_PATH: list of paths to be searched for analysis
metadata files
"""
PROGPATH = sys.argv[0]
PROGNAME = os.path.basename(PROGPATH)
## Try to bootstrap the Python path
import commands
try:
modname = sys.modules[__name__].__file__
binpath = os.path.dirname(modname)
rivetconfigpath = os.path.join(binpath, "rivet-config")
rivetpypath = commands.getoutput(rivetconfigpath + " --pythonpath")
sys.path.append(rivetpypath)
except:
pass
## Parse command line options
parser = OptionParser(usage=usage, version="rivet v%s" % version)
parser.add_option("-n", "--nevts", dest="MAXEVTNUM", type="int",
default=None, metavar="NUM",
help="max number of events to read.")
parser.add_option("-a", "--analysis", dest="ANALYSES", action="append",
default=[], metavar="ANA",
help="add an analysis to the processing list.")
parser.add_option("-A", "--all-analyses", dest="ALL_ANALYSES", action="store_true",
default=False, help="add all analyses to the processing list.")
parser.add_option("--list-analyses", dest="LIST_ANALYSES", action="store_true",
default=False, help="show the list of available analyses' names. With -V, it shows the descriptions, too")
parser.add_option("--list-used-analyses", action="store_true", dest="LIST_USED_ANALYSES",
default=False, help="list the analyses used by this command (after subtraction of inappropriate ones)")
parser.add_option("--show-analysis", dest="SHOW_ANALYSES", action="append",
default=[], help="show the details of an analysis")
parser.add_option("--runname", dest="RUN_NAME", default=None, metavar="NAME",
help="give an optional run name, to be prepended as a 'top level directory' in histo paths")
parser.add_option("-H", "--histo-file", dest="HISTOFILE",
default="Rivet", help="specify the output histo file path")
parser.add_option("-x", "--cross-section", dest="CROSS_SECTION",
default=None, metavar="XS",
help="specify the signal process cross-section in pb")
verbgroup = OptionGroup(parser, "Verbosity control")
parser.add_option("-l", dest="NATIVE_LOG_STRS", action="append",
default=[], help="set a log level in the Rivet library")
verbgroup.add_option("-V", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-Q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
opts, args = parser.parse_args()
## Configure logging
try:
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
except:
pass
h = logging.StreamHandler()
h.setFormatter(logging.Formatter("%(message)s"))
logging.getLogger().setLevel(opts.LOGLEVEL)
if logging.getLogger().handlers:
logging.getLogger().handlers[0] = h
else:
logging.getLogger().addHandler(h)
## Try importing rivet
try:
import rivet
except Exception, e:
sys.stderr.write(PROGNAME + " requires the 'rivet' Python module\n");
logging.debug(str(e))
sys.exit(1)
## Control native Rivet library logger
for l in opts.NATIVE_LOG_STRS:
name, level = None, None
try:
name, level = l.split("=")
except:
name = "Rivet"
level = l
## Fix name
if name != "Rivet" and not name.startswith("Rivet."):
name = "Rivet." + name
try:
## Get right error type
LEVEL = level.upper()
if LEVEL == "TRACE":
level = rivet.Log.TRACE
elif LEVEL == "DEBUG":
level = rivet.Log.DEBUG
elif LEVEL == "INFO":
level = rivet.Log.INFO
elif LEVEL == "WARNING" or LEVEL == "WARN":
level = rivet.Log.WARN
elif LEVEL == "ERROR":
level = rivet.Log.ERROR
else:
level = int(level)
logging.debug("Setting log level: %s %d" % (name, level))
rivet.Log.setLogLevel(name, level)
except:
logging.warning("Couldn't process logging string '%s'" % l)
## Parse supplied cross-section
if opts.CROSS_SECTION is not None:
xsstr = opts.CROSS_SECTION
try:
opts.CROSS_SECTION = float(xsstr)
except:
import re
suffmatch = re.search(r"[^\d.]", xsstr)
if not suffmatch:
raise ValueError("Bad cross-section string: %s" % xsstr)
factor = base = None
suffstart = suffmatch.start()
if suffstart != -1:
base = xsstr[:suffstart]
suffix = xsstr[suffstart:].lower()
if suffix == "mb":
factor = 1e+9
elif suffix == "mub":
factor = 1e+6
elif suffix == "nb":
factor = 1e+3
elif suffix == "pb":
factor = 1
elif suffix == "fb":
factor = 1e-3
elif suffix == "ab":
factor = 1e-6
if factor is None or base is None:
raise ValueError("Bad cross-section string: %s" % xsstr)
xs = float(base) * factor
opts.CROSS_SECTION = xs
## Print the available CLI options!
#if opts.LIST_OPTIONS:
# for o in parser.option_list:
# print o.get_opt_string()
# sys.exit(0)
## Set up signal handling
RECVD_KILL_SIGNAL = None
def handleKillSignal(signum, frame):
"Declare us as having been signalled, and return to default handling behaviour"
global RECVD_KILL_SIGNAL
logging.critical("Signal handler called with signal " + str(signum))
RECVD_KILL_SIGNAL = signum
signal.signal(signum, signal.SIG_DFL)
## Signals to handle
signal.signal(signal.SIGTERM, handleKillSignal);
signal.signal(signal.SIGHUP, handleKillSignal);
signal.signal(signal.SIGINT, handleKillSignal);
signal.signal(signal.SIGUSR1, handleKillSignal);
signal.signal(signal.SIGUSR2, handleKillSignal);
try:
signal.signal(signal.SIGXCPU, handleKillSignal);
except:
pass
## List of analyses
all_analyses = rivet.AnalysisLoader.analysisNames()
if opts.LIST_ANALYSES:
## Treat args as case-insensitive regexes if present
regexes = None
if args:
import re
regexes = [re.compile(arg, re.I) for arg in args]
for aname in all_analyses:
if not regexes:
toshow = True
else:
toshow = False
for regex in regexes:
if regex.search(aname):
toshow = True
break
if toshow:
msg = aname
if opts.LOGLEVEL == logging.DEBUG:
a = rivet.AnalysisLoader.getAnalysis(aname)
msg = "%-25s %s" % (aname, " " + a.summary())
print msg
sys.exit(0)
## Show analyses' details
if len(opts.SHOW_ANALYSES) > 0:
toshow = []
for i, a in enumerate(opts.SHOW_ANALYSES):
a_up = a.upper()
if a_up in all_analyses and a_up not in toshow:
toshow.append(a_up)
else:
## Treat as a case-insensitive regex
import re
regex = re.compile(a, re.I)
for ana in all_analyses:
if regex.search(ana) and a_up not in toshow:
toshow.append(ana)
## Show the matching analyses' details
import textwrap
for i, name in enumerate(sorted(toshow)):
ana = rivet.AnalysisLoader.getAnalysis(name)
print ""
print name
print len(name) * "="
print ""
print ana.summary()
print ""
print "Status: %s" % ana.status()
print ""
print "Spires ID: %s" % ana.spiresId()
print "Spires URL: http://www.slac.stanford.edu/spires/find/hep/www?rawcmd=key+%s" % ana.spiresId()
print "HepData URL: http://hepdata.cedar.ac.uk/view/irn%s" % ana.spiresId()
print "Experiment: %s" % ana.experiment(), ana.collider()
print "Year of publication: %s" % ana.year()
print "Authors:"
for a in ana.authors():
print " " + a
print ""
print "Description:"
twrap = textwrap.TextWrapper(width=75, initial_indent=2*" ", subsequent_indent=2*" ")
print twrap.fill(ana.description())
print ""
print "Run details:"
twrap = textwrap.TextWrapper(width=75, initial_indent=2*" ", subsequent_indent=4*" ")
for l in ana.runInfo().split("\n"):
print twrap.fill(l)
if ana.references():
print ""
print "References:"
for r in ana.references():
url = None
if r.startswith("arXiv:"):
code = r.split()[0].replace("arXiv:", "")
url = "http://arxiv.org/abs/" + code
elif r.startswith("doi:"):
code = r.replace("doi:", "")
url = "http://dx.doi.org/" + code
if url is not None:
r += " - " + url
print " %s" % r
if i+1 < len(toshow):
print "\n"
sys.exit(0)
## Identify HepMC files/streams
## TODO: check readability, deal with stdin
if len(args) > 0:
HEPMCFILES = args
else:
HEPMCFILES = ["-"]
## Event number logging
def logNEvt(n, starttime, maxevtnum):
nevtloglevel = logging.DEBUG
if n % 10 == 0:
nevtloglevel = logging.DEBUG + 5
if n % 100 == 0:
nevtloglevel = logging.INFO
if n % 200 == 0:
nevtloglevel = logging.INFO + 5
if n % 500 == 0:
nevtloglevel = logging.WARNING
if n % 1000 == 0:
nevtloglevel = logging.WARNING + 5
if n % 10000 == 0:
nevtloglevel = logging.CRITICAL
timecurrent = time.time()
timeelapsed = timecurrent - starttime;
if maxevtnum is None:
logging.log(nevtloglevel, "Event %d (%d s elapsed)" % (n, timeelapsed))
else:
timeleft = (maxevtnum-n)*timeelapsed/n
eta = time.strftime("%a %b %d %H:%M", time.localtime(timecurrent + timeleft))
logging.log(nevtloglevel, "Event %d (%d s elapsed / %d s left) -> ETA: %s"
% (n, timeelapsed, timeleft, eta))
## Set up analysis handler
RUNNAME = opts.RUN_NAME or ""
ah = rivet.AnalysisHandler(opts.HISTOFILE, RUNNAME)
if opts.ALL_ANALYSES:
opts.ANALYSES = all_analyses
for a in opts.ANALYSES:
a_up = a.upper()
## Print warning message and exit if not a valid analysis name
if not a_up in all_analyses:
print "'%s' is not a valid analysis. Available analyses are:" % a_up
for aa in all_analyses:
print " %s" % aa
sys.exit(1)
logging.debug("Adding analysis '%s'" % a_up)
ah.addAnalysis(a_up)
## Read and process events
run = rivet.Run(ah)
if opts.CROSS_SECTION is not None:
logging.info("User-supplied cross-section = %e pb" % opts.CROSS_SECTION)
run.setCrossSection(opts.CROSS_SECTION)
if opts.LIST_USED_ANALYSES is not None:
run.setListAnalyses(opts.LIST_USED_ANALYSES)
## Print platform type
import platform
logging.info("Rivet running on machine %s (%s)" % (platform.node(), platform.machine()))
## Init run based on one event
evtfile = HEPMCFILES[0]
if not run.init(evtfile):
logging.error("Failed to initialise on event file %s" % evtfile)
sys.exit(2)
## Event loop
starttime = time.time()
EVTNUM = 0
for fileidx in range(len(HEPMCFILES)):
logging.info("Reading events from '%s'" % HEPMCFILES[fileidx])
while opts.MAXEVTNUM is None or EVTNUM < opts.MAXEVTNUM:
EVTNUM += 1
logNEvt(EVTNUM, starttime, opts.MAXEVTNUM)
if not run.processEvent():
logging.warn("Event processing failed for evt #%i!" % (EVTNUM))
break
if RECVD_KILL_SIGNAL is not None:
break
if not run.readEvent():
break
if fileidx<len(HEPMCFILES)-1:
run.openFile(HEPMCFILES[fileidx+1])
if not run.readEvent():
continue
logging.info("Finished event loop")
run.finalize()
## Finalize and write out data file
ah.finalize()
ah.commitData();

File Metadata

Mime Type
text/x-python
Expires
Sat, Dec 21, 3:12 PM (1 d, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023246
Default Alt Text
rivet (13 KB)

Event Timeline