# This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
#
# MAUS is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MAUS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MAUS. If not, see .
"""
InputPyJSON inputs data as a json document into the MAUS framework
"""
import json
import gzip
import ErrorHandler
class InputPyJSON:
"""Reads JSON documents from files/sockets
This class inputs from a python file object that
is passed as the only argument 'arg_file' to the
constructor. This allows the class to input
from any Python file object:
- an uncompressed ASCII file where each line
represents an spill document. One can use
the command 'python -mjson.tool' to view the
spills in a more human-readable fashion. For
example 'cat filename | python -mjson.tool';
arg_file=open('filename', 'w')
- a gzip-compressed file that can be
decompressed either with InputPyJSON within
MAUS or by the Linux tools gunzip/gzip;
arg_file=GzipFile('filename', 'w');
see http://docs.python.org/library/gzip.html
- a socket;
http://docs.python.org/library/socket.html
- etc...
.
"""
def __init__(self, arg_file=None, arg_number_of_events=-1):
"""Setup InputPyJSON
\param arg_file python file object.
Default: open('mausput','r')
\param arg_number_of_events number of events to
read in. If -1, read forever or until
the end of the file.
Default: -1
"""
self._file = arg_file
self._number_of_events = arg_number_of_events
self._current_event = 0
def birth(self, config_document = "{}"):
"""
birth() opens the json file based on datacards
@param json_config json string holding a dict of json parameters
- input_json_file_name datacard controls file name to open
- input_json_file_type datacard controls file type (either 'text' or
'gzip'
@returns True on success, False on failure
If self._file is opens self._file file.
"""
try:
if self._file == None:
config = json.loads(config_document)
fname = config["input_json_file_name"]
if config["input_json_file_type"] == "gzip":
self._file = gzip.GzipFile(fname, 'r')
elif config["input_json_file_type"] == "text":
self._file = open(fname, 'r')
else:
raise IOError('Did not recognise input_json_file_type '+\
str(config["input_json_file_type"]))
return True
except Exception: #pylint: disable=W0703
ErrorHandler.HandleException({}, self)
return False
def emitter(self):
"""Emit JSON documents
This is a python generator that yields
JSON documents until the end of the file
or until the maximum number of events is hit.
"""
# this returns an empty string if
# there is nothing to read, hence
# while loop ahead
next_value = self._file.readline()
while next_value != '':
# remove \n and whitespace
next_value = next_value.rstrip()
# see if EOF is reached
if next_value == '':
return
# check that it's a valid JSON document
json.loads(next_value)
# have we gone past the number of events we wanted?
if self._number_of_events >= 0 and\
self._current_event >= self._number_of_events:
return
# yield the current event (google 'python generators' if confused)
yield next_value
self._current_event += 1
next_value = self._file.readline()
def death(self):
"""
death() closes input file
"""
self._file.close()
return True