Esempio n. 1
0
def get_values(
    self, unit="SI", is_oneperiod=False, is_antiperiod=False, is_smallestperiod=False
):
    """Returns the vector 'axis' by rebuilding the linspace, symmetries and unit included.
    Parameters
    ----------
    self: DataLinspace
        a DataLinspace object
    unit: str
        requested unit
    is_oneperiod: bool
        return values on a single period
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    Vector of axis values
    """
    initial = self.initial
    if self.number == None:
        final = self.final
        number = (final - initial + self.step) / self.step
    elif self.final == None:
        number = self.number
        final = self.initial + (number - 1) * self.step
    else:
        number = self.number
        final = self.final
    values = linspace(initial, final, int(number), endpoint=self.include_endpoint)

    # Unit conversion
    if unit != "SI" and unit != self.unit:
        values = convert(values, self.unit, unit)

    # Ignore symmetries if fft axis
    if self.name == "freqs" or self.name == "wavenumber":
        is_smallestperiod = True

    # Rebuild symmetries
    if is_smallestperiod:
        return values
    elif is_antiperiod:
        if "antiperiod" in self.symmetries:
            return values
        else:
            raise AxisError("ERROR: axis has no antiperiodicity")
    elif is_oneperiod:
        if "antiperiod" in self.symmetries:
            nper = self.symmetries["antiperiod"]
            self.symmetries["antiperiod"] = 2
            values = rebuild_symmetries_axis(values, self.symmetries)
            self.symmetries["antiperiod"] = nper
            return values
        elif "period" in self.symmetries:
            return values
        else:
            return values
    else:
        values = rebuild_symmetries_axis(values, self.symmetries)
        return values
def get_phase_along(self, *args, unit="SI", is_norm=False, axis_data=[]):
    """Returns the ndarray of the magnitude of the FT, using conversions and symmetries if needed.
    Parameters
    ----------
    self: Data
        a Data object
    *args: list of strings
        List of axes requested by the user, their units and values (optional)
    unit: str
        Unit requested by the user ("SI" by default)
    is_norm: bool
        Boolean indicating if the field must be normalized (False by default)
    axis_data: list
        list of ndarray corresponding to user-input data
    Returns
    -------
    list of 1Darray of axes values, ndarray of magnitude values
    """
    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args
    return_dict = self.get_along(args, axis_data=axis_data)
    values = return_dict[self.symbol]
    # Compute magnitude
    values = np_angle(values)
    # Convert into right unit (apart because of degree conversion)
    if unit == self.unit or unit == "SI":
        if is_norm:
            try:
                values = values / self.normalizations.get("ref")
            except:
                raise NormError(
                    "ERROR: Reference value not specified for normalization"
                )
    elif unit == "°":
        values = convert(values, "rad", "°")
    elif unit in self.normalizations:
        values = values / self.normalizations.get(unit)
    else:
        values = convert(values, self.unit, unit)
    return_dict[self.symbol] = values
    return return_dict
Esempio n. 3
0
def get_values(self,
               unit="SI",
               is_oneperiod=False,
               is_antiperiod=False,
               is_smallestperiod=False):
    """Returns the vector 'axis' taking symmetries into account.
    Parameters
    ----------
    self: Data1D
        a Data1D object
    unit: str
        requested unit
    is_oneperiod: bool
        return values on a single period
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    Vector of axis values
    """
    values = self.values

    # Unit conversion
    if unit != "SI" and unit != self.unit:
        values = convert(values, self.unit, unit)

    # Ignore symmetries if fft axis
    if self.name == "freqs" or self.name == "wavenumber":
        is_smallestperiod = True

    # Rebuild symmetries
    if is_smallestperiod:
        return values
    elif is_antiperiod:
        if "antiperiod" in self.symmetries:
            return values
        else:
            raise AxisError("ERROR: axis has no antiperiodicity")
    elif is_oneperiod:
        if "antiperiod" in self.symmetries:
            nper = self.symmetries["antiperiod"]
            self.symmetries["antiperiod"] = 2
            values = rebuild_symmetries_axis(values, self.symmetries)
            self.symmetries["antiperiod"] = nper
            return values
        elif "period" in self.symmetries:
            return values
        else:
            return values
    else:
        values = rebuild_symmetries_axis(values, self.symmetries)
        return values
