Traces#

Trace#

class mhi.enerplot.Trace(initializer=None, domain=None)#

A trace is an array of numbers which hold the value of a signal as it changes over some domain. For instance, a trace may contain a voltage value as it changes over time.

Channels and Curves both extend from the Trace class.

property data#

Data (y-axis values) of the trace

property domain#

Domain (x-axis values, such as time) of the trace

property read_only#

Whether or not the data is immutable

increasing() bool#

Test if a trace contains strictly increasing values.

A strictly increasing trace is suitable to use as the domain of a dataset.

Returns:

True if every value is larger than the previous one.

decreasing() bool#

Test if a trace contains strictly decreasing values.

Returns:

True if every value is smaller than the previous one.

Basic Operations#

Many basic operations are already possible on a Trace. All operations return a new trace; the original trace is unmodified.

Given the trace a the following unary operations exist:

Operators

Operation

len(a)

Number of data points in the trace

a[n]

Access the n-th data point in the trace

-a

Negation of all values in the trace

abs(a)

Absolute value of all values

math.ceil(a)

Values rounded up to an integer

math.floor(a)

Values rounded down to an integer

math.trunc(a)

Values truncate towards zero

Given two traces, a and b, or a trace and a scalar number in either order, the following operations exist:

Operators

Operation

a + b

Addition

a - b

Subtraction

a * b

Multiplication

a / b

Division

a ** b

Exponentiation

Note

If an operation is performed on two traces of different lengths, these operations will the result in a trace which matches the length of the shorter of the two traces. The extra data in the longer trace is ignored.

Convolution#

Given two traces, a and b, the operation a @ b returns a convolution of the two traces.

For example, given the Finite Impulse Response of a transfer function, the output signal can be created by convolving the input with the finite impulse response:

fir = mhi.enerplot.Trace([0.75, 1.0, 0.5, 0.25, 0.125])

output = input @ fir

The length of the output is 1 sample less than the sum of the lengths of the two input traces.

Other Operations#

Additional operations on traces require importing methods from the mhi.enerplot.math library.

Example:

The following computed trace would approximate the full wave rectifier output:

from mhi.enerplot.math import minimum, maximum

cigre = enerplot.datafile('Cigre_47.csv')

a = cigre[r'Rectifier\AC Voltage:1']
b = cigre[r'Rectifier\AC Voltage:2']
c = cigre[r'Rectifier\AC Voltage:3']

rectifier_out = maximum(a, b, c) - minimum(a, b, c)

Logarthimic#

mhi.enerplot.math.exp(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → e^x.

mhi.enerplot.math.ln(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → logₑ(x).

All values less than or equal to zero are replaced with NaN

mhi.enerplot.math.log(trace: Trace, base=2.718281828459045) Trace#

Return a new trace where every value is transformed as: x → logₐ(x). The default base is “e”, for the natural logarithm.

All values less than or equal to zero are transformed to NaN

mhi.enerplot.math.log10(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → log₁₀(x).

All values less than or equal to zero are transformed to NaN

mhi.enerplot.math.sqrt(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → √x.

All values less than or equal to zero are transformed to NaN

Circular#

mhi.enerplot.math.degrees(trace: Trace) Trace#

Return a new trace where every value is transformed from radians to degrees.

mhi.enerplot.math.radians(trace: Trace) Trace#

Return a new trace where every value is transformed from degrees to radians.

mhi.enerplot.math.sin(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → sin(x).

The input to the sin(x) function is intrepeted as being in radians.

mhi.enerplot.math.cos(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → cos(x).

The input to the cos(x) function is intrepeted as being in radians.

mhi.enerplot.math.tan(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → tan(x).

The input to the tan(x) function is intrepeted as being in radians.

mhi.enerplot.math.asin(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → sin⁻¹(x).

The output of the sin⁻¹(x) function is in radians.

NaN is returned for all values greater than 1, or less than -1.

mhi.enerplot.math.acos(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → cos⁻¹(x).

The output of the cos⁻¹(x) function is in radians.

NaN is returned for all values greater than 1, or less than -1.

mhi.enerplot.math.atan(trace: Trace) Trace#

Return a new trace where every value is transformed as: x → tan⁻¹(x).

The output of the tan⁻¹(x) function is in radians.

mhi.enerplot.math.hypot(x: Trace, y: Trace) Trace#

Compute a new trace, returning the Euclidean distance, sqrt(x*x + y*y), for each pair of values from the two input traces.

The follow two statements produce equivalent output:

from mhi.enerplot.math import hypot, sqrt

c = hypot(a, b)
c = sqrt(a ** 2 + b ** 2)

The first statement is significantly faster since the second statement requires allocating several temporary traces for holding the intermediate results.

mhi.enerplot.math.atan2(y: Trace, x: Trace) Trace#

Compute a new trace, returning the arc tangent (measured in radians) of y/x, for each pair of values from the two input traces. Unlike atan(y/x), the signs of both x and y are considered.

When used in conjunction with the hypot(), two traces representing real and imaginary values may be converted into two traces representing polar coordinates: magnitude and angle.

Selection#

mhi.enerplot.math.maximum(*traces: Trace) Trace#

Return a new trace where the maximum value from each trace, at each point, is selected.

mhi.enerplot.math.minimum(*traces: Trace) Trace#

Return a new trace where the minimum value from each trace, at each point, is selected.

Processing#

mhi.enerplot.math.smooth(trace: Trace, time_constant: float, domain: Trace | Sequence[float] | float | None = None) Trace#

Return a smoothed version of the input trace.

This function simulates a lag or ‘real pole’ function. The time domain solution algorithm is based on the trapezoidal rule. The solution method for this function is as follows:

Parameters:
  • trace (Trace) – the input to be smoothed.

  • time_constant (float) – the time-constant to be used for smoothing

  • domain (float or trace) – the time-step, or the signal domain

Examples

If input represents a Curve from a DataFile with a 50µs timestep, the following statements would produce the same output:

from mhi.enerplot.math import smooth

output = smooth(input, 0.001, 50e-6)
output = smooth(input, 0.001, input.domain)