Exemple #1
0
def current_rms(current, period_length=PERIOD_LENGTH):
    """Calculates the Current RMS (CRMS).

    Let \\(I_{W(k)}\\) denote the \\(k\\)th of \\(N\\) periods of current
    measurements, \\(\\langle t_1, t_2, ..., t_n \\rangle\\) the
    concatenation of tuples \\(t_1, ..., t_n\\), and \\(\\nu = N \\mod 10\\).
    Then:

    \\[CRMS = \\begin{pmatrix}\\text{rms}(\\langle I_{W(1)}, I_{W(2)}, ...,
    I_{W(10)}\\rangle) \\\\ \\text{rms}(\\langle I_{W(11)}, I_{W(12)}, ...,
    I_{W(20)}\\rangle) \\\\ ... \\\\ \\text{rms}(\\langle I_{W(N - \\nu + 1)},
    I_{W(N - \\nu + 2)}, ..., I_{W(N)}\\rangle)\\end{pmatrix}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.
        n_periods (int): Length of transient and steady state in periods

    Returns:
        numpy.ndarray: Transient steady states ratio as a (n_samples, 1)-dimensional array.
    """
    n = int(math.floor(current.shape[1] / period_length / 10))
    cutoff = n * 10 * period_length
    first = rms(current[:, :cutoff].reshape(-1, n, 10 * period_length), axis=2)

    # Handle window_size is not multiple of 10*period_length
    if cutoff != current.shape[1]:
        return np.hstack((first, rms(current[:, cutoff:])))
    return first
