import numpy as np

from .cadence_features import (
    cad_prob,
    delta_t_hist,
    double_to_single_step,
    normalize_hist,
    find_sorted_peaks,
    peak_bin,
    peak_ratio,
)

from .common_functions import (
    maximum,
    median,
    max_slope,
    median_absolute_deviation,
    minimum,
    percent_beyond_1_std,
    percent_close_to_median,
    skew,
    std,
    weighted_average,
)
from .amplitude import (
    amplitude,
    percent_amplitude,
    flux_percentile_ratio,
    percent_difference_flux_percentile,
)
from .qso_model import qso_fit, get_qso_log_chi2_qsonu, get_qso_log_chi2nuNULL_chi2nu
from .stetson import stetson_j, stetson_k

from .lomb_scargle import (
    lomb_scargle_model,
    get_lomb_frequency,
    get_lomb_amplitude,
    get_lomb_rel_phase,
    get_lomb_amplitude_ratio,
    get_lomb_frequency_ratio,
    get_lomb_signif_ratio,
    get_lomb_lambda,
    get_lomb_signif,
    get_lomb_varrat,
    get_lomb_trend,
    get_lomb_y_offset,
)
from .lomb_scargle_fast import lomb_scargle_fast_period
from .num_alias import num_alias
from .periodic_model import (
    periodic_model,
    get_max_delta_mags,
    get_min_delta_mags,
    get_model_phi1_phi2,
)
from .period_folding import (
    period_folding,
    get_fold2P_slope_percentile,
    get_medperc90_2p_p,
    p2p_model,
    get_p2p_scatter_2praw,
    get_p2p_scatter_over_mad,
    get_p2p_scatter_pfold_over_mad,
    get_p2p_ssqr_diff_over_var,
)
from .scatter_res_raw import scatter_res_raw


__all__ = [
    "CADENCE_FEATS",
    "GENERAL_FEATS",
    "LOMB_SCARGLE_FEATS",
    "generate_dask_graph",
    "feature_categories",
    "dask_feature_graph",
]

feature_categories = {
    "Cadence/Error": [
        "n_epochs",
        "avg_err",
        "med_err",
        "std_err",
        "total_time",
        "avgt",
        "cads_std",
        "mean",
        "cads_avg",
        "cads_med",
        "cad_probs_1",
        "cad_probs_10",
        "cad_probs_20",
        "cad_probs_30",
        "cad_probs_40",
        "cad_probs_50",
        "cad_probs_100",
        "cad_probs_500",
        "cad_probs_1000",
        "cad_probs_5000",
        "cad_probs_10000",
        "cad_probs_50000",
        "cad_probs_100000",
        "cad_probs_500000",
        "cad_probs_1000000",
        "cad_probs_5000000",
        "cad_probs_10000000",
        "med_double_to_single_step",
        "avg_double_to_single_step",
        "std_double_to_single_step",
        "all_times_nhist_numpeaks",
        "all_times_nhist_peak_val",
        "all_times_nhist_peak_1_to_2",
        "all_times_nhist_peak_1_to_3",
        "all_times_nhist_peak_2_to_3",
        "all_times_nhist_peak_1_to_4",
        "all_times_nhist_peak_2_to_4",
        "all_times_nhist_peak_3_to_4",
        "all_times_nhist_peak1_bin",
        "all_times_nhist_peak2_bin",
        "all_times_nhist_peak3_bin",
        "all_times_nhist_peak4_bin",
    ],
    "General": [
        "amplitude",
        "flux_percentile_ratio_mid20",
        "flux_percentile_ratio_mid35",
        "flux_percentile_ratio_mid50",
        "flux_percentile_ratio_mid65",
        "flux_percentile_ratio_mid80",
        "max_slope",
        "maximum",
        "median",
        "median_absolute_deviation",
        "minimum",
        "percent_amplitude",
        "percent_beyond_1_std",
        "percent_close_to_median",
        "percent_difference_flux_percentile",
        "period_fast",
        "qso_log_chi2_qsonu",
        "qso_log_chi2nuNULL_chi2nu",
        "skew",
        "std",
        "stetson_j",
        "stetson_k",
        "weighted_average",
    ],
    "Lomb-Scargle (Periodic)": [
        "fold2P_slope_10percentile",
        "fold2P_slope_90percentile",
        "freq1_amplitude1",
        "freq1_amplitude2",
        "freq1_amplitude3",
        "freq1_amplitude4",
        "freq1_freq",
        "freq1_lambda",
        "freq1_rel_phase2",
        "freq1_rel_phase3",
        "freq1_rel_phase4",
        "freq1_signif",
        "freq2_amplitude1",
        "freq2_amplitude2",
        "freq2_amplitude3",
        "freq2_amplitude4",
        "freq2_freq",
        "freq2_rel_phase2",
        "freq2_rel_phase3",
        "freq2_rel_phase4",
        "freq3_amplitude1",
        "freq3_amplitude2",
        "freq3_amplitude3",
        "freq3_amplitude4",
        "freq3_freq",
        "freq3_rel_phase2",
        "freq3_rel_phase3",
        "freq3_rel_phase4",
        "freq_amplitude_ratio_21",
        "freq_amplitude_ratio_31",
        "freq_frequency_ratio_21",
        "freq_frequency_ratio_31",
        "freq_model_max_delta_mags",
        "freq_model_min_delta_mags",
        "freq_model_phi1_phi2",
        "freq_n_alias",
        "freq_signif_ratio_21",
        "freq_signif_ratio_31",
        "freq_varrat",
        "freq_y_offset",
        "linear_trend",
        "medperc90_2p_p",
        "p2p_scatter_2praw",
        "p2p_scatter_over_mad",
        "p2p_scatter_pfold_over_mad",
        "p2p_ssqr_diff_over_var",
        "scatter_res_raw",
    ],
}

