Structure of NA64SW project

na64sw API provides a number of various classes and functions. To maintain some sort of reasonable order, they are split onto few libraries with well-defined functionality. This is what we called a core libraries.

Besides of core libraries a set of utility applications and scripts is provided by the distribution to utilize this core infrastructure for needs of NA64 experiment (yet, core libs are assumed to be experiment-agnostic).

Libraries

The core set of libraries with their roles and dependency graph is summed up on the following diagram:

../_images/core-libs-component-diagram.png

Core libraries of NA64sw package. One component here normally corresponds to one static or dynamic library. Note, that part of the library set depends on the code synthesed based on .yaml files (event-struct artifact).

The project relies on static polymorphism regarding data being processed. Besides of significant performance benefit (compared to more traditional RTTI-based C++ polymorphism), this makes possible for most of the routines become generic to the particular event data types before the compilation. However, the compiled implementation becomes data-specific. Effectively, if one would like to adopt this framework to another experiment, with different event data topology one has to change what is described in event-struct manifests (.yaml files) and re-compile the code.

Core libraries and their roles:

  • na64util common purpose utility functions and classes shared across other specialized libraries. Provides various utilities used by other libraries: logging system (via third-party library), string interpolation, URI and path parsing and tokenization, files lookup, etc.

  • na64detID library implements detector identification functions: the DetID C++ type with to/from string conversion with DetectorNaming class responsible for such conversions. Details on detectors naming are documented in Detectors naming section of this manual.

  • na64calib provides calibration data management classes implementing publisher/subscriber pattern, calibration data loader and dispatcher abstractions.

  • na64event provides physical event data representation with corresponding hits structures. Sources for this library are partially generated automatically.

  • na64dp contains a data pipeline API implementation

  • na64app is high-level API designed for applications. Defines common logic for gearing things up within executable or third-party codes (resolving environment variables, discovering calibration data and building its dependency graph, etc).

Library settings get initialized at the runtime (typically, from within na64app’s high-level calls) from few major configuration files. By default the logging sub-system gets configured from logging.yaml config file, the calibration settings are read from calibration.yaml where naming.yaml is referenced as a part of calibration info to be further used together with na64detID routines.

../_images/core-libs-component-diagram-w-configs.png

Core libraries of NA64sw package and default configuration sources. Note, that particular location of these files can be overloaded at the runtime.

In the repository core libraries are implemented in the corresponding subdirectories of ./include/ and ./src/ first-level dirs, artifacts (config files) are located in presets/ dir.

Applications

A (limited) set of applications utilizing core library interfaces is provided:

  • na64sw-pipe is the pipeline application (perhaps, most important one).

  • na64sw-tests (built optionally) performs unit-testing. Depends on Google’s testing framework and won’t be compiled if gtest is not found in the system.

  • na64-get-fts is the helper utility to retrieve various information from file produced by pipeline application (quantity distributions data, approximations, frequencies, etc).

Applications source codes reside in the appropriate subdirectories of utils/ first-level folder.

Plug-ins and Extensions

Plug-ins are meant to be loaded at the runtime. Each plugin brings extensions of certain types that meant to be added in the framework to extend the following software capabilities:

  • handler entity represents a single and usually extremely simple event processing procedure. Best way to think of it as of simple standalone program capable to access, add and modify any data within an event. Interface required by data processing component (na64dp library). Interface provided by handlers and exp-handlers libraries.

  • data source entity produces events. It usually receives the subject (phys.event) data from external source – a file, web socket or shared memory. Data source instance transcodes the event from external source into framework’s representation to be processed by the handlers. Interface required by data processing component (na64dp library), provided by extensions like ddd (DaqDataDecoding library implementing NA64 raw data reading) or avro (implements data serialization based on Apache Avro)

  • getter is a (pure) function used to retrieve certain data from subject datum object (phys. event). Getters are even more simpler than handler, they are stateless and usually used by some generalized handlersevent. For instance, “calo_edep” getter will provide generic plotting handler with the energy deposition in calorimeters. Interface is required by event component (na64event library) and implemented statically, within the same library, based on event manifest specification. Consider reading Event object model for details on event data topology.

  • so-called runtime app. extension is a special interface implementation designed to interoperate with main application logic. Various GUI event displays (like one based on GenFit), network recievers and dispatchers provide this type of interface to start/stop event processing based on external stimuli (e.g. user’s actions at GUI). This interface is required by application component (partially implemented in na64app lib).

../_images/core-libs-component-diagram-w-exts.png

Core libraries of NA64sw package as components and some extensions provided in the default source code distro. The handlers and exp-handlers extensions are experiment-specific and tightly bound to data topology.

Though advanced users are encouraged to develop their own plugins in local projects, a somewhat common set may be found in the extensions/ directory: handlers, avro, currently reside there.

Source code structure

The following structure must be respected:

  • doc/ lists the documentation assets (guideline pages, examples, etc.)

  • extensions/ a set of default runtime extensions – plug-ins (handlers, data sources and so on)

  • include/ is for C/C++ header files of the main libraries

  • presets/ is for configuration files, common calibraion data, geometry sources, etc.

  • src/ is for C/C++ inplementation files

  • utils/ is for miscellaneous utils, tiny related subprojects, etc.

  • CMakeLists.txt file is main file that performs build procedure of the project (to be precise, instructs the CMake application how to generate a Makefile that is then used by make to build up everything).

Automatically generated code

Few parts of the framework are generated with automated tools (lake beforementioned event data topology implementation on C++). Although the source code is generated and thus depends on third-party utils and its input, we decided to not to include it as a standard build stage (for instance, detector selectors language or event structure generator) and keep generated output in the repo. This way one can build the project with fewer dependencies.

If, however, one faced it, take note that following parts are generated automatically:

Environment variables

Following environment variables affect evaluation of the na64sw routines:

  • NA64SW_PREFIX installation prefix for na64sw. Used to define various assets’ locations: source configs, calibration files, extension modules, run configuration files, etc. By default, the one configured by CMake is used.

  • NA64SW_RUN_CFG_PATH colon-separated list of the runtime configuration files. Assumed to .:$NA64SW_PREFIX/etc/na64sw/run by default. Used in include definitions of runtime configs.

  • NA64SW_MODULES_PATH colon-separated list of the directories for modules lookup. Assumed to .:$NA64SW_PREFIX/lib/na64sw/extensions by default.

  • P348_CONDDB_PATH – path for calibration files lookup. Not used directly from C/C++ code but may be referred in calibration configuration files.

  • P348RECO_DIR – some extensions (DDD data source and p348reco data source) may rely on this variable to locate DAQ mappings for raw data decoding. If it is not explicitly set, it will be assumed to whatever path was found for p348-daq repo during configuration stage.

Installation Prefix (FHS)

Standard UNIX prefix-based package installation structure (FHS) implies that package is deployed with respect of some path prefix in a following form:

  • /prefix/lib or /prefix/usr/lib64 is for libraries

  • /prefix/include is for header files

  • /prefix/bin is for utilities

  • /prefix/etc is for configuration files

  • /prefix/share is for various assets

System packages (like binutils) usually installed at / prefix, while user’s system-wide packages (so called secondary hierarchy) are deployed under /usr prefix. You are doubtly interested in system-wide installation of na64sw but it is better to stick to this classic convention for compatibility reasons, so do we.