Ejemplo n.º 1
0
def rebuild_symmetries(
    self,
    values,
    axis_name,
    axis_index,
    is_oneperiod=False,
    is_antiperiod=False,
    is_smallestperiod=False,
):
    """Reconstructs the field of a Data object taking symmetries into account
    Parameters
    ----------
    self: Data
        a Data object
    values: ndarray
        ndarray of a field
    axes_list: list
        a list of RequestedAxis objects
    Returns
    -------
    ndarray of the reconstructed field
    """
    # Rebuild symmetries
    if is_smallestperiod:
        return values
    elif is_antiperiod:
        if axis_name in self.symmetries.keys():
            if "antiperiod" in self.symmetries.get(axis_name):
                return values
            else:
                raise AxisError("ERROR: axis has no antiperiodicity")
        else:
            raise AxisError("ERROR: axis has no antiperiodicity")
    elif is_oneperiod:
        if axis_name in self.symmetries:
            if "antiperiod" in self.symmetries.get(axis_name):
                nper = self.symmetries.get(axis_name)["antiperiod"]
                self.symmetries.get(axis_name)["antiperiod"] = 2
                values = rebuild_symmetries_fct(values, axis_index,
                                                self.symmetries.get(axis_name))
                self.symmetries.get(axis_name)["antiperiod"] = nper
                return values
            else:
                return values
        else:
            return values
    else:
        if axis_name in self.symmetries:
            values = rebuild_symmetries_fct(values, axis_index,
                                            self.symmetries.get(axis_name))
            return values
        else:
            return values
Ejemplo n.º 2
0
def comp_axes(self, axes_list):
    """Completes the RequestedAxis objects in axes_list.
    Parameters
    ----------
    self: Data
        a Data object
    axes_list: list
        a list of RequestedAxis objects
    Returns
    -------
    list of RequestedAxis objects
    """

    # Check if the requested axis is defined in the Data object
    for axis_requested in axes_list:
        axis_name = axis_requested.name
        for index, axis in enumerate(self.axes):
            if axis.name == axis_name:
                axis_requested.index = index
                axis_requested.corr_name = axis_name
        if axis_requested.index is None:
            # Check if requested axis is in correspondance dicts
            if axis_name in axes_dict.keys():
                for index, axis in enumerate(self.axes):
                    if axis.name == axes_dict[axis_name][0]:
                        axis_requested.corr_name = axes_dict[axis_name][0]
                        axis_requested.operation = axes_dict[axis_name][
                            0] + "_to_" + axis_name
                        axis_requested.transform = axes_dict[axis_name][1]
                        axis_requested.index = index
                if axis_requested.index is None:
                    raise AxisError("ERROR: Requested axis [" + axis_name +
                                    "] is not available")
            elif axis_name in rev_axes_dict.keys():
                for index, axis in enumerate(self.axes):
                    if axis.name == rev_axes_dict[axis_name][0]:
                        axis_requested.corr_name = rev_axes_dict[axis_name][0]
                        axis_requested.operation = rev_axes_dict[axis_name][
                            0] + "_to_" + axis_name
                        axis_requested.transform = rev_axes_dict[axis_name][1]
                        axis_requested.index = index
                if axis_requested.index is None:
                    raise AxisError("ERROR: Requested axis [" + axis_name +
                                    "] is not available")
            else:
                # Axis does not exist and is ignored
                axes_list.remove(axis_requested)
    # Extract the requested axes (symmetries + unit)
    for axis_requested in axes_list:
        axis_requested.get_axis(self.axes[axis_requested.index],
                                self.normalizations)
    return axes_list
Ejemplo n.º 3
0
def get_length(self, is_oneperiod=False, is_antiperiod=False):
    """Returns the length of the axis taking symmetries into account.
    Parameters
    ----------
    self: DataLinspace
        a DataLinspace object
    is_oneperiod: bool
        return values on a single period
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    Length of axis
    """

    if self.number is None:
        N = (self.final - self.initial + self.step) / self.step
    else:
        N = self.number

    # Rebuild symmetries
    if is_antiperiod:
        if self.name in self.symmetries:
            if "antiperiod" in self.symmetries.get(self.name):
                return N
            else:
                raise AxisError("ERROR: axis has no antiperiodicity")
        else:
            raise AxisError("ERROR: axis has no antiperiodicity")
    elif is_oneperiod:
        if self.name in self.symmetries:
            if "antiperiod" in self.symmetries.get(self.name):
                return N * 2
            elif "period" in self.symmetries.get(self.name):
                return N
            else:
                raise AxisError("ERROR: unknown periodicity")
        else:
            return N
    else:
        if self.name in self.symmetries:
            if "antiperiod" in self.symmetries.get(self.name):
                return N * self.symmetries.get(self.name)["antiperiod"]
            elif "period" in self.symmetries.get(self.name):
                return N * self.symmetries.get(self.name)["period"]
            else:
                raise AxisError("ERROR: unknown periodicity")
        else:
            return N