CADENCE_FEATS = feature_categories["Cadence/Error"]
GENERAL_FEATS = feature_categories["General"]
LOMB_SCARGLE_FEATS = feature_categories["Lomb-Scargle (Periodic)"]


# See http://dask.pydata.org/en/latest/custom-graphs.html

dask_feature_graph = {
    "n_epochs": (len, "t"),
    "avg_err": (np.mean, "e"),
    "med_err": (np.median, "e"),
    "std_err": (np.std, "e"),
    "total_time": (lambda x: np.max(x) - np.min(x), "t"),
    "avgt": (np.mean, "t"),
    "cads": (np.diff, "t"),
    "cads_std": (np.std, "cads"),
    "mean": (np.mean, "m"),
    "cads_avg": (np.mean, "cads"),
    "cads_med": (np.median, "cads"),
    "cad_probs_1": (cad_prob, "cads", 1),
    "cad_probs_10": (cad_prob, "cads", 10),
    "cad_probs_20": (cad_prob, "cads", 20),
    "cad_probs_30": (cad_prob, "cads", 30),
    "cad_probs_40": (cad_prob, "cads", 40),
    "cad_probs_50": (cad_prob, "cads", 50),
    "cad_probs_100": (cad_prob, "cads", 100),
    "cad_probs_500": (cad_prob, "cads", 500),
    "cad_probs_1000": (cad_prob, "cads", 1000),
    "cad_probs_5000": (cad_prob, "cads", 5000),
    "cad_probs_10000": (cad_prob, "cads", 10000),
    "cad_probs_50000": (cad_prob, "cads", 50000),
    "cad_probs_100000": (cad_prob, "cads", 100000),
    "cad_probs_500000": (cad_prob, "cads", 500000),
    "cad_probs_1000000": (cad_prob, "cads", 1000000),
    "cad_probs_5000000": (cad_prob, "cads", 5000000),
    "cad_probs_10000000": (cad_prob, "cads", 10000000),
    "double_to_single_step": (double_to_single_step, "cads"),
    "avg_double_to_single_step": (np.mean, "double_to_single_step"),
    "med_double_to_single_step": (np.median, "double_to_single_step"),
    "std_double_to_single_step": (np.std, "double_to_single_step"),
    "delta_t_hist": (delta_t_hist, "t"),
    "delta_t_nhist": (normalize_hist, "delta_t_hist", "total_time"),
    "nhist_peaks": (find_sorted_peaks, "delta_t_nhist"),
    "all_times_nhist_numpeaks": (len, "nhist_peaks"),
    "all_times_nhist_peak_val": (np.max, "delta_t_nhist"),
    "all_times_nhist_peak_1_to_2": (peak_ratio, "nhist_peaks", 1, 2),
    "all_times_nhist_peak_1_to_3": (peak_ratio, "nhist_peaks", 1, 3),
    "all_times_nhist_peak_2_to_3": (peak_ratio, "nhist_peaks", 2, 3),
    "all_times_nhist_peak_1_to_4": (peak_ratio, "nhist_peaks", 1, 4),
    "all_times_nhist_peak_2_to_4": (peak_ratio, "nhist_peaks", 2, 4),
    "all_times_nhist_peak_3_to_4": (peak_ratio, "nhist_peaks", 3, 4),
    "all_times_nhist_peak1_bin": (peak_bin, "nhist_peaks", 1),
    "all_times_nhist_peak2_bin": (peak_bin, "nhist_peaks", 2),
    "all_times_nhist_peak3_bin": (peak_bin, "nhist_peaks", 3),
    "all_times_nhist_peak4_bin": (peak_bin, "nhist_peaks", 4),
    # Standalone features (disconnected nodes)
    "amplitude": (amplitude, "m"),
    "flux_percentile_ratio_mid20": (flux_percentile_ratio, "m", 20),
    "flux_percentile_ratio_mid35": (flux_percentile_ratio, "m", 35),
    "flux_percentile_ratio_mid50": (flux_percentile_ratio, "m", 50),
    "flux_percentile_ratio_mid65": (flux_percentile_ratio, "m", 65),
    "flux_percentile_ratio_mid80": (flux_percentile_ratio, "m", 80),
    "maximum": (maximum, "m"),
    "max_slope": (max_slope, "t", "m"),
    "median": (median, "m"),
    "median_absolute_deviation": (median_absolute_deviation, "m"),
    "minimum": (minimum, "m"),
    "percent_amplitude": (percent_amplitude, "m"),
    "percent_beyond_1_std": (percent_beyond_1_std, "m", "e"),
    "percent_close_to_median": (percent_close_to_median, "m"),
    "percent_difference_flux_percentile": (percent_difference_flux_percentile, "m"),
    "skew": (skew, "m"),
    "std": (std, "m"),
    "stetson_j": (stetson_j, "m"),
    "stetson_k": (stetson_k, "m"),
    "weighted_average": (weighted_average, "m", "e"),
    # QSO model features
    "qso_model": (qso_fit, "t", "m", "e"),
    "qso_log_chi2_qsonu": (get_qso_log_chi2_qsonu, "qso_model"),
    "qso_log_chi2nuNULL_chi2nu": (get_qso_log_chi2nuNULL_chi2nu, "qso_model"),
    # Fast Lomb-Scargle from Gatspy
    "period_fast": (lomb_scargle_fast_period, "t", "m", "e"),
    "_lomb_model": (lomb_scargle_model, "t", "m", "e"),
    # These could easily be programmatically generated, but this is more readable
    "freq1_freq": (get_lomb_frequency, "_lomb_model", 1),
    "freq2_freq": (get_lomb_frequency, "_lomb_model", 2),
    "freq3_freq": (get_lomb_frequency, "_lomb_model", 3),
    "freq1_amplitude1": (get_lomb_amplitude, "_lomb_model", 1, 1),
    "freq1_amplitude2": (get_lomb_amplitude, "_lomb_model", 1, 2),
    "freq1_amplitude3": (get_lomb_amplitude, "_lomb_model", 1, 3),
    "freq1_amplitude4": (get_lomb_amplitude, "_lomb_model", 1, 4),
    "freq2_amplitude1": (get_lomb_amplitude, "_lomb_model", 2, 1),
    "freq2_amplitude2": (get_lomb_amplitude, "_lomb_model", 2, 2),
    "freq2_amplitude3": (get_lomb_amplitude, "_lomb_model", 2, 3),
    "freq2_amplitude4": (get_lomb_amplitude, "_lomb_model", 2, 4),
    "freq3_amplitude1": (get_lomb_amplitude, "_lomb_model", 3, 1),
    "freq3_amplitude2": (get_lomb_amplitude, "_lomb_model", 3, 2),
    "freq3_amplitude3": (get_lomb_amplitude, "_lomb_model", 3, 3),
    "freq3_amplitude4": (get_lomb_amplitude, "_lomb_model", 3, 4),
    #        'freq1_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 1, 1),
    "freq1_rel_phase2": (get_lomb_rel_phase, "_lomb_model", 1, 2),
    "freq1_rel_phase3": (get_lomb_rel_phase, "_lomb_model", 1, 3),
    "freq1_rel_phase4": (get_lomb_rel_phase, "_lomb_model", 1, 4),
    #        'freq2_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 2, 1),
    "freq2_rel_phase2": (get_lomb_rel_phase, "_lomb_model", 2, 2),
    "freq2_rel_phase3": (get_lomb_rel_phase, "_lomb_model", 2, 3),
    "freq2_rel_phase4": (get_lomb_rel_phase, "_lomb_model", 2, 4),
    #        'freq3_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 3, 1),
    "freq3_rel_phase2": (get_lomb_rel_phase, "_lomb_model", 3, 2),
    "freq3_rel_phase3": (get_lomb_rel_phase, "_lomb_model", 3, 3),
    "freq3_rel_phase4": (get_lomb_rel_phase, "_lomb_model", 3, 4),
    "freq_amplitude_ratio_21": (get_lomb_amplitude_ratio, "_lomb_model", 2),
    "freq_amplitude_ratio_31": (get_lomb_amplitude_ratio, "_lomb_model", 3),
    "freq_frequency_ratio_21": (get_lomb_frequency_ratio, "_lomb_model", 2),
    "freq_frequency_ratio_31": (get_lomb_frequency_ratio, "_lomb_model", 3),
    "freq_signif_ratio_21": (get_lomb_signif_ratio, "_lomb_model", 2),
    "freq_signif_ratio_31": (get_lomb_signif_ratio, "_lomb_model", 3),
    "freq1_lambda": (get_lomb_lambda, "_lomb_model"),
    "freq1_signif": (get_lomb_signif, "_lomb_model"),
    "freq_varrat": (get_lomb_varrat, "_lomb_model"),
    "linear_trend": (get_lomb_trend, "_lomb_model"),
    "freq_y_offset": (get_lomb_y_offset, "_lomb_model"),
    # Other features that operate on Lomb-Scargle residuals
    "freq_n_alias": (num_alias, "_lomb_model"),
    "scatter_res_raw": (scatter_res_raw, "t", "m", "e", "_lomb_model"),
    "_periodic_model": (periodic_model, "_lomb_model"),
    "_period_folded_model": (period_folding, "t", "m", "e", "_lomb_model"),
    "freq_model_max_delta_mags": (get_max_delta_mags, "_periodic_model"),
    "freq_model_min_delta_mags": (get_min_delta_mags, "_periodic_model"),
    "freq_model_phi1_phi2": (get_model_phi1_phi2, "_periodic_model"),
    "fold2P_slope_10percentile": (
        get_fold2P_slope_percentile,
        "_period_folded_model",
        10,
    ),
    "fold2P_slope_90percentile": (
        get_fold2P_slope_percentile,
        "_period_folded_model",
        90,
    ),
    "medperc90_2p_p": (get_medperc90_2p_p, "_period_folded_model"),
    "_p2p_model": (p2p_model, "t", "m", "freq1_freq"),
    "p2p_scatter_2praw": (get_p2p_scatter_2praw, "_p2p_model"),
    "p2p_scatter_over_mad": (get_p2p_scatter_over_mad, "_p2p_model"),
    "p2p_scatter_pfold_over_mad": (get_p2p_scatter_pfold_over_mad, "_p2p_model"),
    "p2p_ssqr_diff_over_var": (get_p2p_ssqr_diff_over_var, "_p2p_model"),
}


