Skip to content

Commit

Permalink
Merge pull request #54 from sintel-dev/interface_pipeline_update
Browse files Browse the repository at this point in the history
Update interface of SigPro w/pipelines and primitives
  • Loading branch information
andyx13 authored Jan 31, 2024
2 parents 6e12f4c + 9ced51d commit 5e16aaa
Show file tree
Hide file tree
Showing 15 changed files with 3,645 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.8']
os: [ubuntu-20.04]
steps:
- uses: actions/checkout@v1
Expand Down
172 changes: 172 additions & 0 deletions sigpro/basic_primitives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
"""Reference class implementations of existing primitives."""
from sigpro import contributing, primitive

# Transformations


class Identity(primitive.AmplitudeTransformation):
"""Identity primitive class."""

def __init__(self):
super().__init__('sigpro.transformations.amplitude.identity.identity')


class PowerSpectrum(primitive.AmplitudeTransformation):
"""PowerSpectrum primitive class."""

def __init__(self):
super().__init__('sigpro.transformations.amplitude.spectrum.power_spectrum')
primitive_spec = contributing._get_primitive_spec('transformation', 'frequency')
self.set_primitive_inputs(primitive_spec['args'])
self.set_primitive_outputs(primitive_spec['output'])


class FFT(primitive.FrequencyTransformation):
"""FFT primitive class."""

def __init__(self):
super().__init__("sigpro.transformations.frequency.fft.fft")


class FFTReal(primitive.FrequencyTransformation):
"""FFTReal primitive class."""

def __init__(self):
super().__init__("sigpro.transformations.frequency.fft.fft_real")


class FrequencyBand(primitive.FrequencyTransformation):
"""
FrequencyBand primitive class.
Filter between a high and low band frequency and return the amplitude values and
frequency values for those.
Args:
low (int): Lower band frequency of filter.
high (int): Higher band frequency of filter.
"""

def __init__(self, low, high):
super().__init__("sigpro.transformations.frequency.band.frequency_band",
init_params={'low': low, 'high': high})
self.set_primitive_inputs([{"name": "amplitude_values", "type": "numpy.ndarray"},
{"name": "frequency_values", "type": "numpy.ndarray"}])
self.set_primitive_outputs([{'name': 'amplitude_values', 'type': "numpy.ndarray"},
{'name': 'frequency_values', 'type': "numpy.ndarray"}])
self.set_fixed_hyperparameters({'low': {'type': 'int'}, 'high': {'type': 'int'}})


class STFT(primitive.FrequencyTimeTransformation):
"""STFT primitive class."""

def __init__(self):
super().__init__('sigpro.transformations.frequency_time.stft.stft')
self.set_primitive_outputs([{"name": "amplitude_values", "type": "numpy.ndarray"},
{"name": "frequency_values", "type": "numpy.ndarray"},
{"name": "time_values", "type": "numpy.ndarray"}])


class STFTReal(primitive.FrequencyTimeTransformation):
"""STFTReal primitive class."""

def __init__(self):
super().__init__('sigpro.transformations.frequency_time.stft.stft_real')
self.set_primitive_outputs([{"name": "real_amplitude_values", "type": "numpy.ndarray"},
{"name": "frequency_values", "type": "numpy.ndarray"},
{"name": "time_values", "type": "numpy.ndarray"}])

# Aggregations


class CrestFactor(primitive.AmplitudeAggregation):
"""CrestFactor primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.crest_factor')
self.set_primitive_outputs([{'name': 'crest_factor_value', 'type': "float"}])


class Kurtosis(primitive.AmplitudeAggregation):
"""
Kurtosis primitive class.
Computes the kurtosis value of the input array. If all values are equal, return
`-3` for Fisher's definition and `0` for Pearson's definition.
Args:
fisher (bool):
If ``True``, Fisher’s definition is used (normal ==> 0.0). If ``False``,
Pearson’s definition is used (normal ==> 3.0). Defaults to ``True``.
bias (bool):
If ``False``, then the calculations are corrected for statistical bias.
Defaults to ``True``.
"""

def __init__(self, fisher=True, bias=True):
super().__init__('sigpro.aggregations.amplitude.statistical.kurtosis',
init_params={'fisher': fisher, 'bias': bias})
self.set_primitive_outputs([{'name': 'kurtosis_value', 'type': "float"}])
self.set_fixed_hyperparameters({'fisher': {'type': 'bool', 'default': True},
'bias': {'type': 'bool', 'default': True}})


class Mean(primitive.AmplitudeAggregation):
"""Mean primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.mean')
self.set_primitive_outputs([{'name': 'mean_value', 'type': "float"}])


class RMS(primitive.AmplitudeAggregation):
"""RMS primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.rms')
self.set_primitive_outputs([{'name': 'rms_value', 'type': "float"}])


class Skew(primitive.AmplitudeAggregation):
"""Skew primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.skew')
self.set_primitive_outputs([{'name': 'skew_value', 'type': "float"}])