def get_magnitude_along(self, *args, unit="SI", is_norm=False, axis_data=[]):
    """Returns the ndarray of the magnitude of the FT, using conversions and symmetries if needed.
    Parameters
    ----------
    self: Data
        a Data object
    *args: list of strings
        List of axes requested by the user, their units and values (optional)
    unit: str
        Unit requested by the user ("SI" by default)
    is_norm: bool
        Boolean indicating if the field must be normalized (False by default)
    axis_data: list
        list of ndarray corresponding to user-input data
    Returns
    -------
    list of 1Darray of axes values, ndarray of magnitude values
    """
    return_dict = self.get_along(args, axis_data=axis_data)
    values = return_dict[self.symbol]
    # Compute magnitude
    values = np_abs(values)
    # Convert into right unit (apart because of dBA conversion)
    if unit == self.unit or unit == "SI":
        if is_norm:
            try:
                values = values / self.normalizations.get("ref")
            except:
                raise NormError(
                    "ERROR: Reference value not specified for normalization")
    elif unit == "dB":
        ref_value = 1.0
        if "ref" in self.normalizations.keys():
            ref_value *= self.normalizations.get("ref")
        values = to_dB(values, self.unit, ref_value)
    elif unit == "dBA":
        ref_value = 1.0
        if "ref" in self.normalizations.keys():
            ref_value *= self.normalizations.get("ref")
        if "freqs" in return_dict.keys():
            values = to_dBA(values, return_dict["freqs"], self.unit, ref_value)
        else:
            raise UnitError(
                "ERROR: dBA conversion only available for fft with frequencies"
            )
    elif unit in self.normalizations:
        values = values / self.normalizations.get(unit)
    else:
        values = convert(values, self.unit, unit)
    return_dict[self.symbol] = values
    return return_dict
Esempio n. 5
0
def get_values(
    self,
    unit="SI",
    is_pattern=False,
    is_oneperiod=False,
    is_antiperiod=False,
    is_smallestperiod=False,
):
    """Returns the vector 'axis' taking symmetries into account.
    Parameters
    ----------
    self: DataPattern
        a DataPattern object
    unit: str
        requested unit
    is_oneperiod: bool
        return values on a single period
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    Vector of axis values
    """
    values = self.values

    # Unit conversion
    if unit != "SI" and unit != self.unit:
        values = convert(values, self.unit, unit)

    # Rebuild pattern
    if is_smallestperiod or is_pattern:
        return values
    else:
        if self.values_whole is not None:
            return self.values_whole
        else:
            return values[self.rebuild_indices]
Esempio n. 6
0
def get_axis(self, axis, normalizations):
    """Computes the vector 'axis' in the unit required, using conversions and symmetries if needed.
    Parameters
    ----------
    self: RequestedAxis
        a RequestedAxis object
    axis: Axis
        an Axis object
    normalizations: dict
        dictionary of the normalizations
    """
    
    # Get original values of the axis
    if self.operation is not None:
        module = import_module("SciDataTool.Functions.conversions")
        func = getattr(module, self.operation) # Conversion function
        values = array(func(axis.get_values()))
    else:
        values = array(axis.get_values())
    # Unit conversions and normalizations
    unit = self.unit
    if unit == axis.unit or unit == "SI":
        pass
    elif unit in normalizations:
        values = array([v / normalizations.get(unit) for v in values])
    else:
        values = convert(values, axis.unit, unit)
    # Interpolate axis with input data
    if self.extension == "whole":
        self.values = values
    elif self.input_data is not None:
        self.input_data = get_common_base(self.input_data, values)
        self.values = values
    elif self.indices is not None:
        self.values = values[self.indices]
                    