Exemple #2
0
def positive_negative_half_cycle_ratio(current, period_length=PERIOD_LENGTH):
    """Calculates Positive-negative half cycle ratio (PNR).

    Let \\(I_{P_\\text{pos}}\\) and \\(I_{P_\\text{neg}}\\) be the RMS of 10
    averaged positive and negative current half cycles. Then

    \\[PNR = \\frac{\\min\\{I_{P_\\text{pos}}, I_{P_\\text{neg}}\\}}
                   {\\max\\{I_{P_\\text{pos}}, I_{P_\\text{neg}}\\}}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: PNR as a (n_samples, 1)-dimensional array.
    """
    # Create indices for positive and negative half cycles of sin wave
    idcs = np.arange(0, period_length * 10)
    p_idcs = idcs[idcs % period_length < period_length / 2]
    n_idcs = idcs[idcs % period_length >= period_length / 2]

    p_current = current[:, p_idcs].reshape(-1, 10, period_length // 2)
    n_current = current[:, n_idcs].reshape(-1, 10, period_length // 2) * -1

    # Calculate RMS of averaged half cycles
    p_n = np.hstack((rms(np.mean(p_current,
                                 axis=1)), rms(np.mean(n_current, axis=1))))

    return (np.min(p_n, axis=1) / np.max(p_n, axis=1)).reshape(-1, 1)
Exemple #3
0
def apparent_power(voltage, current):
    """Calculates Apparent power (S).

    \\[S = \\text{rms}(V) \\times \\text{rms}(I)\\]

    Args:
        voltage (numpy.ndarray): (n_samples, window_size)-dimensional array of voltage measurements.
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Apparent power as a (n_samples, 1)-dimensional array.
    """
    return rms(voltage) * rms(current)
Exemple #4
0
def resistance_mean(voltage, current):
    """Calculates Resistance \\(R_\\text{mean}\\) (mean version) from
    voltage and current arrays.

    \\[R_\\text{mean} = \\frac{\\sqrt{\\text{mean}(V^2)}}{\\sqrt{\\text{mean}(I^2)}}\\]

    Args:
        voltage (numpy.ndarray): (n_samples, window_size)-dimensional array of voltage measurements.
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Resistance as a (n_samples, 1)-dimensional array.
    """
    return rms(voltage) / rms(current)
Exemple #5
0
def inrush_current_ratio(current, period_length=PERIOD_LENGTH):
    """Calculates the Inrush current ratio (ICR).

    Let \\(I_{W(k)}\\) denote the \\(k\\)th of \\(N\\) periods of current
    measurements. Then \\(I_{P(k)} = \\text{rms}(I_{W(k)})\\) and

    \\[ICR =  \\frac{I_{P(1)}}{I_{P(N)}}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Inrush current ratio as a (n_samples, 1)-dimensional array.
    """
    return rms(current[:, :period_length]) / rms(current[:, -period_length:])
Exemple #6
0
def temporal_centroid(current,
                      mains_frequency=POWER_FREQUENCY,
                      period_length=PERIOD_LENGTH):
    """Calculates the Temporal centroid \\(C_t\\).

    Let \\(I_{W(k)}\\) denote the \\(k\\)th of \\(N\\) periods of current
    measurements. Then \\(I_{P(k)} = \\text{rms}(I_{W(k)})\\) and
    \\[C_t = \\frac{1}{f_0} \\cdot \\frac{\\sum_{k=1}^N I_{P(k)} \\cdot k}
       {\\sum_{k=1}^N I_{P(k)}} \\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.
        mains_frequency (int): Mains frequency, defaults to power frequency.

    Returns:
        numpy.ndarray: Temporal centroid as a (n_samples, 1)-dimensional array.
    """
    # Calculate RMS of each period
    # TODO: Use apply_to_periods?
    ip = rms(current.reshape(current.shape[0], -1, period_length), axis=2)

    # Calculate numerator and denominator and put together
    numerator = np.sum(ip * np.arange(1, ip.shape[1] + 1), axis=1)
    denominator = np.sum(ip, axis=1)
    return mains_frequency * (numerator / denominator).reshape(-1, 1)
Exemple #7
0
def crest_factor(current):
    """Calculates Crest factor (CF).

    \\[CF = \\frac{\\max(|I|)}{\\text{rms}(I)}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Crest factor as a (n_samples, 1)-dimensional array.
    """
    return np.max(np.abs(current), axis=1).reshape(-1, 1) / rms(current)
Exemple #8
0
def form_factor(current):
    """Calculates Form factor (FF).

    \\[FF = \\frac{\\text{rms}(I)}{\\text{mean}(|I|)}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Form factor as a (n_samples, 1)-dimensional array.
    """
    return rms(current) / np.mean(np.abs(current), axis=1).reshape(-1, 1)
Exemple #9
0
def transient_steady_states_ratio(current,
                                  n_periods=5,
                                  period_length=PERIOD_LENGTH):
    """Calculates the Transient steady states ratio (TSSR).

    Let \\(I_{W(k)}\\) denote the \\(k\\)th of \\(N\\) periods of current
    measurements and \\(\\langle t_1, t_2, ..., t_n \\rangle\\) the
    concatenation of tuples \\(t_1, ..., t_n\\). Then:

    \\[TSSR = \\frac{\\text{rms}(\\langle I_{W(1)}, I_{W(2)}, ...,
    I_{W(\\text{n_periods})}\\rangle)}
    {\\text{rms}(\\langle I_{W(N - \\text{n_periods})},
    I_{W(N - \\text{n_periods} + 1)}, ..., I_{W(N)}\\rangle)}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.
        n_periods (int): Length of transient and steady state in periods

    Returns:
        numpy.ndarray: Transient steady states ratio as a (n_samples, 1)-dimensional array.
    """
    return (rms(current[:, :n_periods * period_length]) /
            rms(current[:, -n_periods * period_length:])).reshape(-1, 1)
Exemple #10
0
def reactive_power(voltage,
                   current,
                   phase_shift=None,
                   period_length=PERIOD_LENGTH):
    """Calculates Reactive power (Q).

    If phase shift is None, it is calculated.

    \\[Q = \\text{rms}(V) \\times \\text{rms}(I) \\times \\sin(\\phi)\\]

    Args:
        voltage (numpy.ndarray): (n_samples, window_size)-dimensional array of voltage measurements.
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.
        phase_shift (numpy.ndarray): (n_samples, 1)-dimensional array of phase shifts.

    Returns:
        numpy.ndarray: Reactive power as a (n_samples, 1)-dimensional array.
    """
    if phase_shift is None:
        phase_shift = phase_shift(voltage,
                                  current,
                                  period_length=period_length)

    return np.abs(rms(voltage) * rms(current) * np.sin(phase_shift))
Exemple #11
0
def max_inrush_ratio(current, period_length=PERIOD_LENGTH):
    """Calculates the Max inrush ratio (MIR).

    Let \\(I_{W(k)}\\) be the current measurements of the \\(k\\)th period and
    \\(I_{P(k)} = \\text{rms}(I_{W(k)})\\). Then

    \\[MIR = \\frac{I_{P(1)}}{\\max(|I_{W(1)}|)}\\]

    Args:
        current (numpy.ndarray): (n_samples, window_size)-dimensional array of current measurements.

    Returns:
        numpy.ndarray: Max inrush ratio as a (n_samples, 1)-dimensional array.
    """
    first_period_rms = rms(current[:, :period_length])
    first_period_max = np.max(np.abs(current[:, :period_length]), axis=1)
    return first_period_rms / first_period_max.reshape(-1, 1)
def total_harmonic_distortion(harmonics_amp, spectrum_amp):
    """Calculates the Total harmonic distortion (THD).

    Let \\(x_{f_1}, ..., x_{f_{20}}\\) be the amplitudes of the first 20
    harmonics of the current and \\(x_{f_0}\\) the mains frequency amplitude.
    Then:

    \\[THD = \\frac{\\text{rms}([x_{f_1}, x_{f_2}, x_{f_3}, ..., x_{f_{20}}])}
                   {x_{f_0}}\\]

    Args:
        harmonics_amp (numpy.ndarray): Harmonic amplitudes as a (n_samples, n)-dimensional array.
        spectrum_amp (numpy.ndarray): Spectral amplitudes as a (n_samples, window)-dimensional array.

    Returns:
        numpy.ndarray: Total harmonic distortion as a (n_samples, 1)-dimensional array.
    """
    return (rms(harmonics_amp) / _mains_frequency_amplitude(spectrum_amp))