HepMC3 event record library
ReaderFactory

HepMC includes an abstract Reader interface that can be implemented to read a wide range of different file types. Example file types include the old Ascii2 version, the new Ascii standard, or ROOT I/O.

User code may want to be independent of the file type, and so a way of obtaining a Reader without specifying the type is useful.

ReaderFactory has a static make_reader(string) method, which takes the name of a file as the input. When this is called, the ReaderFactory will test each of the possible Readers that it is aware of and return one if it matches the file type. For an example of the use, see test/testReaderFactory1.cc or test/testReaderFactory2.cc. Note that in both tests, the derived type of the Reader does not need to be specified, even though the tests read a few different file types.

Users can implement their own derived Reader types for reading custom files etc. In order for such a custom Reader to be known to the ReaderFactory, it must implement the following:

In a single compilation unit (typically the .cc file for the custom Reader) there must be a declared instance of a Creator as follows:

#include "HepMC3/ReaderFactory.h"
namespace HepMC3{
class MyCustomReaderClass;
ReaderFactory::Creator<MyCustomReaderClass> MyCustomReaderClassCreator;
}
HepMC3 main namespace.

In order to be matched to the appropriate file type, the custom reader must implement one of the two following methods

fileSignatures() returns a list of strings whose presence will be checked for in the header of the file. The factory expects that these strings will occur in the file on separate consecutive lines (empty lines are ignored). i.e. in the example below, it expects "str1" to be found on the first non-empty line and "str2" will be found on the second non-empty line

vector<string> fileSignatures()const override{return {"str1", "str2"}};

Alternatively, the custom Reader must implement a method called matchesFile

bool matchesFile(const string &filename) const override;

This will check the given filename and return true if the custom Reader is capable of reading it. See for example rootIO/include/HepMC3/ReaderRootTree.h

Having implemented the new Reader and added one (or both) of those methods, it can be checked by the ReaderFactory and will be used automatically where appropriate.

Note that it is always possible to construct a specific type of Reader directly if that is a better fit for the user code. Also note that it is fine to implement a custom Reader that does not implement the necessary functions for ReaderFactory, but such a Reader will not be discoverable by ReaderFactory - it could only be constructed directly. ReaderFactory is an optional utility to make user code simpler, but it is not mandatory to use it.

Last update 27 Oct 2020