Esempio n. 7
0
def get_axis(self, axis, is_real):
    """Computes the vector 'axis' in the unit required, using conversions and symmetries if needed.
    Parameters
    ----------
    self: RequestedAxis
        a RequestedAxis object
    axis: Axis
        an Axis object
    """
    if self.operation is not None:
        module = import_module("SciDataTool.Functions.conversions")
        func = getattr(module, self.operation)  # Conversion function
    if isinstance(axis, DataPattern):
        self.is_pattern = True
        self.rebuild_indices = axis.rebuild_indices
        self.is_step = axis.is_step
    is_components = getattr(axis, "is_components", False)
    if is_components:
        values = axis.get_values()
        if not self.extension in ["sum", "rss", "mean", "rms", "integrate"]:
            self.extension = "list"
        if self.indices is not None:
            self.values = values[self.indices]
        else:
            self.values = values
    else:
        if self.extension == "pattern":
            if not self.is_pattern:
                raise AxisError(
                    "ERROR: [pattern] cannot be called with non DataPattern axis"
                )
            else:
                is_smallestperiod = True
                is_oneperiod = False
                is_antiperiod = False
                self.extension = "smallestperiod"
        elif self.extension == "smallestperiod":
            if isinstance(axis, DataPattern):
                raise AxisError(
                    "ERROR: [smallestperiod] cannot be called with DataPattern axis"
                )
            else:
                is_smallestperiod = True
                is_oneperiod = False
                is_antiperiod = False
        elif self.extension == "antiperiod":
            if isinstance(axis, DataPattern):
                raise AxisError(
                    "ERROR: [antiperiod] cannot be called with DataPattern axis"
                )
            else:
                is_smallestperiod = False
                is_oneperiod = False
                is_antiperiod = True
        elif self.extension == "oneperiod" or self.transform == "fft":
            if isinstance(axis, DataPattern):
                raise AxisError(
                    "ERROR: [oneperiod] cannot be called with DataPattern axis"
                )
            else:
                is_smallestperiod = False
                is_oneperiod = True
                is_antiperiod = False
        elif self.extension in ["sum", "rss", "mean", "rms", "integrate"]:
            is_smallestperiod = False
            is_oneperiod = False
            is_antiperiod = False
        # Ignore symmetries if fft axis
        elif self.name == "freqs" or self.name == "wavenumber":
            is_smallestperiod = True
            is_oneperiod = False
            is_antiperiod = False
        else:
            if self.input_data is not None and not self.is_step:
                # Check if symmetries need to be reconstructed to match input_data
                if self.operation is not None:
                    axis_values = func(
                        axis.get_values(is_smallestperiod=True, ),
                        is_real=is_real,
                    )
                else:
                    axis_values = axis.get_values(is_smallestperiod=True, )
                if min(self.input_data) >= min(axis_values) and max(
                        self.input_data) <= max(axis_values):
                    is_smallestperiod = True
                    is_oneperiod = False
                    is_antiperiod = False
                else:
                    if self.operation is not None:
                        axis_values = func(
                            axis.get_values(is_oneperiod=True, ),
                            is_real=is_real,
                        )
                    else:
                        axis_values = axis.get_values(is_oneperiod=True, )
                    if min(self.input_data) >= min(axis_values) and max(
                            self.input_data) <= max(axis_values):
                        is_smallestperiod = False
                        is_oneperiod = True
                        is_antiperiod = False
                        self.extension = "oneperiod"
                    else:
                        is_smallestperiod = False
                        is_oneperiod = False
                        is_antiperiod = False
                        if not self.is_pattern:
                            self.extension = "interval"
            elif self.transform == "ifft":  # Ignore symmetries in ifft case
                is_smallestperiod = True
                is_oneperiod = False
                is_antiperiod = False
            else:
                is_smallestperiod = False
                is_oneperiod = False
                is_antiperiod = False
        # Get original values of the axis
        if self.operation is not None:
            values = array(
                func(
                    axis.get_values(
                        is_oneperiod=is_oneperiod,
                        is_antiperiod=is_antiperiod,
                        is_smallestperiod=is_smallestperiod,
                    ),
                    is_real=is_real,
                ))
            # Store original values
            self.corr_values = array(
                axis.get_values(
                    is_oneperiod=is_oneperiod,
                    is_antiperiod=is_antiperiod,
                    is_smallestperiod=is_smallestperiod,
                ))
        else:
            values = array(
                axis.get_values(
                    is_oneperiod=is_oneperiod,
                    is_antiperiod=is_antiperiod,
                    is_smallestperiod=is_smallestperiod,
                ))
        # Unit conversions and normalizations
        unit = self.unit
        if unit == self.corr_unit or unit == "SI":
            pass
        elif unit in axis.normalizations:
            if axis.normalizations.get(unit) == "indices":
                values = array([i for i in range(len(values))])
            elif isinstance(axis.normalizations.get(unit), ndarray):
                values = axis.normalizations.get(unit)
            else:
                values = values / axis.normalizations.get(unit)
        else:
            values = convert(values, self.corr_unit, unit)
        # Rebuild symmetries in fft case
        if self.transform == "fft":
            if "period" in axis.symmetries:
                if axis.name != "time":
                    values = values * axis.symmetries["period"]
            elif "antiperiod" in axis.symmetries:
                if axis.name != "time":
                    values = values * axis.symmetries["antiperiod"] / 2
        # Rebuild symmetries in ifft case
        if self.transform == "ifft":
            # if "antiperiod" in axis.symmetries:
            #     axis.symmetries["antiperiod"] = int(axis.symmetries["antiperiod"]/2)
            if (self.extension != "smallestperiod"
                    and self.extension != "oneperiod"
                    and self.extension != "antiperiod"):
                values = rebuild_symmetries_axis(values, axis.symmetries)
            # if "period" in axis.symmetries:
            #     if axis.name != "freqs":
            #         values = values * axis.symmetries["period"]
            # elif "antiperiod" in axis.symmetries:
            #     if axis.name != "freqs":
            #         values = values * axis.symmetries["antiperiod"] / 2
        # Interpolate axis with input data
        if self.input_data is None:
            self.values = values
        else:
            # if self.is_step:
            #     values = values[axis.rebuild_indices]
            if len(self.input_data) == 2 and self.extension != "axis_data":
                indices = [
                    i for i, x in enumerate(values)
                    if x >= self.input_data[0] and x <= self.input_data[-1]
                ]
                if self.indices is None:
                    self.indices = indices
                else:
                    indices_new = []
                    for i in self.indices:
                        if i in indices:
                            indices_new.append(i)
                    self.indices = indices_new
                self.input_data = None
            else:
                self.values = values
        if self.indices is not None:
            self.values = values[self.indices]
            if self.extension in ["sum", "rss", "mean", "rms", "integrate"]:
                self.indices = None