Ejemplo n.º 4
0
def freq_to_time(self):
    """Performs the inverse Fourier Transform and stores the resulting field in a DataTime object.
    Parameters
    ----------
    self : DataFreq
        a DataFreq object
    Returns
    -------
    a DataTime object
    """
    
    axes_str = [axis.name for axis in self.axes]
    axes_str = ["time" if axis_name == "freqs" else axis_name for axis_name in axes_str]
    axes_str = ["angle" if axis_name == "wavenumber" else axis_name for axis_name in axes_str]
    
    if axes_str == [axis.name for axis in self.axes]:
        raise AxisError(
            "ERROR: No available axis is compatible with fft (should be time or angle)"
        )
    else:
        results = self.get_along(*axes_str)
        values = results.pop(self.symbol)
        Axes = []
        for axis in results.keys():
            Axes.append(Data1D(name=axis, values=results[axis]))
        return DataTime(
            name=self.name,
            unit=self.unit,
            symbol=self.symbol,
            axes=Axes,
            values=values,
        )
Ejemplo n.º 5
0
def get_length(self, is_oneperiod=False, is_antiperiod=False):
    """Returns the length of the axis taking symmetries into account.
    Parameters
    ----------
    self: Data1D
        a Data1D object
    is_oneperiod: bool
        return values on a single period
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    Length of axis
    """
    N = len(self.values)
    # Rebuild symmetries
    if is_antiperiod:
        if "antiperiod" in self.symmetries:
            return N
        else:
            raise AxisError("ERROR: axis has no antiperiodicity")
    elif is_oneperiod:
        if "antiperiod" in self.symmetries:
            return N * 2
        elif "period" in self.symmetries:
            return N
        else:
            return N
    else:
        if "antiperiod" in self.symmetries:
            return N * self.symmetries["antiperiod"]
        elif "period" in self.symmetries:
            return N * self.symmetries["period"]
        else:
            return N
