""" Handle the parsing and aggregation of simulation results
Classes:
:py:class:`StatsParser`
main statistics parsing class
"""
import cPickle
import os
import sys
from simulations.base import Base
from simulations.base import withoptions
@withoptions
[docs]class StatsParser(Base):
""" Base class for parsing result files.
Keyword Parameters:
option_error_handler
An error handler for the :py:class:`~simulations.utils.optionparser.OptionParser`
option_exit_handler
An exit handler for the :py:class:`~simulations.utils.optionparser.OptionParser`
Public Methods:
:py:meth:`~StatsParser.go`
Kick off parsing the results
Methods to Implement:
:py:meth:`~simulations.base.Base._add_listeners`
Add listeners for various parsing events
Events:
done(this, out)
emitted when results are totally done
go(this)
emitted when the :py:meth:`~StatsRunner.go` method is called
oparser set up(this)
emitted after the :py:class:`~simulations.utils.optionparser.OptionParser`
is set up and able to add options
options parsed(this)
emitted after the :py:class:`~simulations.utils.optionparser.OptionParser`
has parsed arguments
result(this, out, duplication, result)
emitted when a result is ready to be interpreted
result options(this, out, options)
emitted when the simulation runner options are ready to be interpreted
"""
def __init__(self, *args, **kwdargs):
""" Sets up the parsing aparatus
Keyword Parameters:
option_error_handler
An error handler for the :py:class:`~simulations.utils.optionparser.OptionParser`
option_exit_handler
An exit handler for the :py:class:`~simulations.utils.optionparser.OptionParser`
"""
super(StatsParser, self).__init__(*args, **kwdargs)
[docs] def go(self, **kwdargs):
""" Pass off the parsing of the results file after some data manipulation
Keyword Parameters:
option_args
arguments to pass to the :py:class:`~simulations.utils.optionparser.OptionParser`.
Defaults to sys.argv[1:].
option_values
target of option parsing (probably should not use)
"""
self.emit('go', self)
if 'option_args' in kwdargs:
option_args = kwdargs['option_args']
else:
option_args = None
if 'option_values' in kwdargs:
option_values = kwdargs['option_values']
else:
option_values = None
(self.options, self.args) = self.oparser.parse_args(args=option_args, values=option_values)
self._check_base_options()
self.emit('options parsed', self)
with open(self.options.stats_file, "rb") as statsfile:
if self.options.out_file:
if self.options.verbose:
print "Sending output to {0}...".format(self.options.out_file)
with open(self.options.out_file, "w") as out:
self._go(statsfile, out)
self.emit('done', self, out)
else:
if self.options.verbose:
print "Sending output to stdout..."
self._go(statsfile, sys.stdout)
self.emit('done', self, sys.stdout)
[docs] def _go(self, statsfile, out):
""" Actually parses the data
Parameters:
statsfile
a file object for the file to parse
out
the output target (either a file object or sys.stdout)
"""
count = -1
pickle = ""
if self.options.verbose:
print "Beginning processing of stats file..."
for line in statsfile:
if line == "\n":
if self.options.verbose:
print "Entry boundary encountered."
count += 1
if count == 0:
if self.options.verbose:
print "Emitting 'result options'."
self.emit('result options',
self,
out,
cPickle.loads(pickle)
)
else:
if self.options.verbose:
print "Emitting 'result'."
self.emit('result',
self,
out,
count,
cPickle.loads(pickle))
pickle = ""
if self.options.verbose:
print "Prepared for next entry."
else:
pickle += line
if count < 1:
raise ValueError("Stats file contained no duplication results")
elif self.options.verbose:
resstr = "Processing done. Entries for {0} duplications found."
print resstr.format(count)
[docs] def _set_base_options(self):
""" Set up the basic :py:class:`~simulations.utils.optionparser.OptionParser` options
Options:
-F FILE, --statsfile=FILE File name of the results file
-O FILE, --outfile=FILE File to which to print data
-V, --verbose Print detailed output to stdout as things are processed
"""
self.oparser.add_option("-F", "--statsfile", action="store",
dest="stats_file",
default="./output/aggregate",
help="file holding aggregate stats")
self.oparser.add_option("-O", "--outfile", action="store",
dest="out_file", default=None,
help="file to which to print data")
self.oparser.add_option("-V", "--verbose", action="store_true",
dest="verbose", default=False,
help="detailed output?")
[docs] def _check_base_options(self):
""" Verify the values passed to the base options
Checks:
- Stats file exists
"""
file_exists = os.path.isfile(self.options.stats_file)
if not self.options.stats_file or not file_exists:
self.oparser.error("The stats file specified does not exist")