Back to home page

EIC code displayed by LXR

 
 

    


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