|
|
from dataclasses import dataclass, field |
|
|
from enum import Enum |
|
|
|
|
|
import numpy as np |
|
|
|
|
|
from src.data.frequency import Frequency |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class GeneratorParams: |
|
|
"""Base class for generator parameters.""" |
|
|
|
|
|
global_seed: int = 42 |
|
|
length: int = 2048 |
|
|
frequency: list[Frequency] | None = None |
|
|
start: list[np.datetime64] | None = None |
|
|
|
|
|
def update(self, **kwargs): |
|
|
"""Update parameters from keyword arguments.""" |
|
|
for k, v in kwargs.items(): |
|
|
if hasattr(self, k): |
|
|
setattr(self, k, v) |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class ForecastPFNGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the ForecastPFNGenerator.""" |
|
|
|
|
|
trend_exp: bool = True |
|
|
scale_noise: tuple[float, float] = (0.6, 0.3) |
|
|
harmonic_scale_ratio: float = 0.5 |
|
|
harmonic_rate: float = 1.0 |
|
|
period_factor: float = 1.0 |
|
|
seasonal_only: bool = False |
|
|
trend_additional: bool = True |
|
|
transition_ratio: float = 1.0 |
|
|
random_walk: bool = False |
|
|
|
|
|
|
|
|
mixup_prob: float = 0.1 |
|
|
mixup_series: int = 4 |
|
|
damp_and_spike: bool = False |
|
|
damping_noise_ratio: float = 0.05 |
|
|
spike_noise_ratio: float = 0.05 |
|
|
spike_signal_ratio: float = 0.05 |
|
|
spike_batch_ratio: float = 0.05 |
|
|
|
|
|
|
|
|
time_warp_prob: float = 0.1 |
|
|
time_warp_strength: float = 0.05 |
|
|
magnitude_scale_prob: float = 0.2 |
|
|
magnitude_scale_range: tuple[float, float] = ( |
|
|
0.9, |
|
|
1.1, |
|
|
) |
|
|
damping_prob: float = 0.1 |
|
|
spike_prob: float = 0.15 |
|
|
pure_spike_prob: float = 0.02 |
|
|
|
|
|
|
|
|
max_absolute_spread: float = 300.0 |
|
|
max_absolute_value: float = 300.0 |
|
|
max_retries: int = 10 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class GPGeneratorParams(GeneratorParams): |
|
|
""" |
|
|
Parameters for the Gaussian Process (GP) Prior synthetic data generator. |
|
|
""" |
|
|
|
|
|
max_kernels: int = 6 |
|
|
likelihood_noise_level: float = 0.1 |
|
|
noise_level: str = "low" |
|
|
use_original_gp: bool = False |
|
|
gaussians_periodic: bool = True |
|
|
peak_spike_ratio: float = 0.1 |
|
|
subfreq_ratio: float = 0.2 |
|
|
periods_per_freq: float = 0.5 |
|
|
gaussian_sampling_ratio: float = 0.2 |
|
|
max_period_ratio: float = 0.5 |
|
|
kernel_periods: tuple[int, ...] = (4, 5, 7, 21, 24, 30, 60, 120) |
|
|
kernel_bank: dict[str, float] = field( |
|
|
default_factory=lambda: { |
|
|
"matern_kernel": 1.5, |
|
|
"linear_kernel": 1.0, |
|
|
"periodic_kernel": 5.0, |
|
|
"polynomial_kernel": 0.0, |
|
|
"spectral_mixture_kernel": 0.0, |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class KernelGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the KernelSynthGenerator.""" |
|
|
|
|
|
max_kernels: int = 5 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class SineWaveGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the SineWaveGenerator - focused on diverse sinusoidal patterns.""" |
|
|
|
|
|
|
|
|
num_components_range: tuple[int, int] = (1, 3) |
|
|
period_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = (10.0, 200.0) |
|
|
amplitude_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = (0.5, 3.0) |
|
|
phase_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = (0.0, 2.0 * np.pi) |
|
|
|
|
|
|
|
|
trend_slope_range: tuple[float, float] = (-0.01, 0.01) |
|
|
base_level_range: tuple[float, float] = (0.0, 2.0) |
|
|
|
|
|
|
|
|
noise_probability: float = 0.7 |
|
|
noise_level_range: tuple[float, float] = ( |
|
|
0.05, |
|
|
0.2, |
|
|
) |
|
|
|
|
|
|
|
|
enable_amplitude_modulation: bool = True |
|
|
amplitude_modulation_strength: float = 0.1 |
|
|
enable_frequency_modulation: bool = True |
|
|
frequency_modulation_strength: float = 0.05 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class SawToothGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the SawToothGenerator.""" |
|
|
|
|
|
periods: tuple[int, int] = (2, 7) |
|
|
amplitude_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = (0.5, 3.0) |
|
|
phase_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = ( |
|
|
0.0, |
|
|
1.0, |
|
|
) |
|
|
trend_slope_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = ( |
|
|
-0.001, |
|
|
0.001, |
|
|
) |
|
|
seasonality_amplitude_range: tuple[float, float] | tuple[tuple[float, float], tuple[float, float]] = ( |
|
|
0.0, |
|
|
0.02, |
|
|
) |
|
|
add_trend: bool = True |
|
|
add_seasonality: bool = True |
|
|
|
|
|
|
|
|
class StepPatternType(Enum): |
|
|
"""Types of step patterns that can be generated.""" |
|
|
|
|
|
STABLE = "stable" |
|
|
GRADUAL_INCREASE = "gradual_increase" |
|
|
GRADUAL_DECREASE = "gradual_decrease" |
|
|
SPIKE_UP = "spike_up" |
|
|
SPIKE_DOWN = "spike_down" |
|
|
OSCILLATING = "oscillating" |
|
|
RANDOM_WALK = "random_walk" |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class SubseriesConfig: |
|
|
"""Configuration for a single subseries pattern.""" |
|
|
|
|
|
pattern_type: StepPatternType |
|
|
length_range: tuple[int, int] |
|
|
num_changepoints_range: tuple[int, int] |
|
|
step_size_range: tuple[float, float] |
|
|
level_drift_range: tuple[float, float] = (0.0, 0.0) |
|
|
step_size_decay: float = 1.0 |
|
|
weight: float = 1.0 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class StepGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the StepGenerator with subseries support.""" |
|
|
|
|
|
|
|
|
subseries_configs: list[SubseriesConfig] = field( |
|
|
default_factory=lambda: [ |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.STABLE, |
|
|
length_range=(200, 600), |
|
|
num_changepoints_range=(0, 3), |
|
|
step_size_range=(-1.0, 1.0), |
|
|
weight=0.8, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.GRADUAL_INCREASE, |
|
|
length_range=(300, 700), |
|
|
num_changepoints_range=(5, 15), |
|
|
step_size_range=(1.0, 5.0), |
|
|
level_drift_range=(0.0, 0.1), |
|
|
weight=0.6, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.GRADUAL_DECREASE, |
|
|
length_range=(300, 700), |
|
|
num_changepoints_range=(5, 15), |
|
|
step_size_range=(-5.0, -1.0), |
|
|
level_drift_range=(-0.1, 0.0), |
|
|
weight=0.6, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.SPIKE_UP, |
|
|
length_range=(200, 500), |
|
|
num_changepoints_range=(3, 8), |
|
|
step_size_range=(3.0, 10.0), |
|
|
step_size_decay=0.7, |
|
|
weight=0.4, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.SPIKE_DOWN, |
|
|
length_range=(200, 500), |
|
|
num_changepoints_range=(3, 8), |
|
|
step_size_range=(-10.0, -3.0), |
|
|
step_size_decay=0.7, |
|
|
weight=0.4, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.OSCILLATING, |
|
|
length_range=(400, 800), |
|
|
num_changepoints_range=(8, 20), |
|
|
step_size_range=(-4.0, 4.0), |
|
|
weight=0.3, |
|
|
), |
|
|
|
|
|
SubseriesConfig( |
|
|
pattern_type=StepPatternType.RANDOM_WALK, |
|
|
length_range=(100, 400), |
|
|
num_changepoints_range=(5, 20), |
|
|
step_size_range=(-3.0, 3.0), |
|
|
weight=0.2, |
|
|
), |
|
|
] |
|
|
) |
|
|
|
|
|
|
|
|
min_subseries: int = 10 |
|
|
max_subseries: int = 100 |
|
|
|
|
|
|
|
|
enable_smooth_transitions: bool = False |
|
|
transition_length: int = 5 |
|
|
|
|
|
|
|
|
base_level_range: tuple[float, float] = (5.0, 15.0) |
|
|
noise_level_range: tuple[float, float] = (0.001, 0.01) |
|
|
|
|
|
|
|
|
add_seasonality: bool = True |
|
|
daily_seasonality_amplitude_range: tuple[float, float] = (0.0, 0.8) |
|
|
weekly_seasonality_amplitude_range: tuple[float, float] = (0.0, 0.7) |
|
|
|
|
|
|
|
|
add_trend: bool = False |
|
|
trend_slope_range: tuple[float, float] = (-0.005, 0.005) |
|
|
|
|
|
|
|
|
scale_range: tuple[float, float] = (0.1, 10.0) |
|
|
|
|
|
|
|
|
inject_anomalies: bool = False |
|
|
anomaly_probability: float = 0.02 |
|
|
anomaly_magnitude_range: tuple[float, float] = (2.0, 5.0) |
|
|
|
|
|
|
|
|
maintain_level_continuity: bool = True |
|
|
max_level_jump_between_subseries: float = 5.0 |
|
|
|
|
|
|
|
|
class AnomalyType(Enum): |
|
|
"""Types of anomalies that can be generated.""" |
|
|
|
|
|
SPIKE_UP = "spike_up" |
|
|
SPIKE_DOWN = "spike_down" |
|
|
|
|
|
|
|
|
class MagnitudePattern(Enum): |
|
|
"""Spike magnitude patterns.""" |
|
|
|
|
|
CONSTANT = "constant" |
|
|
INCREASING = "increasing" |
|
|
DECREASING = "decreasing" |
|
|
CYCLICAL = "cyclical" |
|
|
RANDOM_BOUNDED = "random_bounded" |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class AnomalyGeneratorParams(GeneratorParams): |
|
|
"""Parameters for anomaly time series generation.""" |
|
|
|
|
|
|
|
|
base_level_range: tuple[float, float] = (-100.0, 100.0) |
|
|
|
|
|
|
|
|
spike_direction_probability: float = 0.5 |
|
|
|
|
|
|
|
|
base_period_range: tuple[int, int] = (100, 300) |
|
|
period_variance: float = 0.0 |
|
|
|
|
|
|
|
|
cluster_series_probability: float = 0.25 |
|
|
random_series_probability: float = 0.25 |
|
|
|
|
|
|
|
|
|
|
|
cluster_event_fraction: float = 0.3 |
|
|
|
|
|
cluster_additional_spikes_range: tuple[int, int] = (1, 4) |
|
|
|
|
|
cluster_offset_range: tuple[int, int] = (-10, 11) |
|
|
|
|
|
|
|
|
|
|
|
random_spike_fraction_of_base: float = 0.3 |
|
|
|
|
|
|
|
|
magnitude_pattern: MagnitudePattern = MagnitudePattern.RANDOM_BOUNDED |
|
|
base_magnitude_range: tuple[float, float] = (10.0, 50.0) |
|
|
magnitude_correlation: float = 0.7 |
|
|
magnitude_trend_strength: float = 0.02 |
|
|
cyclical_period_ratio: float = 0.3 |
|
|
|
|
|
|
|
|
magnitude_noise: float = 0.1 |
|
|
timing_jitter: float = 0.0 |
|
|
|
|
|
def __post_init__(self): |
|
|
"""Validate parameters after initialization.""" |
|
|
if not (0 <= self.spike_direction_probability <= 1): |
|
|
raise ValueError("spike_direction_probability must be between 0 and 1") |
|
|
if not (0 <= self.period_variance <= 0.5): |
|
|
raise ValueError("period_variance must be between 0 and 0.5") |
|
|
if not (0 <= self.magnitude_correlation <= 1): |
|
|
raise ValueError("magnitude_correlation must be between 0 and 1") |
|
|
if self.base_period_range[0] >= self.base_period_range[1]: |
|
|
raise ValueError("base_period_range must have min < max") |
|
|
|
|
|
if not (0.0 <= self.cluster_series_probability <= 1.0): |
|
|
raise ValueError("cluster_series_probability must be between 0 and 1") |
|
|
if not (0.0 <= self.random_series_probability <= 1.0): |
|
|
raise ValueError("random_series_probability must be between 0 and 1") |
|
|
if self.cluster_series_probability + self.random_series_probability > 1.0: |
|
|
raise ValueError("Sum of cluster_series_probability and random_series_probability must be <= 1") |
|
|
|
|
|
if not (0.0 <= self.cluster_event_fraction <= 1.0): |
|
|
raise ValueError("cluster_event_fraction must be between 0 and 1") |
|
|
if self.cluster_additional_spikes_range[0] >= self.cluster_additional_spikes_range[1]: |
|
|
raise ValueError("cluster_additional_spikes_range must have min < max") |
|
|
if self.cluster_offset_range[0] >= self.cluster_offset_range[1]: |
|
|
raise ValueError("cluster_offset_range must have min < max") |
|
|
|
|
|
if not (0.0 <= self.random_spike_fraction_of_base <= 1.0): |
|
|
raise ValueError("random_spike_fraction_of_base must be between 0 and 1") |
|
|
|
|
|
|
|
|
class SpikeShape(Enum): |
|
|
"""Enumeration of spike shapes.""" |
|
|
|
|
|
V_SHAPE = "v" |
|
|
INVERTED_V = "inverted_v" |
|
|
CHOPPED_V = "chopped_v" |
|
|
CHOPPED_INVERTED_V = "chopped_inverted_v" |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class SpikesGeneratorParams(GeneratorParams): |
|
|
"""Parameters for spike time series generation.""" |
|
|
|
|
|
|
|
|
spike_count_burst: tuple[int, int] = (2, 4) |
|
|
spike_count_uniform: tuple[int, int] = (4, 7) |
|
|
|
|
|
|
|
|
spike_amplitude: float | tuple[float, float] = (50.0, 300.0) |
|
|
|
|
|
|
|
|
spike_angle_range: tuple[float, float] = (70.0, 85.0) |
|
|
|
|
|
|
|
|
burst_mode_probability: float = 0.05 |
|
|
|
|
|
|
|
|
plateau_duration: tuple[int, int] = (30, 50) |
|
|
|
|
|
|
|
|
baseline: float | tuple[float, float] = (-200, 200) |
|
|
|
|
|
|
|
|
burst_width_fraction: tuple[float, float] = (0.1, 0.25) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
edge_margin_ratio: float = 0.2 |
|
|
|
|
|
|
|
|
spikes_above_baseline_probability: float = 0.5 |
|
|
|
|
|
|
|
|
series_type_probabilities: dict[str, float] = field( |
|
|
default_factory=lambda: { |
|
|
"v_only": 0.4, |
|
|
"chopped_only": 0.3, |
|
|
"mixed": 0.3, |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
min_spike_width: int = 30 |
|
|
|
|
|
|
|
|
max_spike_width: int = 100 |
|
|
|
|
|
|
|
|
min_spike_margin: int = 10 |
|
|
|
|
|
|
|
|
noise_std: float = 2 |
|
|
noise_probability: float = 0.5 |
|
|
brown_noise_alpha: float = 2.0 |
|
|
noise_cutoff_freq: float = 0.1 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class CauKerGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the CauKer (SCM-GP) generator.""" |
|
|
|
|
|
|
|
|
|
|
|
num_channels: int | tuple[int, int] | list[int] = 6 |
|
|
|
|
|
|
|
|
max_parents: int = 3 |
|
|
|
|
|
|
|
|
num_nodes: int = 6 |
|
|
|
|
|
|
|
|
class TrendType(Enum): |
|
|
"""Types of trends that can be applied to the OU process.""" |
|
|
|
|
|
NONE = "none" |
|
|
LINEAR = "linear" |
|
|
EXPONENTIAL = "exponential" |
|
|
LOGISTIC = "logistic" |
|
|
SINUSOIDAL = "sinusoidal" |
|
|
PIECEWISE_LINEAR = "piecewise_linear" |
|
|
POLYNOMIAL = "polynomial" |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class TrendConfig: |
|
|
"""Configuration for time-varying trends in OU process parameters.""" |
|
|
|
|
|
trend_type: TrendType = TrendType.NONE |
|
|
|
|
|
|
|
|
linear_slope_range: tuple[float, float] = (-0.01, 0.01) |
|
|
|
|
|
|
|
|
exp_rate_range: tuple[float, float] = (-0.005, 0.005) |
|
|
exp_asymptote_range: tuple[float, float] = (-5.0, 5.0) |
|
|
|
|
|
|
|
|
logistic_growth_rate_range: tuple[float, float] = (0.01, 0.1) |
|
|
logistic_capacity_range: tuple[float, float] = (5.0, 20.0) |
|
|
logistic_midpoint_ratio_range: tuple[float, float] = ( |
|
|
0.3, |
|
|
0.7, |
|
|
) |
|
|
|
|
|
|
|
|
sin_amplitude_range: tuple[float, float] = (1.0, 5.0) |
|
|
sin_period_ratio_range: tuple[float, float] = ( |
|
|
0.1, |
|
|
0.5, |
|
|
) |
|
|
sin_phase_range: tuple[float, float] = (0.0, 2.0 * np.pi) |
|
|
|
|
|
|
|
|
num_segments_range: tuple[int, int] = (2, 5) |
|
|
segment_slope_range: tuple[float, float] = (-0.02, 0.02) |
|
|
|
|
|
|
|
|
poly_degree_range: tuple[int, int] = (2, 3) |
|
|
poly_coeff_range: tuple[float, float] = ( |
|
|
-1e-6, |
|
|
1e-6, |
|
|
) |
|
|
|
|
|
|
|
|
enable_structural_changes: bool = True |
|
|
num_structural_changes_range: tuple[int, int] = (0, 3) |
|
|
structural_change_magnitude_range: tuple[float, float] = (1.0, 5.0) |
|
|
min_segment_length: int = 200 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class OrnsteinUhlenbeckProcessGeneratorParams(GeneratorParams): |
|
|
"""Parameters for the Regime-Switching Ornstein-Uhlenbeck generator. |
|
|
|
|
|
The generator samples concrete values per series using these ranges. |
|
|
Enhanced with time-varying parameter support for realistic non-stationary behavior. |
|
|
""" |
|
|
|
|
|
|
|
|
dt: float = 0.01 |
|
|
|
|
|
|
|
|
regime0_theta_range: tuple[float, float] = (1.0, 5.0) |
|
|
regime0_mu_mean_std: tuple[float, float] = (-2.0, 1.0) |
|
|
regime0_sigma_lognormal_params: tuple[float, float] = (float(np.log(0.3)), 0.3) |
|
|
|
|
|
|
|
|
regime0_vol_reversion_range: tuple[float, float] = (2.0, 5.0) |
|
|
regime0_vol_mean_range: tuple[float, float] = (0.2, 0.4) |
|
|
regime0_vol_vol_range: tuple[float, float] = (0.1, 0.3) |
|
|
|
|
|
|
|
|
regime1_theta_range: tuple[float, float] = (0.05, 0.5) |
|
|
regime1_mu_mean_std: tuple[float, float] = (2.0, 1.0) |
|
|
regime1_sigma_lognormal_params: tuple[float, float] = (float(np.log(1.5)), 0.5) |
|
|
|
|
|
|
|
|
regime1_vol_reversion_range: tuple[float, float] = (0.5, 2.0) |
|
|
regime1_vol_mean_range: tuple[float, float] = (0.8, 1.2) |
|
|
regime1_vol_vol_range: tuple[float, float] = (0.3, 0.5) |
|
|
|
|
|
|
|
|
x0_mean_std: tuple[float, float] = (0.0, 2.0) |
|
|
|
|
|
|
|
|
p00_range: tuple[float, float] = (0.85, 0.999) |
|
|
p11_range: tuple[float, float] = (0.85, 0.999) |
|
|
|
|
|
|
|
|
trend_config: TrendConfig = field(default_factory=TrendConfig) |
|
|
|
|
|
|
|
|
mu_trend_probability: float = 0.7 |
|
|
theta_trend_probability: float = 0.2 |
|
|
sigma_trend_probability: float = 0.3 |
|
|
|
|
|
|
|
|
global_level_range: tuple[float, float] = ( |
|
|
-100.0, |
|
|
100.0, |
|
|
) |
|
|
global_scale_range: tuple[float, float] = ( |
|
|
0.1, |
|
|
50.0, |
|
|
) |
|
|
|
|
|
|
|
|
measurement_noise_std_range: tuple[float, float] = ( |
|
|
0.0, |
|
|
0.1, |
|
|
) |
|
|
|
|
|
|
|
|
enable_long_memory: bool = False |
|
|
hurst_exponent_range: tuple[float, float] = ( |
|
|
0.3, |
|
|
0.8, |
|
|
) |
|
|
|
|
|
|
|
|
enable_seasonality: bool = True |
|
|
num_seasonal_components_range: tuple[int, int] = ( |
|
|
1, |
|
|
3, |
|
|
) |
|
|
seasonal_periods: tuple[float, ...] = ( |
|
|
7.0, |
|
|
30.0, |
|
|
90.0, |
|
|
365.25, |
|
|
182.625, |
|
|
) |
|
|
seasonal_amplitude_range: tuple[float, float] = ( |
|
|
0.5, |
|
|
3.0, |
|
|
) |
|
|
seasonal_phase_range: tuple[float, float] = (0.0, 2.0 * np.pi) |
|
|
seasonal_period_jitter: float = 0.05 |
|
|
|
|
|
|
|
|
mu_seasonality_probability: float = 0.6 |
|
|
sigma_seasonality_probability: float = 0.3 |
|
|
|
|
|
|
|
|
enable_seasonal_evolution: bool = True |
|
|
seasonal_amplitude_trend_range: tuple[float, float] = ( |
|
|
-0.001, |
|
|
0.001, |
|
|
) |
|
|
|
|
|
def __post_init__(self): |
|
|
if self.dt <= 0: |
|
|
raise ValueError("dt must be positive for OU process simulation") |
|
|
|
|
|
if not (0.0 <= self.mu_trend_probability <= 1.0): |
|
|
raise ValueError("mu_trend_probability must be between 0 and 1") |
|
|
if not (0.0 <= self.theta_trend_probability <= 1.0): |
|
|
raise ValueError("theta_trend_probability must be between 0 and 1") |
|
|
if not (0.0 <= self.sigma_trend_probability <= 1.0): |
|
|
raise ValueError("sigma_trend_probability must be between 0 and 1") |
|
|
|
|
|
if self.global_level_range[0] >= self.global_level_range[1]: |
|
|
raise ValueError("global_level_range must have min < max") |
|
|
if self.global_scale_range[0] <= 0: |
|
|
raise ValueError("global_scale_range values must be positive") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
class AudioGeneratorParams(GeneratorParams): |
|
|
"""Common parameters for audio-based time series generators (pyo-backed).""" |
|
|
|
|
|
|
|
|
server_duration: float = 2.0 |
|
|
sample_rate: int = 44100 |
|
|
|
|
|
|
|
|
normalize_output: bool = True |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class FinancialVolatilityAudioParams(AudioGeneratorParams): |
|
|
"""Parameters for the FinancialVolatility audio generator.""" |
|
|
|
|
|
|
|
|
trend_lfo_freq_range: tuple[float, float] = (0.1, 0.5) |
|
|
trend_lfo_mul_range: tuple[float, float] = (0.2, 0.5) |
|
|
|
|
|
|
|
|
volatility_carrier_freq_range: tuple[float, float] = (1.0, 5.0) |
|
|
follower_freq_range: tuple[float, float] = (1.0, 4.0) |
|
|
volatility_range: tuple[float, float] = (0.1, 0.8) |
|
|
|
|
|
|
|
|
jump_metro_time_range: tuple[float, float] = (0.3, 1.0) |
|
|
jump_env_start_range: tuple[float, float] = (0.5, 1.0) |
|
|
jump_env_decay_time_range: tuple[float, float] = (0.05, 0.2) |
|
|
jump_freq_range: tuple[float, float] = (20.0, 80.0) |
|
|
jump_direction_up_probability: float = 0.5 |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class MultiScaleFractalAudioParams(AudioGeneratorParams): |
|
|
"""Parameters for the Multi-Scale Fractal audio generator.""" |
|
|
|
|
|
base_noise_mul_range: tuple[float, float] = (0.3, 0.8) |
|
|
num_scales_range: tuple[int, int] = (3, 6) |
|
|
scale_freq_base_range: tuple[float, float] = (20.0, 2000.0) |
|
|
q_factor_range: tuple[float, float] = (0.5, 3.0) |
|
|
per_scale_attenuation_range: tuple[float, float] = ( |
|
|
0.5, |
|
|
0.8, |
|
|
) |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class StochasticRhythmAudioParams(AudioGeneratorParams): |
|
|
"""Parameters for the Stochastic Rhythm audio generator.""" |
|
|
|
|
|
base_tempo_hz_range: tuple[float, float] = (2.0, 8.0) |
|
|
num_layers_range: tuple[int, int] = (3, 5) |
|
|
subdivisions: tuple[int, ...] = (1, 2, 3, 4, 6, 8) |
|
|
attack_range: tuple[float, float] = (0.001, 0.01) |
|
|
decay_range: tuple[float, float] = (0.05, 0.3) |
|
|
tone_freq_range: tuple[float, float] = (50.0, 800.0) |
|
|
tone_mul_range: tuple[float, float] = (0.2, 0.5) |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class NetworkTopologyAudioParams(AudioGeneratorParams): |
|
|
"""Parameters for the Network Topology audio generator.""" |
|
|
|
|
|
|
|
|
traffic_lfo_freq_range: tuple[float, float] = (0.2, 1.0) |
|
|
traffic_lfo_mul_range: tuple[float, float] = (0.2, 0.5) |
|
|
|
|
|
|
|
|
burst_rate_hz_range: tuple[float, float] = (3.0, 12.0) |
|
|
burst_duration_range: tuple[float, float] = (0.02, 0.1) |
|
|
burst_mul_range: tuple[float, float] = (0.2, 0.6) |
|
|
|
|
|
|
|
|
congestion_period_range: tuple[float, float] = (1.0, 3.0) |
|
|
congestion_depth_range: tuple[float, float] = (-0.6, -0.2) |
|
|
congestion_release_time_range: tuple[float, float] = (0.3, 0.8) |
|
|
|
|
|
|
|
|
overhead_lfo_freq_range: tuple[float, float] = (20.0, 50.0) |
|
|
overhead_mul_range: tuple[float, float] = (0.05, 0.15) |
|
|
|
|
|
|
|
|
attack_period_range: tuple[float, float] = (2.0, 5.0) |
|
|
attack_env_points: tuple[tuple[float, float], tuple[float, float], tuple[float, float]] = ( |
|
|
(0.0, 1.2), |
|
|
(0.1, 0.8), |
|
|
(0.8, 0.0), |
|
|
) |
|
|
attack_mul_range: tuple[float, float] = (0.4, 0.8) |
|
|
|