Ejemplo n.º 6
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
Ejemplo n.º 7
0
def get_harm_rad_along(self,
                       N_harm,
                       *args,
                       unit="SI",
                       is_norm=False,
                       axis_data=[]):
    """Returns the ndarray of the radial component of the field, 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 field values
    """

    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args

    if "radial" in self.components.keys():
        return_dict = self.components["radial"].get_harmonics(
            N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        return_dict[self.symbol + "_r"] = return_dict.pop(
            self.components["radial"].symbol)

    elif "x" in self.components.keys() and "y" in self.components.keys():
        # Extract from DataND
        resultx = self.components["x"].get_harmonics(N_harm,
                                                     args,
                                                     unit=unit,
                                                     is_norm=is_norm,
                                                     axis_data=axis_data)
        resulty = self.components["y"].get_harmonics(N_harm,
                                                     args,
                                                     unit=unit,
                                                     is_norm=is_norm,
                                                     axis_data=axis_data)
        field_x = resultx[self.components["x"].symbol]
        field_y = resulty[self.components["y"].symbol]
        x = resultx["x"]
        y = resultx["y"]
        # Convert to cylindrical coordinates
        (r, phi) = xy_to_rphi(x, y)
        (field_r, field_t) = cart2pol(field_x, field_y, phi)
        return_dict = dict(resultx)
        del return_dict[self.components["x"].symbol]
        return_dict[self.symbol + "_r"] = field_r
    else:
        raise AxisError("radial or x,y components necessary")

    return return_dict
Ejemplo n.º 8
0
def rebuild_symmetries_axis(values, symmetries):
    """Reconstructs the field of a Data object taking symmetries into account
    Parameters
    ----------
    values: ndarray
        ndarray of a the axis values
    symmetries: dict
        Dictionary of the symmetries along the axis
    Returns
    -------
    ndarray of the reconstructed axis
    """
    values_new = values
    if "period" in symmetries.keys():
        for i in range(symmetries.get("period") - 1):
            if len(values) == 1:
                if "delta" in symmetries.keys():
                    values_new = append(values_new,
                                        values_new[-1] + symmetries["delta"])
                else:
                    raise AxisError(
                        "ERROR: must provide delta for symmetries with one sample"
                    )
            else:
                values_new = concatenate((
                    values_new,
                    values + (values_new[-1] - values_new[-2]) +
                    values_new[-1],
                ))
    elif "antiperiod" in symmetries.keys():
        for i in range(symmetries.get("antiperiod") - 1):
            if len(values) == 1:
                if "delta" in symmetries.keys():
                    values_new = append(values_new,
                                        values_new[-1] + symmetries["delta"])
                else:
                    raise AxisError(
                        "ERROR: must provide delta for symmetries with one sample"
                    )
            else:
                values_new = concatenate((
                    values_new,
                    values + (values_new[-1] - values_new[-2]) +
                    values_new[-1],
                ))
    return values_new
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def get_axis_periodic(self, Nper, is_antiperiod=False):
    """Returns the vector 'axis' taking symmetries into account.
    Parameters
    ----------
    self: DataLinspace
        a DataLinspace object
    Nper: int
        number of periods
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    New DataLinspace
    """

    # Dynamic import to avoid loop
    module = __import__("SciDataTool.Classes.DataLinspace",
                        fromlist=["DataLinspace"])
    DataLinspace = getattr(module, "DataLinspace")

    values = self.get_values()
    N = self.get_length()

    if N % Nper != 0:
        raise AxisError(
            "ERROR: length of axis is not divisible by the number of periods")

    values_per = values[:int(N / Nper)]

    if is_antiperiod:
        sym = "antiperiod"
    else:
        sym = "period"

    New_axis = DataLinspace(
        initial=self.initial,
        final=values_per[-1],
        number=int(N / Nper),
        include_endpoint=True,
        name=self.name,
        unit=self.unit,
        symmetries={sym: Nper},
        normalizations=self.normalizations,
        is_components=self.is_components,
        symbol=self.symbol,
    )

    return New_axis
Ejemplo n.º 11
0
def get_harm_ax_along(self,
                      N_harm,
                      *args,
                      unit="SI",
                      is_norm=False,
                      axis_data=[]):
    """Returns the ndarray of the axial (z) component of the field, 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 field values
    """

    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args

    if "axial" in self.components.keys():
        return_dict = self.components["axial"].get_harmonics(
            N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        return_dict[self.symbol + "_z"] = return_dict.pop(
            self.components["axial"].symbol)

    elif "z" in self.components.keys():
        return_dict = self.components["z"].get_harmonics(N_harm,
                                                         args,
                                                         unit=unit,
                                                         is_norm=is_norm,
                                                         axis_data=axis_data)
        return_dict[self.symbol + "_z"] = return_dict.pop(
            self.components["z"].symbol)

    else:
        raise AxisError("axial or z component necessary")

    return return_dict
Ejemplo n.º 12
0
def get_axis_periodic(self, Nper, is_antiperiod=False):
    """Returns the vector 'axis' taking symmetries into account.
    Parameters
    ----------
    self: Data1D
        a Data1D object
    Nper: int
        number of periods
    is_antiperiod: bool
        return values on a semi period (only for antiperiodic signals)
    Returns
    -------
    New Data1D
    """

    # Dynamic import to avoid loop
    module = __import__("SciDataTool.Classes.Data1D", fromlist=["Data1D"])
    Data1D = getattr(module, "Data1D")

    values = self.values
    N = self.get_length()

    if N % Nper != 0:
        raise AxisError(
            "ERROR: length of axis is not divisible by the number of periods")

    values_per = values[:int(N / Nper)]

    if is_antiperiod:
        sym = "antiperiod"
    else:
        sym = "period"

    New_axis = Data1D(
        values=values_per,
        name=self.name,
        unit=self.unit,
        symmetries={self.name: {
            sym: Nper
        }},
        is_components=self.is_components,
        symbol=self.symbol,
    )

    return New_axis
Ejemplo n.º 13
0
def freq_to_time(self):
    """Performs the inverse Fourier Transform and stores the resulting field in a DataTime object.
    Parameters
    ----------
    self : DataFreq
        a DataFreq object
    Returns
    -------
    a DataTime object
    """

    # Dynamic import to avoid loop
    module = __import__("SciDataTool.Classes.DataTime", fromlist=["DataTime"])
    DataTime = getattr(module, "DataTime")

    axes_str = []
    for i, axis in enumerate(self.axes):
        if axis.is_components:
            axis_str = axis.name + str(list(range(len(axis.values))))
        elif axis.name == "freqs":
            axis_str = "time"
        elif axis.name == "wavenumber":
            axis_str = "angle"
        else:
            axis_str = axis.name
        axes_str.append(axis_str)
    if axes_str == [axis.name for axis in self.axes]:
        raise AxisError(
            "ERROR: No available axis is compatible with fft (should be time or angle)"
        )
    else:
        results = self.get_along(*axes_str)
        values = results.pop(self.symbol)
        Axes = []
        for axis in self.axes:
            if axis.is_components:  # components axis
                name = axis.name
                is_components = True
                axis_values = axis.values
                unit = "SI"
            elif axis.name == "freqs":
                name = "time"
                is_components = False
                axis_values = results["time"]
                unit = "s"
            elif axis.name == "wavenumber":
                name = "angle"
                is_components = False
                axis_values = results["angle"]
                unit = "rad"
            else:
                name = axis.name
                is_components = False
                axis_values = results[axis.name]
                unit = axis.unit
            Axes.append(
                Data1D(
                    name=name,
                    unit=unit,
                    values=axis_values,
                    is_components=is_components,
                )
            )
        return DataTime(
            name=self.name,
            unit=self.unit,
            symbol=self.symbol,
            axes=Axes,
            values=values,
        )
Ejemplo n.º 14
0
def rebuild_symmetries(
    self,
    values,
    axes_list,
):
    """Reconstructs the field of a Data object taking symmetries into account
    Parameters
    ----------
    self: Data
        a Data object
    values: ndarray
        ndarray of a field
    axes_list: list
        a list of RequestedAxis objects
    Returns
    -------
    ndarray of the reconstructed field
    """
    
    for axis in axes_list:
        if axis.transform != "fft" and axis.extension in [
            "whole",
            "interval",
            "oneperiod",
            "antiperiod",
            "smallestperiod",
        ]:
            if axis.extension == "smallestperiod":
                is_smallestperiod = True
                is_oneperiod = False
                is_antiperiod = False
            elif axis.extension == "antiperiod":
                is_smallestperiod = False
                is_oneperiod = False
                is_antiperiod = True
            elif axis.extension == "oneperiod":
                is_smallestperiod = False
                is_oneperiod = True
                is_antiperiod = False
            else:
                is_smallestperiod = False
                is_oneperiod = False
                is_antiperiod = False
             
            # Rebuild symmetries
            axis_symmetries = self.axes[axis.index].symmetries
            if is_smallestperiod:
                return values
            elif is_antiperiod:
                if "antiperiod" in axis_symmetries:
                    return values
                else:
                    raise AxisError("ERROR: axis has no antiperiodicity")
            elif is_oneperiod:
                if "antiperiod" in axis_symmetries:
                    nper = axis_symmetries["antiperiod"]
                    axis_symmetries["antiperiod"] = 2
                    values = rebuild_symmetries_fct(
                        values, axis.index, axis_symmetries
                    )
                    axis_symmetries["antiperiod"] = nper
                    return values
                else:
                    return values
            else:
                values = rebuild_symmetries_fct(
                    values, axis.index, axis_symmetries
                )
                return values
        else:
            return values
Ejemplo n.º 15
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
Ejemplo n.º 16
0
def read_input_strings(args, axis_data):
    """Reads the string input into the "get_along" methods to define the axes
    Parameters
    ----------
    args: list
        list of string describing the requested axes
    axis_data: ndarray
        user-input values for the axes
    Returns
    -------
    list of axes data (axes_list)
    """
    axes_list = []
    for axis_str in args:
        unit = "SI"
        values = None
        indices = None
        input_data = None
        # Detect unit
        if "{" in axis_str:
            elems = axis_str.split("{")
            unit = elems[1].strip("}")
            axis_str = elems[0]
        # Detect sum
        if "sum" in axis_str:
            elems = axis_str.split("=sum")
            name = elems[0]
            extension = "sum"
        elif "oneperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "oneperiod"
        elif "antiperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "antiperiod"
        elif "smallestperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "smallestperiod"
        # Detect axis_data input
        elif "axis_data" in axis_str:
            elems = axis_str.split("=axis_data")
            name = elems[0]
            extension = "interval"
            try:
                input_data = axis_data[int(elems[1]) - 1]
            except:
                try:
                    input_data = axis_data[0]
                except:
                    raise AxisError("ERROR: Absence of axis_data")
        # Detect interval
        elif "=[" in axis_str:
            elems = axis_str.split("=[")
            elems2 = elems[1].split(",")
            init_str = elems2[0]
            interval_init = eval(init_str)
            final_str = elems2[1].strip("]")
            interval_final = eval(final_str)
            name = elems[0]
            extension = "interval"
            input_data = [interval_init, interval_final]
        # Detect single value
        elif "=" in axis_str:
            elems = axis_str.split("=")
            name = elems[0]
            extension = "single"
            input_data = [eval(elems[1])]
        # Detect index input...
        elif "[" in axis_str:
            elems = axis_str.split("[")
            ind_str = elems[1].strip("]")
            name = elems[0]
            # Range of indices
            if ":" in ind_str:
                elems2 = ind_str.split(":")
                extension = "interval"
                indices = [
                    i for i in range(int(elems2[0]),
                                     int(elems2[1]) + 1)
                ]
            # List of indices
            elif "," in ind_str:
                extension = "list"
                indices = ind_str.split(",")
            # Single index
            else:
                extension = "single"
                indices = [int(ind_str)]
        # Whole axis
        else:
            name = axis_str
            extension = "whole"
        # RequestedAxis object creation
        axis = RequestedAxis(
            name=name,
            unit=unit,
            extension=extension,
            values=values,
            indices=indices,
            input_data=input_data,
        )
        axes_list.append(axis)
    return axes_list
Ejemplo n.º 17
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]
Ejemplo n.º 18
0
def get_mag_xyz_along(self, *args, unit="SI", is_norm=False, axis_data=[]):
    """Returns the list of the cartesian (comp_x,comp_y,comp_z) components of the field, 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 field values
    """

    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args

    if "radial" in self.components.keys(
    ) and "circumferential" in self.components.keys():
        # Extract from DataND
        resultr = self.components["radial"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        resultphi = self.components["circumferential"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_r = resultr[self.components["radial"].symbol]
        field_c = resultphi[self.components["circumferential"].symbol]
        shape = field_r.shape
        phi = resultr["phi"]
        # Convert to cylindrical coordinates
        (field_x, field_y) = pol2cart(field_r, field_c, phi)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "comp_z" in self.components.keys():
            resultz = self.components["comp_z"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["comp_z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resultr)
        del return_dict[self.components["radial"].symbol]

    elif "comp_x" in self.components.keys():
        resultx = self.components["comp_x"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_x = resultx[self.components["comp_x"].symbol]
        shape = field_x.shape
        if "comp_y" in self.components.keys():
            resulty = self.components["comp_y"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_y = resulty[self.components["comp_y"].symbol]
        else:
            field_y = zeros(shape)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "comp_z" in self.components.keys():
            resultz = self.components["comp_z"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["comp_z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resultx)
        del return_dict[self.components["comp_x"].symbol]

    elif "comp_y" in self.components.keys():
        resulty = self.components["comp_y"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_y = resultphi[self.components["comp_y"].symbol]
        shape = field_y.shape
        if "comp_x" in self.components.keys():
            resultx = self.components["comp_x"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_x = resultphi[self.components["comp_x"].symbol]
        else:
            field_x = zeros(shape)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "comp_z" in self.components.keys():
            resultz = self.components["comp_z"].get_magnitude_along(
                args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["comp_z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resulty)
        del return_dict[self.components["comp_y"].symbol]

    elif "axial" in self.components.keys():
        resultz = self.components["axial"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_z = resultz[self.components["axial"].symbol]
        shape = field_z.shape
        field_x = zeros(shape)
        field_y = zeros(shape)
        return_dict = dict(resultz)
        del return_dict[self.components["axial"].symbol]

    elif "comp_z" in self.components.keys():
        resultz = self.components["comp_z"].get_magnitude_along(
            args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_z = resultz[self.components["comp_z"].symbol]
        shape = field_z.shape
        field_x = zeros(shape)
        field_y = zeros(shape)
        return_dict = resultz
        del return_dict[self.components["comp_z"].symbol]

    else:
        raise AxisError(
            "Vector_field object is empty (should contain at least radial, circumferential, axial, x, y or z"
        )

    return_dict["comp_x"] = field_x
    return_dict["comp_y"] = field_y
    return_dict["comp_z"] = field_z

    return return_dict
Ejemplo n.º 19
0
def time_to_freq(self):
    """Performs the Fourier Transform and stores the resulting field in a DataFreq object.
    Parameters
    ----------
    self : DataTime
        a DataTime object
    Returns
    -------
    a DataFreq object
    """

    # Dynamic import to avoid loop
    module = __import__("SciDataTool.Classes.DataFreq", fromlist=["DataFreq"])
    DataFreq = getattr(module, "DataFreq")

    axes_str = []
    for i, axis in enumerate(self.axes):
        if axis.is_components:
            axis_str = axis.name + str(list(range(len(axis.values))))
        elif axis.name == "time":
            axis_str = "freqs"
        elif axis.name == "angle":
            axis_str = "wavenumber"
        else:
            axis_str = axis.name
        axes_str.append(axis_str)
    if axes_str == [axis.name for axis in self.axes]:
        raise AxisError(
            "ERROR: No available axis is compatible with fft (should be time or angle)"
        )
    else:
        results = self.get_along(*axes_str)
        values = results.pop(self.symbol)
        Axes = []
        for axis in self.axes:
            if axis.is_components:  # components axis
                name = axis.name
                is_components = True
                axis_values = axis.values
                unit = "SI"
            elif axis.name == "time":
                name = "freqs"
                is_components = False
                axis_values = results["freqs"]
                unit = "Hz"
            elif axis.name == "angle":
                name = "wavenumber"
                is_components = False
                axis_values = results["wavenumber"]
                unit = "dimless"
            else:
                name = axis.name
                is_components = False
                axis_values = results[axis.name]
                unit = axis.unit
            if "antiperiod" in axis.symmetries:
                symmetries = {"period": int(axis.symmetries["antiperiod"] / 2)}
            else:
                symmetries = axis.symmetries.copy()
            Axes.append(
                Data1D(
                    name=name,
                    unit=unit,
                    values=axis_values,
                    is_components=is_components,
                    symmetries=symmetries,
                    normalizations=axis.normalizations.copy(),
                ))
        return DataFreq(
            name=self.name,
            unit=self.unit,
            symbol=self.symbol,
            axes=Axes,
            values=values,
            is_real=self.is_real,
        )
Ejemplo n.º 20
0
def read_input_strings(args, axis_data):
    """Reads the string input into the "get_along" methods to define the axes
    Parameters
    ----------
    args: list
        list of string describing the requested axes
    axis_data: ndarray
        user-input values for the axes
    Returns
    -------
    list of axes data (axes_list)
    """
    axes_list = []
    for axis_str in args:
        unit = "SI"
        values = None
        indices = None
        input_data = None
        # Detect unit
        if "{" in axis_str:
            elems = axis_str.split("{")
            unit = elems[1].strip("}")
            axis_str = elems[0]
        # Detect normalization
        if "->" in axis_str:
            elems = axis_str.split("->")
            if "=" in elems[1]:
                unit = elems[1].split("=")[0]
            elif "[" in elems[1]:
                unit = elems[1].split("[")[0]
            elif ">" in elems[1]:
                unit = elems[1].split("[")[0]
            elif "<" in elems[1]:
                unit = elems[1].split("[")[0]
            else:
                unit = elems[1]
            name = elems[0]
            axis_str = axis_str.replace("->" + unit, "")
        # Detect rms sum
        if "rss" in axis_str:
            elems = axis_str.split("=rss")
            name = elems[0]
            extension = "rss"
        # Detect sum
        elif "sum" in axis_str:
            elems = axis_str.split("=sum")
            name = elems[0]
            extension = "sum"
        # Detect rms mean
        elif "rms" in axis_str:
            elems = axis_str.split("=rms")
            name = elems[0]
            extension = "rms"
        # Detect mean
        elif "mean" in axis_str:
            elems = axis_str.split("=mean")
            name = elems[0]
            extension = "mean"
        # Detect integrate
        elif "integrate" in axis_str:
            elems = axis_str.split("=integrate")
            name = elems[0]
            extension = "integrate"
        # Detect periods
        elif "oneperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "oneperiod"
        elif "antiperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "antiperiod"
        elif "smallestperiod" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "smallestperiod"
        # Detect pattern
        elif "pattern" in axis_str:
            elems = axis_str.split("[")
            name = elems[0]
            extension = "pattern"
        # Detect axis_data input
        elif "axis_data" in axis_str:
            elems = axis_str.split("=axis_data")
            name = elems[0]
            extension = "axis_data"
            try:
                input_data = axis_data[name]
            except:
                raise AxisError("ERROR: No axis_data provided")
        # Detect above
        elif ">" in axis_str:
            elems = axis_str.split(">")
            init_str = elems[1]
            interval_init = eval(init_str)
            interval_final = inf
            name = elems[0]
            extension = "interval"
            input_data = [interval_init, interval_final]
        # Detect below
        elif "<" in axis_str:
            elems = axis_str.split("<")
            init_str = elems[1]
            interval_init = -inf
            interval_final = eval(init_str)
            name = elems[0]
            extension = "interval"
            input_data = [interval_init, interval_final]
        # Detect interval
        elif "=[" in axis_str:
            elems = axis_str.split("=[")
            elems2 = elems[1].split(",")
            if len(elems2) > 2:
                extension = "list"
                name = elems[0]
                input_data = [eval(elem.strip("]")) for elem in elems2]
            else:
                init_str = elems2[0]
                interval_init = eval(init_str)
                final_str = elems2[1].strip("]")
                interval_final = eval(final_str)
                name = elems[0]
                extension = "interval"
                input_data = [interval_init, interval_final]
        # Detect single value
        elif "=" in axis_str:
            elems = axis_str.split("=")
            name = elems[0]
            extension = "single"
            input_data = [eval(elems[1])]
        # Detect index input...
        elif "[" in axis_str:
            elems = axis_str.split("[")
            ind_str = elems[1].strip("]")
            name = elems[0]
            # Range of indices
            if ":" in ind_str:
                elems2 = ind_str.split(":")
                extension = "interval"
                indices = [i for i in range(int(elems2[0]), int(elems2[1]))]
            # List of indices
            elif "," in ind_str:
                extension = "list"
                indices = [int(x) for x in ind_str.split(",")]
            # Single index
            else:
                extension = "single"
                indices = [int(ind_str)]
        # Whole axis
        else:
            name = axis_str
            extension = "whole"
        # Detect 1/nth octave band
        if "oct" in unit:
            noct = int(unit.split("oct")[0].split("/")[1])
            unit = "SI"
        else:
            noct = None
        # RequestedAxis object creation
        axis = RequestedAxis(
            name=name,
            unit=unit,
            extension=extension,
            values=values,
            indices=indices,
            input_data=input_data,
            noct=noct,
        )
        axes_list.append(axis)
    return axes_list
Ejemplo n.º 21
0
def freq_to_time(self):
    """Performs the inverse Fourier Transform and stores the resulting field in a DataTime object.
    Parameters
    ----------
    self : DataFreq
        a DataFreq object
    Returns
    -------
    a DataTime object
    """

    # Dynamic import to avoid loop
    module = __import__("SciDataTool.Classes.DataTime", fromlist=["DataTime"])
    DataTime = getattr(module, "DataTime")
    module = __import__("SciDataTool.Classes.DataPattern",
                        fromlist=["DataPattern"])
    DataPattern = getattr(module, "DataPattern")

    axes_str = []
    for i, axis in enumerate(self.axes):
        if axis.is_components:
            axis_str = axis.name + str(list(range(len(axis.values))))
        elif axis.name == "freqs":
            axis_str = "time[smallestperiod]"
        elif axis.name == "wavenumber":
            axis_str = "angle[smallestperiod]"
        elif isinstance(axis, DataPattern):
            axis_str = axis.name + "[pattern]"
        else:
            axis_str = axis.name + "[smallestperiod]"
        axes_str.append(axis_str)
    if axes_str == [axis.name for axis in self.axes]:
        raise AxisError(
            "ERROR: No available axis is compatible with fft (should be time or angle)"
        )
    else:
        results = self.get_along(*axes_str)
        values = results.pop(self.symbol)
        Axes = []
        for axis in self.axes:
            if axis.name == "freqs":
                axis_new = Data1D(
                    name="time",
                    is_components=False,
                    values=results["time"],
                    unit="s",
                    symmetries=axis.symmetries.copy(),
                    normalizations=axis.normalizations.copy(),
                )
            elif axis.name == "wavenumber":
                axis_new = Data1D(
                    name="angle",
                    is_components=False,
                    values=results["angle"],
                    unit="rad",
                    symmetries=axis.symmetries.copy(),
                    normalizations=axis.normalizations.copy(),
                )
            else:
                axis_new = axis.copy()
            Axes.append(axis_new)

        return DataTime(
            name=self.name,
            unit=self.unit,
            symbol=self.symbol,
            axes=Axes,
            values=values,
            is_real=self.is_real,
            normalizations=self.normalizations.copy(),
        )
Ejemplo n.º 22
0
def get_harm_rphiz_along(self,
                         N_harm,
                         *args,
                         unit="SI",
                         is_norm=False,
                         axis_data=[]):
    """Returns the list of the cylindrical (r,phi,z) components of the field, 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 field values
    """

    if len(args) == 1 and type(args[0]) == tuple:
        args = args[0]  # if called from another script with *args

    if "x" in self.components.keys() and "y" in self.components.keys():
        # Extract from DataND
        resultx = self.components["x"].get_harmonics(N_harm,
                                                     args,
                                                     unit=unit,
                                                     is_norm=is_norm,
                                                     axis_data=axis_data)
        resulty = self.components["y"].get_harmonics(N_harm,
                                                     args,
                                                     unit=unit,
                                                     is_norm=is_norm,
                                                     axis_data=axis_data)
        field_x = resultx[self.components["x"].symbol]
        field_y = resulty[self.components["y"].symbol]
        shape = field_x.shape
        x = resultx["x"]
        y = resultx["y"]
        # Convert to cylindrical coordinates
        (r, phi) = xy_to_rphi(x, y)
        (field_r, field_t) = cart2pol(field_x, field_y, phi)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_harmonics(
                N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "z" in self.components.keys():
            resultz = self.components["z"].get_harmonics(N_harm,
                                                         args,
                                                         unit=unit,
                                                         is_norm=is_norm,
                                                         axis_data=axis_data)
            field_z = resultz[self.components["z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resultx)
        del return_dict[self.components["x"].symbol]

    elif "radial" in self.components.keys():
        resultr = self.components["radial"].get_harmonics(N_harm,
                                                          args,
                                                          unit=unit,
                                                          is_norm=is_norm,
                                                          axis_data=axis_data)
        field_r = resultr[self.components["radial"].symbol]
        shape = field_r.shape
        if "tangential" in self.components.keys():
            resultphi = self.components["tangential"].get_harmonics(
                N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_t = resultphi[self.components["tangential"].symbol]
        else:
            field_t = zeros(shape)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_harmonics(
                N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "z" in self.components.keys():
            resultz = self.components["z"].get_harmonics(N_harm,
                                                         args,
                                                         unit=unit,
                                                         is_norm=is_norm,
                                                         axis_data=axis_data)
            field_z = resultz[self.components["z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resultr)
        del return_dict[self.components["radial"].symbol]

    elif "tangential" in self.components.keys():
        resultphi = self.components["tangential"].get_harmonics(
            N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
        field_t = resultphi[self.components["tangential"].symbol]
        shape = field_t.shape
        if "radial" in self.components.keys():
            resultr = self.components["radial"].get_harmonics(
                N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_r = resultphi[self.components["radial"].symbol]
        else:
            field_r = zeros(shape)
        if "axial" in self.components.keys():
            resultz = self.components["axial"].get_harmonics(
                N_harm, args, unit=unit, is_norm=is_norm, axis_data=axis_data)
            field_z = resultz[self.components["axial"].symbol]
        elif "z" in self.components.keys():
            resultz = self.components["z"].get_harmonics(N_harm,
                                                         args,
                                                         unit=unit,
                                                         is_norm=is_norm,
                                                         axis_data=axis_data)
            field_z = resultz[self.components["z"].symbol]
        else:
            field_z = zeros(shape)
        return_dict = dict(resultphi)
        del return_dict[self.components["tangential"].symbol]

    elif "axial" in self.components.keys():
        resultz = self.components["axial"].get_harmonics(N_harm,
                                                         args,
                                                         unit=unit,
                                                         is_norm=is_norm,
                                                         axis_data=axis_data)
        field_z = resultz[self.components["axial"].symbol]
        shape = field_z.shape
        field_r = zeros(shape)
        field_t = zeros(shape)
        return_dict = dict(resultz)
        del return_dict[self.components["axial"].symbol]

    elif "z" in self.components.keys():
        resultz = self.components["z"].get_harmonics(N_harm,
                                                     args,
                                                     unit=unit,
                                                     is_norm=is_norm,
                                                     axis_data=axis_data)
        field_z = resultz[self.components["z"].symbol]
        shape = field_z.shape
        field_r = zeros(shape)
        field_t = zeros(shape)
        return_dict = resultz
        del return_dict[self.components["z"].symbol]

    else:
        raise AxisError(
            "Vector_field object is empty (should contain at least radial, tangential, axial, x, y or z"
        )

    return_dict[self.symbol + "_r"] = field_r
    return_dict[self.symbol + "_t"] = field_t
    return_dict[self.symbol + "_z"] = field_z

    return return_dict