def generate_dask_graph(t, m, e):
    full_graph = {"t": t, "m": m, "e": e}
    full_graph.update(dask_feature_graph)
    return full_graph


extra_feature_docs = {
    "n_epochs": "Total number of observed values.",
    "avg_err": "Mean of the error estimates.",
    "med_err": "Median of error estimates.",
    "std_err": "Standard deviation of the error estimates.",
    "total_time": "Absolute difference between max and min of time values.",
    "avgt": "Mean of the time values.",
    "mean": "Mean of observed values.",
    "cads": "List of differences between successive time values (`np.diff(t)`).",
    "cads_std": "Standard deviation of `cads` (discrete difference between times).",
    "cads_avg": "Mean value of `cads` (discrete difference between times).",
    "cads_med": "Median value of `cads` (discrete difference between times).",
    "avg_double_to_single_step": "Mean value of ratios (t[i+2] - t[i]) / (t[i+2] - t[i+1]).",
    "med_double_to_single_step": "Median value of ratios (t[i+2] - t[i]) / (t[i+2] - t[i+1]).",
    "std_double_to_single_step": "Standard deviation of ratios (t[i+2] - t[i]) / (t[i+2] - t[i+1]).",
    "all_times_nhist_numpeaks": "Number of peaks (local maxima) in histogram of all possible delta_t's.",
    "all_times_nhist_peak_val": "Peak value in histogram of all possible delta_t's.",
}


