Python and C++ Parser
The endf-parserpy package contains two independent ENDF parsers,
one written in pure Python and another one written
(or more appropriate, generated)
in C++. Most examples in the tutorials make use of the Python parser by
instantiating the EndfParserPy class. However,
the C++ parser implemented in the EndfParserCpp
class is much faster and functionally equivalent,
apart from the fact that it does not support some very specific initialization arguments.
In other words, the C++ parser returns exactly the same nested Python dictionary
as the Python parser. Also, when you serialize a Python dictionary to the
ENDF format, the output of both parsers is exactly the same, character by character.
Therefore, it is recommended to use the C++ parser and only fall back on the
Python parser if the C++ parser is not available or some very specific
behavior has been requested that is only supported by the Python parser.
To help with the selection of the appropriate parser,
the EndfParserFactory class can automatically
select the right parser according to the user-supplied
initialization arguments. A parser object can be obtained by
from endf_parserpy import EndfParserFactory
parser = EndfParserFactory.create()
Without any initialization arguments, the faster C++ parser will be selected
if available, otherwise the Python parser. If the method needs to fall back
on the Python parser, it will issue a UserWarning informing
the user that parsing and writing will be slow. This warning message
can be suppressed by using an additional argument:
parser = EndfParserFactory.create(warn_slow=False)
In addition, this function can take any arguments that are supported
by the EndfParserPy or
the EndfParserCpp class.
It will then select the appropriate parser according to argument compatibility.
For instance, using the loglevel argument, not supported by
the C++ parser, will force the selection of the Python parser:
from endf_parserpy import EndfParserPy
parser = EndfParserFactory.create(loglevel=30)
assert type(parser) = EndfParserPy
From the viewpoint of a developer, it may be pertinent to have some
guarantee that initialization arguments are compatible with both
the Python and the C++ parser to avoid depending on a specific
parser. Argument compatibility can be enforced by the
require_compat argument:
parser = EndfParserFactory.create(require_compat=True)
With this option being true, parser instantiation will fail for
arguments not compatible with both parser types,
raising a ValueError exception. For instance,
parser = EndfParserFactory.create(require_compat=True, loglevel=20)
will fail as loglevel is only supported by the Python parser.
Without the require_compat=True argument, the method would return
a Python parser object (instance of EndfParserPy).
Finally, it is also possible to manually select the parser type by
supplying the select argument. Instead of the default,
select="fastest", one can also use "python" for the Python and
"cpp" for the C++ parser, for instance:
parser = EndfParserFactory.create(select="cpp")
This invocation is equivalent to parser = EndfParserCpp().
In summary, the endf_parserpy.EndfParserFactory.create() method
helps the user to pick the best available parser type and provides
informative error messages if something goes wrong. Disregarding the
implemented selection logic for a moment, this function is equivalent to
from endf_parserpy import EndfParserPy
parser = EndfParserPy(...)
if the Python parser (EndfParserPy) is selected or
from endf_parserpy import EndfParserCpp
parser = EndfParserCpp(...)
if the C++ parser (EndfParserCpp) is selected
As described above, the selection of the parser
depends on the availability of the C++ parser and whether the arguments
provided to EndfParserFactory are supported by the
C++ parser.