Esempio n. 8
0
def get_axis(self, axis):
    """Computes the vector 'axis' in the unit required, using conversions and symmetries if needed.
    Parameters
    ----------
    self: RequestedAxis
        a RequestedAxis object
    axis: Axis
        an Axis object
    """
    is_components = getattr(axis, "is_components", False)
    if is_components:
        values = axis.get_values()
        self.extension = "list"
        if self.indices is not None:
            self.values = values[self.indices]
        else:
            self.values = values
    else:
        if self.extension == "smallestperiod":
            is_smallestperiod = True
            is_oneperiod = False
            is_antiperiod = False
        elif self.extension == "antiperiod":
            is_smallestperiod = False
            is_oneperiod = False
            is_antiperiod = True
        elif self.extension == "oneperiod" or self.transform == "fft":
            is_smallestperiod = False
            is_oneperiod = True
            is_antiperiod = False
        elif self.extension == "axis_data":
            is_smallestperiod = True
            is_oneperiod = False
            is_antiperiod = False
        else:
            is_smallestperiod = False
            is_oneperiod = False
            is_antiperiod = False
        # Get original values of the axis
        if self.operation is not None:
            module = import_module("SciDataTool.Functions.conversions")
            func = getattr(module, self.operation)  # Conversion function
            values = array(
                func(
                    axis.get_values(
                        is_oneperiod=is_oneperiod,
                        is_antiperiod=is_antiperiod,
                        is_smallestperiod=is_smallestperiod,
                    )
                )
            )
        else:
            values = array(
                axis.get_values(
                    is_oneperiod=is_oneperiod,
                    is_antiperiod=is_antiperiod,
                    is_smallestperiod=is_smallestperiod,
                )
            )
        # Unit conversions and normalizations
        unit = self.unit
        if unit == self.corr_unit or unit == "SI":
            pass
        elif unit in axis.normalizations:
            values = array([v / axis.normalizations.get(unit) for v in values])
        else:
            values = convert(values, self.corr_unit, unit)
        # Rebuild symmetries in fft case
        if self.transform == "fft":
            if "period" in axis.symmetries:
                if axis.name != "time":
                    values = values * axis.symmetries["period"]
            elif "antiperiod" in axis.symmetries:
                if axis.name != "time":
                    values = (
                        values * axis.symmetries["antiperiod"] / 2
                    )
        # Interpolate axis with input data
        if self.extension in ["whole", "oneperiod", "antiperiod", "smallestperiod"]:
            self.values = values
        elif self.input_data is not None:
            if len(self.input_data) == 2 and self.extension != "axis_data":
                self.indices = [
                    i
                    for i, x in enumerate(values)
                    if x >= self.input_data[0] and x <= self.input_data[-1]
                ]
                self.input_data = None
            else:
                if self.extension == "axis_data":
                    self.input_data = get_common_base(self.input_data, values, is_downsample=True)
                else:
                    self.input_data = get_common_base(self.input_data, values)
                self.values = values
        if self.indices is not None:
            self.values = values[self.indices]