class Std(primitive.AmplitudeAggregation):
"""Std primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.std')
self.set_primitive_outputs([{'name': 'std_value', 'type': "float"}])


class Var(primitive.AmplitudeAggregation):
"""Var primitive class."""

def __init__(self):
super().__init__('sigpro.aggregations.amplitude.statistical.var')
self.set_primitive_outputs([{'name': 'var_value', 'type': "float"}])


class BandMean(primitive.FrequencyAggregation):
"""
BandMean primitive class.
Filters between a high and low band and compute the mean value for this specific band.
Args:
min_frequency (int or float):
Band minimum.
max_frequency (int or float):
Band maximum.
"""

def __init__(self, min_frequency, max_frequency):
super().__init__('sigpro.aggregations.frequency.band.band_mean', init_params={
'min_frequency': min_frequency, 'max_frequency': max_frequency})
self.set_fixed_hyperparameters({'min_frequency': {'type': 'float'},
'max_frequency': {'type': 'float'}})
95 changes: 74 additions & 21 deletions sigpro/contributing.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,11 @@ def _write_primitive(primitive_dict, primitive_name, primitives_path, primitives
return primitive_path


def make_primitive(primitive, primitive_type, primitive_subtype,
context_arguments=None, fixed_hyperparameters=None,
tunable_hyperparameters=None, primitive_outputs=None,
primitives_path='sigpro/primitives', primitives_subfolders=True):
"""Create a primitive JSON.
During the JSON creation the primitive function signature is validated to
ensure that it matches the primitive type and subtype implicitly specified
by the primitive name.
Any additional function arguments are also validated to ensure that the
function does actually expect them.
def _make_primitive_dict(primitive, primitive_type, primitive_subtype,
context_arguments=None, fixed_hyperparameters=None,
tunable_hyperparameters=None, primitive_inputs=None,
primitive_outputs=None):
"""Create a primitive dict.
Args:
primitive (str):
Expand All @@ -308,30 +301,27 @@ def make_primitive(primitive, primitive_type, primitive_subtype,
A dictionary containing as key the name of the hyperparameter and as
value a dictionary containing the type and the default value and the
range of values that it can take.
primitive_inputs (list or None):
A list with dictionaries containing the name and type of the input values. If
``None`` default values for those will be used.
primitive_outputs (list or None):
A list with dictionaries containing the name and type of the output values. If
``None`` default values for those will be used.
primitives_path (str):
Path to the root of the primitives folder, in which the primitives JSON will be stored.
Defaults to `sigpro/primitives`.
primitives_subfolders (bool):
Whether to store the primitive JSON in a subfolder tree (``True``) or to use a flat
primitive name (``False``). Defaults to ``True``.
Raises:
ValueError:
If the primitive specification arguments are not valid.
Returns:
str:
Path of the generated JSON file.
dict:
Generated JSON file as a Python dict.
"""
context_arguments = context_arguments or []
fixed_hyperparameters = fixed_hyperparameters or {}
tunable_hyperparameters = tunable_hyperparameters or {}

primitive_spec = _get_primitive_spec(primitive_type, primitive_subtype)
primitive_inputs = primitive_spec['args']
primitive_inputs = primitive_inputs or primitive_spec['args']
primitive_outputs = primitive_outputs or primitive_spec['output']

primitive_function = _import_object(primitive)
Expand Down Expand Up @@ -366,6 +356,69 @@ def make_primitive(primitive, primitive_type, primitive_subtype,
}
}

return primitive_dict

# pylint: disable = too-many-arguments


def make_primitive(primitive, primitive_type, primitive_subtype,
context_arguments=None, fixed_hyperparameters=None,
tunable_hyperparameters=None, primitive_inputs=None,
primitive_outputs=None, primitives_path='sigpro/primitives',
primitives_subfolders=True):
"""Create a primitive JSON.
During the JSON creation the primitive function signature is validated to
ensure that it matches the primitive type and subtype implicitly specified
by the primitive name.
Any additional function arguments are also validated to ensure that the
function does actually expect them.
Args:
primitive (str):
The name of the primitive, the python path including the name of the
module and the name of the function.
primitive_type (str):
Type of primitive.
primitive_subtype (str):
Subtype of the primitive.
context_arguments (list or None):
A list with dictionaries containing the name and type of the context arguments.
fixed_hyperparameters (dict or None):
A dictionary containing as key the name of the hyperparameter and as
value a dictionary containing the type and the default value that it
should take.
tunable_hyperparameters (dict or None):
A dictionary containing as key the name of the hyperparameter and as
value a dictionary containing the type and the default value and the
range of values that it can take.
primitive_inputs (list or None):
A list with dictionaries containing the name and type of the input values. If
``None`` default values for those will be used.
primitive_outputs (list or None):
A list with dictionaries containing the name and type of the output values. If
``None`` default values for those will be used.
primitives_path (str):
Path to the root of the primitives folder, in which the primitives JSON will be stored.
Defaults to `sigpro/primitives`.
primitives_subfolders (bool):
Whether to store the primitive JSON in a subfolder tree (``True``) or to use a flat
primitive name (``False``). Defaults to ``True``.
Raises:
ValueError:
If the primitive specification arguments are not valid.
Returns:
str:
Path of the generated JSON file.
"""
primitive_dict = _make_primitive_dict(primitive, primitive_type, primitive_subtype,
context_arguments, fixed_hyperparameters,
tunable_hyperparameters, primitive_inputs,
primitive_outputs)

return _write_primitive(primitive_dict, primitive, primitives_path, primitives_subfolders)


Expand Down
Loading

0 comments on commit 5e16aaa

Please sign in to comment.