feature_tags = {
    "n_epochs": ["Astronomy", "General"],
    "avg_err": ["Astronomy", "Error", "General"],
    "med_err": ["Astronomy", "Error", "General"],
    "std_err": ["Astronomy", "Error", "General"],
    "total_time": ["Astronomy", "General"],
    "avgt": ["Astronomy", "General"],
    "cads": ["Astronomy", "General", "Cadence"],
    "cads_std": ["Astronomy", "General", "Cadence"],
    "mean": ["Astronomy", "General"],
    "cads_avg": ["Astronomy", "General", "Cadence"],
    "cads_med": ["Astronomy", "General", "Cadence"],
    "cad_probs_1": ["Astronomy", "General", "Cadence"],
    "cad_probs_10": ["Astronomy", "General", "Cadence"],
    "cad_probs_20": ["Astronomy", "General", "Cadence"],
    "cad_probs_30": ["Astronomy", "General", "Cadence"],
    "cad_probs_40": ["Astronomy", "General", "Cadence"],
    "cad_probs_50": ["Astronomy", "General", "Cadence"],
    "cad_probs_100": ["Astronomy", "General", "Cadence"],
    "cad_probs_500": ["Astronomy", "General", "Cadence"],
    "cad_probs_1000": ["Astronomy", "General", "Cadence"],
    "cad_probs_5000": ["Astronomy", "General", "Cadence"],
    "cad_probs_10000": ["Astronomy", "General", "Cadence"],
    "cad_probs_50000": ["Astronomy", "General", "Cadence"],
    "cad_probs_100000": ["Astronomy", "General", "Cadence"],
    "cad_probs_500000": ["Astronomy", "General", "Cadence"],
    "cad_probs_1000000": ["Astronomy", "General", "Cadence"],
    "cad_probs_5000000": ["Astronomy", "General", "Cadence"],
    "cad_probs_10000000": ["Astronomy", "General", "Cadence"],
    "double_to_single_step": ["Astronomy", "General", "Cadence"],
    "avg_double_to_single_step": ["Astronomy", "General", "Cadence"],
    "med_double_to_single_step": ["Astronomy", "General", "Cadence"],
    "std_double_to_single_step": ["Astronomy", "General", "Cadence"],
    "delta_t_hist": ["Astronomy", "General", "Cadence"],
    "delta_t_nhist": ["Astronomy", "General", "Cadence"],
    "nhist_peaks": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_numpeaks": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_val": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_1_to_2": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_1_to_3": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_2_to_3": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_1_to_4": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_2_to_4": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak_3_to_4": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak1_bin": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak2_bin": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak3_bin": ["Astronomy", "General", "Cadence"],
    "all_times_nhist_peak4_bin": ["Astronomy", "General", "Cadence"],
    # Standalone features (disconnected nodes)
    "amplitude": ["Astronomy", "General"],
    "flux_percentile_ratio_mid20": ["Astronomy"],
    "flux_percentile_ratio_mid35": ["Astronomy"],
    "flux_percentile_ratio_mid50": ["Astronomy"],
    "flux_percentile_ratio_mid65": ["Astronomy"],
    "flux_percentile_ratio_mid80": ["Astronomy"],
    "maximum": ["Astronomy", "General"],
    "max_slope": ["Astronomy", "General"],
    "median": ["Astronomy", "General"],
    "median_absolute_deviation": ["Astronomy", "General"],
    "minimum": ["Astronomy", "General"],
    "percent_amplitude": ["Astronomy", "General"],
    "percent_beyond_1_std": ["Astronomy", "General"],
    "percent_close_to_median": ["Astronomy", "General"],
    "percent_difference_flux_percentile": ["Astronomy", "General"],
    "skew": ["Astronomy", "General"],
    "std": ["Astronomy", "General"],
    "stetson_j": ["Astronomy", "General"],
    "stetson_k": ["Astronomy", "General"],
    "weighted_average": ["Astronomy", "General"],
    # QSO model features
    "qso_model": ["Astronomy"],
    "qso_log_chi2_qsonu": ["Astronomy"],
    "qso_log_chi2nuNULL_chi2nu": ["Astronomy"],
    # Fast Lomb-Scargle from Gatspy
    "period_fast": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "_lomb_model": ["Astronomy", "Periodic", "Lomb-Scargle"],
    # These could easily be programmatically generated, but this is more readable
    "freq1_freq": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_freq": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_freq": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_amplitude1": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_amplitude2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_amplitude3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_amplitude4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_amplitude1": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_amplitude2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_amplitude3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_amplitude4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_amplitude1": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_amplitude2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_amplitude3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_amplitude4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    #        'freq1_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 1, 1),
    "freq1_rel_phase2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_rel_phase3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_rel_phase4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    #        'freq2_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 2, 1),
    "freq2_rel_phase2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_rel_phase3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq2_rel_phase4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    #        'freq3_rel_phase1': (get_lomb_rel_phase, 'lomb_model', 3, 1),
    "freq3_rel_phase2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_rel_phase3": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq3_rel_phase4": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_amplitude_ratio_21": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_amplitude_ratio_31": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_frequency_ratio_21": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_frequency_ratio_31": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_signif_ratio_21": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_signif_ratio_31": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_lambda": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq1_signif": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_varrat": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "linear_trend": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_y_offset": ["Astronomy", "Periodic", "Lomb-Scargle"],
    # Other features that operate on Lomb-Scargle residuals
    "freq_n_alias": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "scatter_res_raw": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "_periodic_model": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "_period_folded_model": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_model_max_delta_mags": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_model_min_delta_mags": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "freq_model_phi1_phi2": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "fold2P_slope_10percentile": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "fold2P_slope_90percentile": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "medperc90_2p_p": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "_p2p_model": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "p2p_scatter_2praw": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "p2p_scatter_over_mad": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "p2p_scatter_pfold_over_mad": ["Astronomy", "Periodic", "Lomb-Scargle"],
    "p2p_ssqr_diff_over_var": ["Astronomy", "Periodic", "Lomb-Scargle"],
}