def get_magnitude_along(
    self, *args, unit="SI", is_norm=False, axis_data=[], is_squeeze=True
):
    """Returns the ndarray of the magnitude of the FT, using conversions and symmetries if needed.
    Parameters
    ----------
    self: Data
        a Data object
    *args: list of strings
        List of axes requested by the user, their units and values (optional)
    unit: str
        Unit requested by the user ("SI" by default)
    is_norm: bool
        Boolean indicating if the field must be normalized (False by default)
    axis_data: list
        list of ndarray corresponding to user-input data
    Returns
    -------
    list of 1Darray of axes values, ndarray of magnitude values
    """
    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args
    return_dict = self.get_along(
        args, axis_data=axis_data, is_squeeze=is_squeeze, is_magnitude=True
    )
    values = return_dict[self.symbol]

    # 1/nth octave band
    for axis in return_dict["axes_list"]:
        if axis.name == "freqs" or axis.corr_name == "freqs":
            index = axis.index
            if axis.noct is not None:
                (values, foct) = apply_along_axis(
                    to_noct, index, values, return_dict["freqs"], noct=axis.noct
                )
                return_dict[axis.name] = foct
    # Convert into right unit (apart because of dBA conversion)
    if unit == self.unit or unit == "SI":
        if is_norm:
            try:
                values = values / self.normalizations.get("ref")
            except:
                raise NormError(
                    "ERROR: Reference value not specified for normalization"
                )
    elif unit == "dB":
        ref_value = 1.0
        if "ref" in self.normalizations.keys():
            ref_value *= self.normalizations.get("ref")
        values = to_dB(values, self.unit, ref_value)
    elif unit == "dBA":
        ref_value = 1.0
        if "ref" in self.normalizations.keys():
            ref_value *= self.normalizations.get("ref")
        if "freqs" in return_dict.keys():
            for axis in return_dict["axes_list"]:
                if axis.name == "freqs" or axis.corr_name == "freqs":
                    index = axis.index
            values = apply_along_axis(
                to_dBA, index, values, return_dict["freqs"], self.unit, ref_value
            )
        else:
            raise UnitError(
                "ERROR: dBA conversion only available for fft with frequencies"
            )
    elif unit in self.normalizations:
        values = values / self.normalizations.get(unit)
    else:
        values = convert(values, self.unit, unit)
    return_dict[self.symbol] = values
    return return_dict
