# 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.

`increasing`()

Test if a trace contains strictly increasing values.

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

Returns: `True` if every value is larger than the previous one. bool
`decreasing`()

Test if a trace contains strictly decreasing values.

Returns: `True` if every value is smaller than the previous one. bool

## Basic Operations¶

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

Given a 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
`abs(a)` Absolute value
`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, the 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)

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

`mhi.enerplot.math.``ln`(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, base=2.718281828459045)

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)

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)

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)

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

`mhi.enerplot.math.``radians`(trace)

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

`mhi.enerplot.math.``sin`(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)

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

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

`mhi.enerplot.math.``tan`(trace)

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

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

`mhi.enerplot.math.``asin`(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)

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)

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, y)

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, x)

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)

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

`mhi.enerplot.math.``minimum`(*traces)

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

### Processing¶

`mhi.enerplot.math.``smooth`(trace, time_constant, domain)

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)
```