use
– Inject parsing results into free functions
This module extends the functionalities provided by use
to
the commonplace task of parsing Tripoli-4 output files. The decorators defined
by this module, using_parse_result
and using_browser
,
can be used to remove boilerplate code that parses and accesses the Tripoli-4
results. At the same time, they simplify the integration of user-defined
post-processing (tests) into the valjean
workflow.
We will need to set up a few things to show an example of how to use the decorators. We don’t want to build and run Tripoli-4 for the purpose of this documentation, but we can mock a Tripoli-4 run by writing an existing Tripoli-4 output to a file. Here is the sample output:
>>> example = """BATCH 10
... initialization time (s): 7
... batch number : 10
... *********************************************************
... RESULTS ARE GIVEN FOR SOURCE INTENSITY : 8.111452e+04
... *********************************************************
...
...
... Mean weight leakage = 7.929746e+00 sigma = 7.929746e+00 sigma% = 1.000000e+02
...
...
... Edition after batch number : 10
...
...
...
... ******************************************************************************
... RESPONSE FUNCTION : FLUX
... RESPONSE NAME :
... ENERGY DECOUPAGE NAME : DEC_SPECTRE
...
...
... PARTICULE : NEUTRON
... ******************************************************************************
...
... scoring mode : SCORE_SURF
... scoring zone : Frontier volumes : 14,27
...
...
... SPECTRUM RESULTS
... number of first discarded batches : 0
...
... group score sigma_% score/lethargy
... Units: MeV neut.s^-1 % neut.s^-1
...
... 2.000000e+01 - 1.000000e-11 1.307419e+00 8.719708e+01 1.046074e+01
...
... ENERGY INTEGRATED RESULTS
...
... number of first discarded batches : 0
...
... number of batches used: 10 1.307419e+00 8.719708e+01
...
...
...
... simulation time (s) : 20
...
...
... Type and parameters of random generator at the end of simulation:
... DRAND48_RANDOM 13531 45249 20024 COUNTER 2062560
...
...
... simulation time (s): 20
...
...
... =====================================================================
... NORMAL COMPLETION
... =====================================================================
... """
We construct a RunTaskFactory
that simply echoes any text passed as
an argument:
>>> from valjean.cosette.run import RunTaskFactory
>>> echo_factory = RunTaskFactory.from_executable('/bin/echo', name='echo',
... default_args=['{text}'])
In the real world, the RunTaskFactory
would actually generate tasks
to run a Tripoli-4 executable.
Injecting the raw parse results
Now we can construct the decorator that parses the Tripoli-4 results and apply it to a Python function:
>>> from valjean.eponine.tripoli4 import use
>>> using_last_parse_result = use.using_last_parse_result(echo_factory)
>>> @using_last_parse_result(text=example)
... def source(results):
... return results.res['batch_data']['source_intensity']
If we inspect source, we can see that it is a Use
object:
>>> type(source)
<class 'valjean.cosette.use.Use'>
If you are not sure what Use
does, this is a good moment to go and
read its documentation. Don’t worry, I’ll wait.
(time passes)
valjean
can inspect this object and convert it into a Task
:
>>> source_task = source.get_task()
>>> type(source_task)
<class 'valjean.cosette.pythontask.PythonTask'>
>>> source_task.name
'....source'
The task has explicit dependencies, which means that it will be correctly
integrated in the valjean
dependency graph. In particular, this task
depends on a task that actually does the parsing:
>>> source_task.depends_on
{Task('....parse_batch_index')}
>>> parse_task = next(iter(source_task.depends_on))
It depends on the make_parser_task, that scans the file and build the parser
>>> parse_task.depends_on
{Task('....make_parser')}
>>> make_parser_task = next(iter(parse_task.depends_on))
and make_parser_task in turn depends on the RunTask
that was
generated by echo_factory:
>>> make_parser_task.depends_on
{Task('....echo')}
>>> run_task = next(iter(make_parser_task.depends_on))
We manually execute the tasks in the correct order and we check that we recover the right result at the end:
>>> from valjean.cosette.env import Env
>>> env = Env()
>>> for task in [run_task, make_parser_task, parse_task, source_task]:
... env_up, _ = task.do(env=env, config=config)
... env.apply(env_up)
>>> print(env[source_task.name]['result'])
81114.52
Using a Browser
The raw parse results are useful in some situations, but most of the time you
probably want to work with a higher-level representation of the calculation
result, such as a Browser
. This module provides a function
to construct a decorator that automatically creates the RunTask
from
the RunTaskFactory
, runs the task, parses the resulting output and
wraps the parse results in an Browser
:
>>> using_browser = use.using_browser(echo_factory, 10)
>>> @using_browser(text=example)
... def extract_simulation_time(browser):
... return browser.globals['simulation_time']
We can again check that everything went as expected by manually unwrapping the sequence of tasks and running them:
>>> extract_task = extract_simulation_time.get_task()
>>> browse_task = next(iter(extract_task.depends_on))
>>> parse_task = next(iter(browse_task.depends_on))
>>> make_parser_task = next(iter(parse_task.depends_on))
>>> run_task = next(iter(make_parser_task.depends_on))
>>> env = Env()
>>> for task in [run_task, make_parser_task, parse_task,
... browse_task, extract_task]:
... env_up, _ = task.do(env=env, config=config)
... env.apply(env_up)
>>> print(env[extract_task.name]['result'])
20
Module API
- valjean.eponine.tripoli4.use.partial(func, *args, **kwargs)[source]
An improved version of
functools.partial
that callsfunctools.update_wrapper
on the partially applied function in order to update its metadata (name, etc.).
- valjean.eponine.tripoli4.use.make_parser(filename)[source]
Create a Parser object and scan a Tripoli-4 output file.
- Parameters:
- Raises:
ValueError – if parsing fails.
- Returns:
the parser
- Return type:
- valjean.eponine.tripoli4.use.parse_batch_number(parser, *, batch_number)[source]
Parse a batch result from Tripoli-4.
- Parameters:
batch_number (int) – batch number
- Return type:
- valjean.eponine.tripoli4.use.parse_batch_index(parser, *, batch_index=- 1)[source]
Parse a batch result from Tripoli-4.
- Parameters:
batch_index (int) – index of the batch in the list of batches
- Return type:
- valjean.eponine.tripoli4.use.using_parser(factory)[source]
Construct a decorator that injects Tripoli-4 parser into a Python function.
- Parameters:
factory (
RunTaskFactory
) – a factory producing Tripoli-4 runs.- Returns:
a decorator (see the module docstring for more information).
- valjean.eponine.tripoli4.use.using_parse_result(factory, batch_number)[source]
Construct a decorator that injects the raw Tripoli-4 parse results into a Python function.
- Parameters:
factory (
RunTaskFactory
) – a factory producing Tripoli-4 runs.batch_number (int) – the number of the batch to parse; see
__init__
.
- Returns:
a decorator (see the module docstring for more information).
- valjean.eponine.tripoli4.use.using_last_parse_result(factory)[source]
Construct a decorator that injects the last raw Tripoli-4 parse results into a Python function.
- Parameters:
factory (
RunTaskFactory
) – a factory producing Tripoli-4 runs.- Returns:
a decorator (see the module docstring for more information).
- valjean.eponine.tripoli4.use.to_browser(result)[source]
Create a
Browser
from the parsing result.- Parameters:
result (ParseResult) – result from T4 parser
- Returns:
the browser
- Return type:
- valjean.eponine.tripoli4.use.using_browser(factory, batch_number)[source]
Construct a decorator that injects an
Browser
to the Tripoli-4 parse results into a Python function.- Parameters:
factory (
RunTaskFactory
) – a factory producing Tripoli-4 runs.batch_number (int) – the number of the required batch (will be parsed then transformed in
Browser
)
- Returns:
a decorator (see the module docstring for more information).
- valjean.eponine.tripoli4.use.using_last_browser(factory)[source]
Construct a decorator that injects a
Browser
to the Tripoli-4 last parse results into a Python function.- Parameters:
factory (
RunTaskFactory
) – a factory producing Tripoli-4 runs.- Returns:
a decorator (see the module docstring for more information).