Esempio n. 10
0
def get_harmonics(self,
                  N_harm,
                  *args,
                  unit="SI",
                  is_norm=False,
                  is_flat=False):
    """Returns the complex Fourier Transform of the field, using conversions and symmetries if needed.
    Parameters
    ----------
    self: Data
        a Data object
    N_harm: int
        Number of largest harmonics to be extracted
    args: list
        Axes names, ranges and units
    unit: str
        Unit demanded by the user ("SI" by default)
    is_norm: bool
        Boolean indicating if the field must be normalized (False by default)
    is_flat: bool
        Boolean if the output data remains flattened (for 2D cases)
    Returns
    -------
    list of 1Darray of axes values, ndarray of magnitude of FT
    """
    # Read the axes input in args
    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args
    axes_list = read_input_strings(args, [])
    # Extract the requested axes (symmetries + unit)
    for axis_requested in axes_list:
        if axis_requested[3] == "values":
            # Get original values of the axis
            axis_requested.append(
                self.get_FT_axis(axis_requested[0] + axis_requested[1]))
            # Interpolate axis with input data
            if str(axis_requested[4]) == "whole":
                axis_requested[4] = axis_requested[5]
                axis_requested[5] = "whole"
            else:
                axis_requested[4] = get_common_base(axis_requested[5],
                                                    axis_requested[4])
        # Change fft name for the slices of the field
        if axis_requested[0] == "freqs":
            axis_requested[0] = "time"
        elif axis_requested[0] == "wavenumber":
            axis_requested[0] = "angle"
    # Check if the requested axis is defined in the Data object
    for axis_requested in axes_list:
        axis_name = axis_requested[0]
        is_match = False
        for index, axis in enumerate(self.axes):
            if axis.name == axis_name:
                is_match = True
        if not is_match:
            axes_list.remove(axis_requested)
    # Rebuild symmetries of field if axis is extracted
    values = self.values
    for index, axis in enumerate(self.axes):
        for axis_requested in axes_list:
            if axis.name in self.symmetries.keys(
            ) and axis.name == axis_requested[0]:
                values = rebuild_symmetries(values, index,
                                            self.symmetries.get(axis.name))
    # Extract the slices of the field (single values)
    for index, axis in enumerate(self.axes):
        is_match = False
        for axis_requested in axes_list:
            if axis.name == axis_requested[0]:
                is_match = True
                if axis_requested[3] == "indices" and axis_requested[
                        2] == "single":
                    values = take(values, axis_requested[4], axis=index)
        if not is_match:  # Axis was not specified -> take slice at the first value
            values = take(values, [0], axis=index)
    # Interpolate over axis values (single values)
    for index, axis in enumerate(self.axes):
        for axis_requested in axes_list:
            if (axis.name == axis_requested[0]
                    and axis_requested[3] == "values"
                    and axis_requested[2] == "single"):
                values = apply_along_axis(
                    get_interpolation,
                    index,
                    values,
                    axis_requested[5],
                    axis_requested[4],
                )
    # Perform Fourier Transform
    values = np_abs(comp_fft(values))
    # Extract slices again (intervals)
    for index, axis in enumerate(self.axes):
        for axis_requested in axes_list:
            if axis.name == axis_requested[0]:
                if axis_requested[2] == "indices" and axis_requested[
                        2] == "interval":
                    values = take(values, axis_requested[4], axis=index)
    # Interpolate over axis values again (intervals)
    for index, axis in enumerate(self.axes):
        for axis_requested in axes_list:
            if axis.name == axis_requested[0]:
                if axis_requested[3] == "values" and axis_requested[
                        2] == "interval":
                    values = apply_along_axis(
                        get_interpolation,
                        index,
                        values,
                        axis_requested[5],
                        axis_requested[4],
                    )
    # Eliminate dimensions=1
    values = squeeze(values)
    # Test if data is 1D or 2D
    if len(values.shape) > 2:
        raise AxisError("ERROR: only 1D or 2D implemented")
    else:
        # Convert into right unit
        if unit == self.unit or unit == "SI":
            if is_norm:
                try:
                    values = values / self.normalizations.get("ref")
                except:
                    raise NormError(
                        "ERROR: Reference value not specified for normalization"
                    )
        elif unit == "dB":
            ref_value = 1.0
            if "ref" in self.normalizations.keys():
                ref_value *= self.normalizations.get("ref")
            values = to_dB(values, self.unit, ref_value)
        elif unit == "dBA":
            ref_value = 1.0
            is_match = False
            if "ref" in self.normalizations.keys():
                ref_value *= self.normalizations.get("ref")
            for axis_requested in axes_list:
                if axis_requested[0] == "time":
                    is_match = True
                    values = to_dBA(values, axis_requested[4], self.unit,
                                    ref_value)
            if not is_match:
                raise UnitError(
                    "ERROR: dBA conversion only available for fft with frequencies"
                )
        elif unit in self.normalizations:
            values = values / self.normalizations.get(unit)
        else:
            values = convert(values, self.unit, unit)
        # 1D case
        if len(values.shape) == 1:
            for axis_requested in axes_list:
                if axis_requested[2] == "interval":
                    axis_values = axis_requested[4]
            indices = argsort(negative(values))
            indices = indices[:N_harm]
            axis_values = axis_values[indices]
            values = values[indices]
            return [axis_values, values]
        # 2D case
        else:
            for axis_requested in axes_list:
                if axis_requested[0] == "angle":
                    r = axis_requested[4]
                elif axis_requested[0] == "time":
                    f = axis_requested[4]
            # Flatten the data
            values_flat = values.flatten()
            R, F = meshgrid(r, f)
            f = F.flatten()
            r = R.flatten()
            # Get the N_harm largest peaks
            indices = argsort(negative(values_flat))
            indices = indices[:N_harm]
            values = values_flat[indices]
            f = f[indices]
            r = r[indices]
            if len(values.shape) == 2 and not is_flat:
                f.reshape((N_harm, N_harm))
                r.reshape((N_harm, N_harm))
                values.reshape((N_harm, N_harm))
            return [f, r, values]