Warning, /jana2/docs/behavior.md is written in an unsupported language. File is not indexed.
0001
0002 # Behavior specification
0003
0004 ## Introduction
0005
0006 ## Components
0007
0008 ### JFactories
0009
0010 #### Callbacks
0011
0012 The user-defined callbacks are `Init`, `Process`, `BeginRun`, `EndRun`, and `Finish`.
0013
0014 - `Init` is run at most once, and is used for loading and caching constant data. It is guaranteed to run before any call to `Process`.
0015 If `Process` is never called, e.g. because the data is `Insert`ed instead, then `Init` will not be called.
0016
0017 - `Finish` only runs if `Init` has ran, and is responsible for cleaning up and closing any state opened by `Init`.
0018
0019 - `BeginRun` runs after `Init` and before `Process`. It will only be called if the run number has been set, and this will be the first call to `Process` corresponding to that run number.
0020 `BeginRun` is responsible for loading and caching data keyed off of the run number, e.g. conditions, calibrations, lookup tables, machine learning models.
0021
0022 - `EndRun` runs after a previously set run number gets changed. It runs after the last call to `Process` with that run number, and before the `BeginRun` for the new run number.
0023 `EndRun` is responsible for cleaning up and closing any state opened by the previous call to `BeginRun`. `EndRun` is guaranteed to be called exactly once for each `BeginRun`, as long
0024 as JANA2 is shut down cleanly.
0025
0026 - `Process` is called exactly once for every JEvent. By the time `Process` is called, JANA2 guarantees that `Init` will have been called, followed by `BeginRun` if the run number has been set.
0027
0028 #### Activation
0029 JFactories are lazy by design, which means that they won't be activated unless requested by another component. Activation is defined as calling `JFactory::Create` with a given JEvent, which
0030 triggers the running of zero or more factory callbacks. Users are discouraged from calling `JFactory::Create` directly; instead, factories are usually activated via any of the following mechanisms:
0031
0032 - Declaring an `Input<T>` helper member variable on another JComponent.
0033 - Calling `JEvent::Get*<T>()` or `JEvent::GetCollection<T>()`
0034 - Setting the parameter `jana:autoactivate=$DATABUNDLE_NAME`. This will activate the factory even though its results are never used downstream, which is mainly useful for debugging.
0035
0036 #### Exception handling
0037 JFactory's user-defined methods are allowed to throw exceptions. Unlike other JANA2 components, throwing an exception here does not immediately terminate processing -- the
0038 user has the opportunity to catch the exception in the caller. For instance, calls to `JEvent::Get*` may be wrapped in a try-catch block. The exception itself is wrapped in a `JException` which preserves
0039 stack trace and component information. If a factory callback excepts, the exception is stored so that it can be re-thrown on future calls. The excepting callback will only be called once. If any
0040 callbacks except, JANA2 will still store the contents of each `Output` helper's transient output buffer. This means that if `Process` excepts, all data inserted prior to the exception will be preserved.
0041
0042 #### State machine
0043
0044 The JFactory state machine is defined as follows. The state has two components, `InitStatus` and `Status`. `InitStatus <- {NotRun, Run, Excepted}`, which allows `JFactory::Create` to guarantee that
0045 `Init` gets called at most once, even when some events have the factory data `Insert`ed and others let it be `Processed`. `Status <- {Empty, Processed, Inserted, Excepted}` captures what exactly
0046 is in cache. `Empty` is the only state where no data has been cached/stored; `Excepted` means that an empty or partial collection was stored. This storage operation is guaranteed to happen exactly once
0047 per activated factory per event, a requirement imposed by Podio's write-exactly-once semantics. The following transition diagram shows the relationship between valid states and transitions corresponding
0048 to factory callbacks.
0049
0050 ```mermaid
0051
0052 stateDiagram-v2
0053 NE : (InitNotRun, Empty)
0054 XE : (InitExcepted, Empty)
0055 XX : (InitExcepted, Excepted)
0056 RE : (InitRun, Empty)
0057 RI : (InitRun, Inserted)
0058 RP : (InitRun, Processed)
0059 RX : (InitRun, Excepted)
0060 NI : (InitNotRun, Inserted)
0061 XI : (InitExcepted, Inserted)
0062
0063 [*] --> NE
0064 NE --> RE: Init
0065 RE --> RP: Process
0066 RP --> RE: ClearData
0067 RE --> RX: Process
0068 RX --> RE: ClearData
0069 RE --> RI: Insert
0070 RI --> RE: ClearData
0071 NE --> NI: Insert
0072 NI --> NE: ClearData
0073 NE --> XE: Init
0074 XE --> XX: Process
0075 XX --> XE: ClearData
0076 XE --> XI: Insert
0077 XI --> XE: ClearData
0078 ```
0079
0080 Note that many of these transitions are encapsulated behind `JFactory::Create`. The only operations available to the user are `Create` (i.e. activate), `Insert`, and `ClearData`.
0081 Redrawing the state diagram in terms of these transitions gives us:
0082
0083 ```mermaid
0084 stateDiagram-v2
0085 NE : (InitNotRun, Empty)
0086 XE : (InitExcepted, Empty)
0087 XX : (InitExcepted, Excepted)
0088 RE : (InitRun, Empty)
0089 RI : (InitRun, Inserted)
0090 RP : (InitRun, Processed)
0091 RX : (InitRun, Excepted)
0092 NI : (InitNotRun, Inserted)
0093 XI : (InitExcepted, Inserted)
0094
0095 [*] --> NE
0096 NE --> RP: Create
0097 RE --> RP: Create
0098 RP --> RE: ClearData
0099 RE --> RX: Create
0100 RX --> RE: ClearData
0101 RE --> RI: Insert
0102 RI --> RE: ClearData
0103 NE --> NI: Insert
0104 NI --> NE: ClearData
0105 NE --> XX: Create
0106 XE --> XX: Create
0107 XX --> XE: ClearData
0108 XE --> XI: Insert
0109 XI --> XE: ClearData
0110 NE --> RX: Create
0111 ```
0112
0113 Although not shown for the sake of visual clarity, it is important to note that `Create` operations are idempotent, so all of the `Status:Inserted`, `Status:Processed`, and `Status:Excepted` states
0114 have implicit `Create` transitions pointing back to themselves. Correspondingly, the `Status:Empty` states have `ClearData` transitions pointing back to themselves. However, the `Status:Inserted` states
0115 do _not_ have `Insert` transitions pointing back to themselves. Multiple `Insert` operations are disallowed due to the write-once constraint.
0116
0117
0118 ## Execution Engine
0119
0120 ### Engine initialization
0121
0122 If no `JEventSources` are present in the processing topology, `JApplication::Initialize()` will still succeed, and all present components will be initialized.
0123
0124 ### Engine operation
0125
0126 If no `JEventSources` are present in the processing topology, `JExecutionEngine::Run()` will immediately throw a detailed `JException`. This will terminate `JApplication::Run()` and cause `JMain::Execute()` to exit the program.
0127
0128 ### Factory auto activation
0129 The `JAutoActivator` plugin, when enabled by setting the `autoactivate` parameter, always runs before the other `PhysicsEvent`-level JEventProcessors`. `JAutoActivator` calls the corresponding `JFactory::Create` for each data bundle in the `autoactivate` list, in the order provided.
0130
0131 ### Max in-flight events
0132 The number of in-flight events is controlled by the `jana:max_inflight_events` parameter, and defaults to the same value as the `nthreads` parameter. JANA2 will create this many `JEvents` in the pool at each `JEventLevel`. Increasing the number of in-flight events means more available tasks and hence better utilization of the worker threads, at the expense of more memory usage and longer startup time.
0133
0134 ### Timeout
0135 The execution engine will optionally enforce a timeout on arrow execution. If the timeout is exceeded, the supervisor will throw an exception, which will end all processing. The timeout duration is controlled by the `jana:timeout` and `jana:warmup_timeout` parameters. The warmup timeout exists because factories' `BeginRun` callback might take a long time when the event is used for the first time, for instance connecting to external resources such as calibration databases. The execution engine will decide whether to enforce the warmup timeout vs the general timeout by checking the `JEvent::IsWarmedUp` flag. This flag is initially set to false and is set to true once it has been processed successfully exactly once, as determined via `JEvent::Finish`.
0136
0137
0138
0139