# 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