Adding a new analyzer module
Location
Modules for the analyzer are stored in the modules/analyzer/
directory.
Naming convention
Currently every analyzer module is defined in a file with the name fault_analyzer_decorator_MODULE_NAME.py
. The reason is that they are all decorators of the analyzer component defined in fault_analyzer_component.py
.
The class name of the module is define as FaultAnalyzerMODULENAME
.
Loading a module
The modules are loaded in the modules/analyzer/analyzer.py
file, in the init_fault_analyzer()
function.
# modules/analyzer/analyzer.py
def init_fault_analyzer(self, **kwargs):
fa = FaultAnalyzer(self.results, **kwargs)
fa = FaultAnalyzerBase(fa, **kwargs)
if are_all(self.values_type, int):
fa = FaultAnalyzerFaultModel(fa, **kwargs)
if "carto" in kwargs:
if kwargs["carto"]:
fa = FaultAnalyzerCarto(fa, **kwargs)
fa = FaultAnalyzerFaultModelsCarto(fa, **kwargs)
if ("delay_name" in kwargs):
fa = FaultAnalyzerDelay(fa, **kwargs)
return fa
To load a module, it is only needed to import it:
from .fault_analyzer_MODULE_NAME import FaultAnalyzerMODULENAME
and to add the following line to the init_fault_analyzer()
function:
fa = FaultAnalyzerMODULENAME(fa, **kwargs)
**kwargs
is the params
dictionary defined in the parameter file. It is possible to make the loading of a module conditional by adding if
statements.
Developping a module
Inheritance
A module inherit from the FaultAnalyzerDecorator
class defined in the fault_analyzer_decorator
file.
from .fault_analyzer_decorator import FaultAnalyzerDecorator
class FaultAnalyzerMODULENAME(FaultAnalyzerDecorator):
# My module
Constructor
The constructor of a module must have the following prototype:
def __init__(self, comp, **kwargs):
super().__init__(comp, **kwargs)
comp
is the component we want to decorate with the module.kwargs
is a dictionary of parameters.
To extract the wanted parameters from the dictionary, it is recommended to use the init_arg()
function from the modules/analyzer/arg_init.py
file:
from .arg_init import init_arg
def __init__(self, comp, **kwargs):
super().__init__(comp, **kwargs)
self.my_param = init_arg("my_param_name", kwargs)
Then it is recommended to create the results structure. The results is a list of dictionary, each dictionary represent a result computed by the module and has three parameters:
- a title which able to identify the result,
- a data set which stores the result values,
- a set of labels which able to identify the different data sets. For instance:
# Create result set
self.my_result1_set = []
self.my_result2_set = []
# Create a result data
self.my_result_data = []
# Add the result data to the results object
self.results += [{
"title": "My title",
"data": self.my_result_data,
"labels": ["My first label", "My second label"]
}]
Mandatory functions
There are two mandatory functions.
-
analyze(self, ope)
This function is called for every load module. The
ope
parameter is a line from the manip file. It is possible to access to the different fields of this line by callingope["field_name"]
.This function must always call the
super().analyze(ope)
function before doing anything. Otherwise the decorator pattern will not work.For instance:
def analyze(self, ope): super().analyze(ope) self.my_result1_set.append(ope["param1"]) self.my_result2_set.append(ope["param2"])
-
post_analysis(self)
This function is called after the whole analysis process for every module. It is used for setting the actual results once the analysis is done.
This function must always call the
super().post_analysis()
function before doing anything. Otherwise the decorator pattern will not work.For instance:
def post_analysis(self): super().post_analysis() self.my_result_data = [self.my_result1_set, self.my_result2_set]
Template
A template is available in the modules/analyzer/fault_analyzer_decorator_template.py
file:
# modules/analyzer/fault_analyzer_decorator_template.py
from .arg_init import init_arg
# Import the FaultAnalyzerDecorator class for inheritance
from .fault_analyzer_decorator import FaultAnalyzerDecorator
# Create a child class of the FaultAnalyzerDecorator class
class FaultAnalyzerTEMPLATE(FaultAnalyzerDecorator):
def __init__(self, comp, **kwargs):
super().__init__(comp, **kwargs)
# Initialize the parameters you need
self.my_param = init_arg("my_param_name", kwargs)
# Create a result data
self.my_result_data = []
# Add the result data to the results object
self.results += [{
"title": "My title",
"data": self.my_result_data,
"labels": ["My first label", "My second label"]
}]
# Overwrite the analyze method
def analyze(self, ope):
# Call the parent class method
super().analyze(ope)
# Update your data
self.update_data(self.my_result_data)
def update_data(self, data):
pass
def post_analysis(self):
super().post_analysis()
# You can modify the results here