Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Corryvreckan
Corryvreckan
Commits
e6890155
Commit
e6890155
authored
Dec 18, 2018
by
Simon Spannagel
Browse files
Separate ModuleManager from central Corryvreckan class
parent
65aeac06
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/core/CMakeLists.txt
View file @
e6890155
...
...
@@ -3,6 +3,7 @@ INCLUDE_DIRECTORIES(SYSTEM ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
# Create core library
ADD_LIBRARY
(
CorryvreckanCore SHARED
Corryvreckan.cpp
detector/Detector.cpp
utils/log.cpp
utils/unit.cpp
...
...
src/core/Corryvreckan.cpp
0 → 100644
View file @
e6890155
/** @file
* @brief Implementation of interface to the core framework
* @copyright Copyright (c) 2017 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
#include
"Corryvreckan.hpp"
#include
<chrono>
#include
<climits>
#include
<fstream>
#include
<memory>
#include
<stdexcept>
#include
<thread>
#include
<utility>
#include
<TROOT.h>
#include
<TRandom.h>
#include
<TStyle.h>
#include
<TSystem.h>
#include
"core/config/exceptions.h"
#include
"core/utils/file.h"
#include
"core/utils/log.h"
#include
"core/utils/unit.h"
using
namespace
corryvreckan
;
/**
* This class will own the managers for the lifetime of the simulation. Will do early initialization:
* - Configure the special header sections.
* - Set the log level and log format as requested.
* - Load the detector configuration and parse it
*/
Corryvreckan
::
Corryvreckan
(
std
::
string
config_file_name
,
const
std
::
vector
<
std
::
string
>&
module_options
,
const
std
::
vector
<
std
::
string
>&
detector_options
)
:
terminate_
(
false
),
has_run_
(
false
),
mod_mgr_
(
std
::
make_unique
<
ModuleManager
>
())
{
// Load the global configuration
conf_mgr_
=
std
::
make_unique
<
ConfigManager
>
(
std
::
move
(
config_file_name
),
std
::
initializer_list
<
std
::
string
>
({
"Corryvreckan"
,
""
}),
std
::
initializer_list
<
std
::
string
>
({
"Ignore"
}));
// Load and apply the provided module options
conf_mgr_
->
loadModuleOptions
(
module_options
);
// Load and apply the provided detector options
conf_mgr_
->
loadDetectorOptions
(
detector_options
);
// Fetch the global configuration
Configuration
&
global_config
=
conf_mgr_
->
getGlobalConfiguration
();
// Set the log level from config if not specified earlier
std
::
string
log_level_string
;
if
(
Log
::
getReportingLevel
()
==
LogLevel
::
NONE
)
{
log_level_string
=
global_config
.
get
<
std
::
string
>
(
"log_level"
,
"INFO"
);
std
::
transform
(
log_level_string
.
begin
(),
log_level_string
.
end
(),
log_level_string
.
begin
(),
::
toupper
);
try
{
LogLevel
log_level
=
Log
::
getLevelFromString
(
log_level_string
);
Log
::
setReportingLevel
(
log_level
);
}
catch
(
std
::
invalid_argument
&
e
)
{
LOG
(
ERROR
)
<<
"Log level
\"
"
<<
log_level_string
<<
"
\"
specified in the configuration is invalid, defaulting to INFO instead"
;
Log
::
setReportingLevel
(
LogLevel
::
INFO
);
}
}
else
{
log_level_string
=
Log
::
getStringFromLevel
(
Log
::
getReportingLevel
());
}
// Set the log format from config
std
::
string
log_format_string
=
global_config
.
get
<
std
::
string
>
(
"log_format"
,
"DEFAULT"
);
std
::
transform
(
log_format_string
.
begin
(),
log_format_string
.
end
(),
log_format_string
.
begin
(),
::
toupper
);
try
{
LogFormat
log_format
=
Log
::
getFormatFromString
(
log_format_string
);
Log
::
setFormat
(
log_format
);
}
catch
(
std
::
invalid_argument
&
e
)
{
LOG
(
ERROR
)
<<
"Log format
\"
"
<<
log_format_string
<<
"
\"
specified in the configuration is invalid, using DEFAULT instead"
;
Log
::
setFormat
(
LogFormat
::
DEFAULT
);
}
// Open log file to write output to
if
(
global_config
.
has
(
"log_file"
))
{
// NOTE: this stream should be available for the duration of the logging
log_file_
.
open
(
global_config
.
getPath
(
"log_file"
),
std
::
ios_base
::
out
|
std
::
ios_base
::
trunc
);
LOG
(
TRACE
)
<<
"Added log stream to file "
<<
global_config
.
getPath
(
"log_file"
);
Log
::
addStream
(
log_file_
);
}
// Wait for the first detailed messages until level and format are properly set
LOG
(
TRACE
)
<<
"Global log level is set to "
<<
log_level_string
;
LOG
(
TRACE
)
<<
"Global log format is set to "
<<
log_format_string
;
}
/**
* Performs the initialization, including:
* - Determine and create the output directory
* - Include all the defined units
* - Load the modules from the configuration
*/
void
Corryvreckan
::
load
()
{
LOG
(
TRACE
)
<<
"Loading Corryvreckan"
;
// Fetch the global configuration
Configuration
&
global_config
=
conf_mgr_
->
getGlobalConfiguration
();
// Put welcome message and set version
LOG
(
STATUS
)
<<
"Welcome to Corryvreckan "
<<
CORRYVRECKAN_PROJECT_VERSION
;
global_config
.
set
<
std
::
string
>
(
"version"
,
CORRYVRECKAN_PROJECT_VERSION
);
// Set the default units to use
add_units
();
// Load the modules from the configuration
if
(
!
terminate_
)
{
mod_mgr_
->
load
(
conf_mgr_
.
get
());
}
else
{
LOG
(
INFO
)
<<
"Skip loading modules because termination is requested"
;
}
}
/**
* Runs the Module::init() method linearly for every module
*/
void
Corryvreckan
::
init
()
{
if
(
!
terminate_
)
{
LOG
(
TRACE
)
<<
"Initializing Corryvreckan"
;
mod_mgr_
->
initialiseAll
();
}
else
{
LOG
(
INFO
)
<<
"Skip initializing modules because termination is requested"
;
}
}
/**
* Runs every modules Module::run() method linearly for the number of events
*/
void
Corryvreckan
::
run
()
{
if
(
!
terminate_
)
{
LOG
(
TRACE
)
<<
"Running Corryvreckan"
;
mod_mgr_
->
run
();
// Set that we have run and want to finalize as well
has_run_
=
true
;
}
else
{
LOG
(
INFO
)
<<
"Skip running modules because termination is requested"
;
}
}
/**
* Runs all modules Module::finalize() method linearly for every module
*/
void
Corryvreckan
::
finalize
()
{
if
(
has_run_
)
{
LOG
(
TRACE
)
<<
"Finalizing Corryvreckan"
;
mod_mgr_
->
finaliseAll
();
}
else
{
LOG
(
INFO
)
<<
"Skip finalizing modules because no module did run"
;
}
}
/*
* This function can be called safely from any signal handler. Time between the request to terminate
* and the actual termination is not always negigible.
*/
void
Corryvreckan
::
terminate
()
{
terminate_
=
true
;
mod_mgr_
->
terminate
();
}
void
Corryvreckan
::
add_units
()
{
LOG
(
TRACE
)
<<
"Adding physical units"
;
// LENGTH
Units
::
add
(
"nm"
,
1e-6
);
Units
::
add
(
"um"
,
1e-3
);
Units
::
add
(
"mm"
,
1
);
Units
::
add
(
"cm"
,
1e1
);
Units
::
add
(
"dm"
,
1e2
);
Units
::
add
(
"m"
,
1e3
);
Units
::
add
(
"km"
,
1e6
);
// TIME
Units
::
add
(
"ps"
,
1e-3
);
Units
::
add
(
"ns"
,
1
);
Units
::
add
(
"us"
,
1e3
);
Units
::
add
(
"ms"
,
1e6
);
Units
::
add
(
"s"
,
1e9
);
// TEMPERATURE
Units
::
add
(
"K"
,
1
);
// ENERGY
Units
::
add
(
"eV"
,
1e-6
);
Units
::
add
(
"keV"
,
1e-3
);
Units
::
add
(
"MeV"
,
1
);
Units
::
add
(
"GeV"
,
1e3
);
// CHARGE
Units
::
add
(
"e"
,
1
);
Units
::
add
(
"ke"
,
1e3
);
Units
::
add
(
"fC"
,
1
/
1.6021766208e-4
);
Units
::
add
(
"C"
,
1
/
1.6021766208e-19
);
// VOLTAGE
// NOTE: fixed by above
Units
::
add
(
"V"
,
1e-6
);
Units
::
add
(
"kV"
,
1e-3
);
// MAGNETIC FIELD
Units
::
add
(
"T"
,
1e-3
);
Units
::
add
(
"mT"
,
1e-6
);
// ANGLES
// NOTE: these are fake units
Units
::
add
(
"deg"
,
0.01745329252
);
Units
::
add
(
"rad"
,
1
);
Units
::
add
(
"mrad"
,
1e-3
);
}
src/core/Corryvreckan.hpp
0 → 100644
View file @
e6890155
/** @file
* @brief Interface to the core framework
* @copyright Copyright (c) 2017 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
/**
* @defgroup Managers Managers
* @brief The global set of managers used in framework
*/
#ifndef CORRYVRECKAN_CORRYVRECKAN_H
#define CORRYVRECKAN_CORRYVRECKAN_H
#include
<atomic>
#include
<fstream>
#include
<memory>
#include
<string>
#include
"config/ConfigManager.hpp"
#include
"module/ModuleManager.hpp"
namespace
corryvreckan
{
/**
* @brief Provides the link between the core framework and the executable.
*
* Supply the path location the main configuration which should be provided to the executable. Hereafter this class
* should be used to load, initialize, run and finalize all the modules.
*/
class
Corryvreckan
{
public:
/**
* @brief Constructs Corryvreckan and initialize all managers
* @param config_file_name Path of the main configuration file
* @param options List of extra configuration options
*/
explicit
Corryvreckan
(
std
::
string
config_file_name
,
const
std
::
vector
<
std
::
string
>&
module_options
=
std
::
vector
<
std
::
string
>
(),
const
std
::
vector
<
std
::
string
>&
detector_options
=
std
::
vector
<
std
::
string
>
());
/**
* @brief Load modules from the main configuration and construct them
* @warning Should be called after the \ref Corryvreckan() "constructor"
*/
void
load
();
/**
* @brief Initialize all modules (pre-run)
* @warning Should be called after the \ref Corryvreckan::load "load function"
*/
void
init
();
/**
* @brief Run all modules for the number of events (run)
* @warning Should be called after the \ref Corryvreckan::init "init function"
*/
void
run
();
/**
* @brief Finalize all modules (post-run)
* @warning Should be called after the \ref Corryvreckan::run "run function"
*/
void
finalize
();
/**
* @brief Request termination as early as possible without changing the standard flow
*/
void
terminate
();
private:
/**
* @brief Sets the default unit conventions
*/
void
add_units
();
/**
* @brief Set the default ROOT plot style
*/
void
set_style
();
// Indicate the framework should terminate
std
::
atomic
<
bool
>
terminate_
;
std
::
atomic
<
bool
>
has_run_
;
// Log file if specified
std
::
ofstream
log_file_
;
// All managers in the framework
std
::
unique_ptr
<
ModuleManager
>
mod_mgr_
;
std
::
unique_ptr
<
ConfigManager
>
conf_mgr_
;
};
}
// namespace corryvreckan
#endif
/* CORRYVRECKAN_CORRYVRECKAN_H */
src/core/module/ModuleManager.cpp
View file @
e6890155
...
...
@@ -32,77 +32,13 @@
using
namespace
corryvreckan
;
// Default constructor
ModuleManager
::
ModuleManager
(
std
::
string
config_file_name
,
const
std
::
vector
<
std
::
string
>&
module_options
,
const
std
::
vector
<
std
::
string
>&
detector_options
)
:
m_reference
(
nullptr
),
m_terminate
(
false
)
{
LOG
(
TRACE
)
<<
"Loading Corryvreckan"
;
// Put welcome message
LOG
(
STATUS
)
<<
"Welcome to Corryvreckan "
<<
CORRYVRECKAN_PROJECT_VERSION
;
// Load the global configuration
conf_manager_
=
std
::
make_unique
<
corryvreckan
::
ConfigManager
>
(
std
::
move
(
config_file_name
),
std
::
initializer_list
<
std
::
string
>
({
"Corryvreckan"
,
""
}),
std
::
initializer_list
<
std
::
string
>
({
"Ignore"
}));
// Load and apply the provided module options
conf_manager_
->
loadModuleOptions
(
module_options
);
// Load and apply the provided detector options
conf_manager_
->
loadDetectorOptions
(
detector_options
);
// Fetch the global configuration
Configuration
&
global_config
=
conf_manager_
->
getGlobalConfiguration
();
// Set the log level from config if not specified earlier
std
::
string
log_level_string
;
if
(
Log
::
getReportingLevel
()
==
LogLevel
::
NONE
)
{
log_level_string
=
global_config
.
get
<
std
::
string
>
(
"log_level"
,
"INFO"
);
std
::
transform
(
log_level_string
.
begin
(),
log_level_string
.
end
(),
log_level_string
.
begin
(),
::
toupper
);
try
{
LogLevel
log_level
=
Log
::
getLevelFromString
(
log_level_string
);
Log
::
setReportingLevel
(
log_level
);
}
catch
(
std
::
invalid_argument
&
e
)
{
LOG
(
ERROR
)
<<
"Log level
\"
"
<<
log_level_string
<<
"
\"
specified in the configuration is invalid, defaulting to INFO instead"
;
Log
::
setReportingLevel
(
LogLevel
::
INFO
);
}
}
else
{
log_level_string
=
Log
::
getStringFromLevel
(
Log
::
getReportingLevel
());
}
// Set the log format from config
std
::
string
log_format_string
=
global_config
.
get
<
std
::
string
>
(
"log_format"
,
"DEFAULT"
);
std
::
transform
(
log_format_string
.
begin
(),
log_format_string
.
end
(),
log_format_string
.
begin
(),
::
toupper
);
try
{
LogFormat
log_format
=
Log
::
getFormatFromString
(
log_format_string
);
Log
::
setFormat
(
log_format
);
}
catch
(
std
::
invalid_argument
&
e
)
{
LOG
(
ERROR
)
<<
"Log format
\"
"
<<
log_format_string
<<
"
\"
specified in the configuration is invalid, using DEFAULT instead"
;
Log
::
setFormat
(
LogFormat
::
DEFAULT
);
}
// Open log file to write output to
if
(
global_config
.
has
(
"log_file"
))
{
// NOTE: this stream should be available for the duration of the logging
log_file_
.
open
(
global_config
.
getPath
(
"log_file"
),
std
::
ios_base
::
out
|
std
::
ios_base
::
trunc
);
Log
::
addStream
(
log_file_
);
}
// Wait for the first detailed messages until level and format are properly set
LOG
(
TRACE
)
<<
"Global log level is set to "
<<
log_level_string
;
LOG
(
TRACE
)
<<
"Global log format is set to "
<<
log_format_string
;
ModuleManager
::
ModuleManager
()
:
m_reference
(
nullptr
),
m_terminate
(
false
)
{
// New clipboard for storage:
m_clipboard
=
std
::
make_shared
<
Clipboard
>
();
}
void
ModuleManager
::
load
()
{
add_units
();
void
ModuleManager
::
load
(
ConfigManager
*
conf_mgr
)
{
conf_manager_
=
conf_mgr
;
load_detectors
();
load_modules
();
...
...
@@ -824,49 +760,3 @@ void ModuleManager::set_module_after(std::tuple<LogLevel, LogFormat> prev) {
LOG
(
TRACE
)
<<
"Reset log format to global level of "
<<
Log
::
getStringFromFormat
(
old_format
);
}
}
void
ModuleManager
::
add_units
()
{
LOG
(
TRACE
)
<<
"Adding physical units"
;
// LENGTH
Units
::
add
(
"nm"
,
1e-6
);
Units
::
add
(
"um"
,
1e-3
);
Units
::
add
(
"mm"
,
1
);
Units
::
add
(
"cm"
,
1e1
);
Units
::
add
(
"dm"
,
1e2
);
Units
::
add
(
"m"
,
1e3
);
Units
::
add
(
"km"
,
1e6
);
// TIME
Units
::
add
(
"ps"
,
1e-3
);
Units
::
add
(
"ns"
,
1
);
Units
::
add
(
"us"
,
1e3
);
Units
::
add
(
"ms"
,
1e6
);
Units
::
add
(
"s"
,
1e9
);
// TEMPERATURE
Units
::
add
(
"K"
,
1
);
// ENERGY
Units
::
add
(
"eV"
,
1e-6
);
Units
::
add
(
"keV"
,
1e-3
);
Units
::
add
(
"MeV"
,
1
);
Units
::
add
(
"GeV"
,
1e3
);
// CHARGE
Units
::
add
(
"e"
,
1
);
Units
::
add
(
"ke"
,
1e3
);
Units
::
add
(
"C"
,
1.6021766208e-19
);
// VOLTAGE
// NOTE: fixed by above
Units
::
add
(
"V"
,
1e-6
);
Units
::
add
(
"kV"
,
1e-3
);
// ANGLES
// NOTE: these are fake units
Units
::
add
(
"deg"
,
0.01745329252
);
Units
::
add
(
"rad"
,
1
);
Units
::
add
(
"mrad"
,
1e-3
);
}
src/core/module/ModuleManager.hpp
View file @
e6890155
...
...
@@ -6,8 +6,8 @@
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
#ifndef CORRYVRECKAN_
ANALYSIS
_H
#define CORRYVRECKAN_
ANALYSIS
_H
#ifndef CORRYVRECKAN_
MODULE_MANAGER
_H
#define CORRYVRECKAN_
MODULE_MANAGER
_H
#include
<fstream>
#include
<map>
...
...
@@ -25,9 +25,10 @@
namespace
corryvreckan
{
/**
* @brief Core class of the Corryvreckan analysis framework
* @ingroup Managers
* @brief Manager responsible for dynamically loading all modules and running their event sequence
*
* The
analysis
class is the core class which allows the event processing to run. It basically contains a vector of
* The
module manager
class is the core class which allows the event processing to run. It basically contains a vector of
* modules, each of which is initialised, run on each event and finalised. It does not define what an event is, merely
* runs each module sequentially and passes the clipboard between them (erasing it at the end of each run sequence). When
* an module returns a Failure code, the event processing will stop.
...
...
@@ -36,22 +37,38 @@ namespace corryvreckan {
using
ModuleList
=
std
::
list
<
std
::
shared_ptr
<
Module
>>
;
public:
// Constructors and destructors
explicit
ModuleManager
(
std
::
string
config_file_name
,
const
std
::
vector
<
std
::
string
>&
module_options
=
std
::
vector
<
std
::
string
>
(),
const
std
::
vector
<
std
::
string
>&
detector_options
=
std
::
vector
<
std
::
string
>
());
virtual
~
ModuleManager
(){};
/**
* @brief Construct manager
*/
ModuleManager
();
/**
* @brief Use default destructor
*/
~
ModuleManager
()
=
default
;
/// @{
/**
* @brief Copying the manager is not allowed
*/
ModuleManager
(
const
ModuleManager
&
)
=
delete
;
ModuleManager
&
operator
=
(
const
ModuleManager
&
)
=
delete
;
/// @}
/// @{
/**
* @brief Moving the manager is not allowed
*/
ModuleManager
(
ModuleManager
&&
)
=
delete
;
ModuleManager
&
operator
=
(
ModuleManager
&&
)
=
delete
;
/// @}
// Member functions
void
load
();
void
load
(
ConfigManager
*
conf_mgr
);
void
run
();
void
timing
();
void
initialiseAll
();
void
finaliseAll
();
void
terminate
();
void
reset
(){};
TBrowser
*
browser
;
...
...
@@ -61,9 +78,10 @@ namespace corryvreckan {
std
::
vector
<
std
::
shared_ptr
<
Detector
>>
m_detectors
;
private:
void
timing
();
void
load_detectors
();
void
load_modules
();
void
add_units
();
/**
* @brief Get a specific detector, identified by its name
...
...
@@ -110,7 +128,7 @@ namespace corryvreckan {
std
::
map
<
std
::
string
,
void
*>
loaded_libraries_
;
std
::
atomic
<
bool
>
m_terminate
;
std
::
unique_ptr
<
corryvreckan
::
ConfigManager
>
conf_manager_
;
ConfigManager
*
conf_manager_
;
std
::
tuple
<
LogLevel
,
LogFormat
>
set_module_before
(
const
std
::
string
&
,
const
Configuration
&
config
);
void
set_module_after
(
std
::
tuple
<
LogLevel
,
LogFormat
>
prev
);
...
...
@@ -119,4 +137,4 @@ namespace corryvreckan {
};
}
// namespace corryvreckan
#endif // CORRYVRECKAN_
ANALYSIS
_H
#endif // CORRYVRECKAN_
MODULE_MANAGER
_H
src/exec/corry.cpp
View file @
e6890155
...
...
@@ -6,8 +6,7 @@
#include
<string>
#include
<utility>
#include
"core/config/ConfigManager.hpp"
#include
"core/module/ModuleManager.hpp"
#include
"core/Corryvreckan.hpp"
#include
"core/utils/exceptions.h"
/**
* @file
...
...
@@ -22,7 +21,7 @@ void clean();
void
abort_handler
(
int
);
void
interrupt_handler
(
int
);
std
::
unique_ptr
<
ModuleManager
>
corry
;
std
::
unique_ptr
<
Corryvreckan
>
corry
;
std
::
atomic
<
bool
>
cv_ready
{
false
};
/**
...
...
@@ -169,20 +168,20 @@ int main(int argc, const char* argv[]) {
try
{
// Construct main Corryvreckan object
corry
=
std
::
make_unique
<
ModuleManager
>
(
config_file_name
,
module_options
,
detector_options
);
corry
=
std
::
make_unique
<
Corryvreckan
>
(
config_file_name
,
module_options
,
detector_options
);
cv_ready
=
true
;
// Load modules
corry
->
load
();
// Initialize modules (pre-run)
corry
->
init
ialiseAll
();
corry
->
init
();
// Run modules and event-loop
corry
->
run
();
// Finalize modules (post-run)
corry
->
finali
seAll
();
corry
->
finali
ze
();
}
catch
(
ConfigurationError
&
e
)
{
LOG
(
FATAL
)
<<
"Error in the configuration file:"
<<
std
::
endl
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment