diff --git a/dev/API/index.html b/dev/API/index.html index f69d01e..0c31a7b 100644 --- a/dev/API/index.html +++ b/dev/API/index.html @@ -1,5 +1,5 @@ -API Documentation · AlignedSpans

API documentation

AlignedSpans.AlignedSpanType
AlignedSpan(sample_rate::Number, first_index::Int, last_index::Int)

Construct an AlignedSpan directly from a sample_rate and indices.

source
AlignedSpans.SpanRoundingModeType
SpanRoundingMode(start::RoundingMode, stop::RoundingMode)

Creates a rounding object for AlignedSpan to indicate how the AlignedSpan's endpoints should be determined from a given spans endpoints'.

source
AlignedSpans.RoundInwardConstant
RoundInward = SpanRoundingMode(RoundUp, RoundDown)

This is a rounding mode where both ends of the continuous time interval are rounded "inwards" to construct the largest span of indices such that all samples are entirely contained within it.

Example

Consider a signal with sample rate 1 Hz.

Index       1   2   3   4   5
+API Documentation · AlignedSpans

API documentation

AlignedSpans.AlignedSpanType
AlignedSpan(sample_rate::Number, first_index::Int, last_index::Int)

Construct an AlignedSpan directly from a sample_rate and indices.

source
AlignedSpans.SpanRoundingModeType
SpanRoundingMode(start::RoundingMode, stop::RoundingMode)

Creates a rounding object for AlignedSpan to indicate how the AlignedSpan's endpoints should be determined from a given spans endpoints'.

source
AlignedSpans.RoundInwardConstant
RoundInward = SpanRoundingMode(RoundUp, RoundDown)

This is a rounding mode where both ends of the continuous time interval are rounded "inwards" to construct the largest span of indices such that all samples are entirely contained within it.

Example

Consider a signal with sample rate 1 Hz.

Index       1   2   3   4   5
 Time (s)    0   1   2   3   4

Now, consider the time span 1.5s (inclusive) to 2.5s (exclusive). Using brackets to highlight this span:

Index       1   2     3     4   5
 Time (s)    0   1  [  2  )  3   4

In code, this span is described by

julia> using AlignedSpans, Dates, TimeSpans
 
@@ -8,7 +8,7 @@
 AlignedSpan(1.0, 3, 3)
 
 julia> AlignedSpans.indices(aligned)
-3:3

gives an AlignedSpan with indices 3:3.

source
AlignedSpans.RoundSpanDownConstant
RoundSpanDown = SpanRoundingMode(RoundDown, RoundDown)

This is a rounding mode where both ends of the continuous time interval are rounded downwards.

Example

Consider a signal with sample rate 1 Hz.

Index       1   2   3   4   5
+3:3

gives an AlignedSpan with indices 3:3.

source
AlignedSpans.RoundSpanDownConstant
RoundSpanDown = SpanRoundingMode(RoundDown, RoundDown)

This is a rounding mode where both ends of the continuous time interval are rounded downwards.

Example

Consider a signal with sample rate 1 Hz.

Index       1   2   3   4   5
 Time (s)    0   1   2   3   4

Now, consider the time span 1.5s (inclusive) to 2.5s (exclusive). Using brackets to highlight this span:

Index       1   2     3     4   5
 Time (s)    0   1  [  2  )  3   4

In code, this span is described by

julia> using AlignedSpans, Dates, TimeSpans
 
@@ -17,7 +17,7 @@
 AlignedSpan(1.0, 2, 3)
 
 julia> AlignedSpans.indices(aligned)
-2:3

gives an AlignedSpan with indices 2:3.

source
AlignedSpans.AlignedSpanMethod
AlignedSpan(sample_rate, span, mode::SpanRoundingMode)

Creates an AlignedSpan by rounding the left endpoint according to mode.start, and the right endpoint by mode.stop.

If mode.start==RoundUp, then the left index of the resulting span is guaranteed to be inside span. This is accomplished by checking if the left endpoint of the span is exclusive, and if so, incrementing the index after rounding when necessary.

Likewise, if mode.start==RoundDown, then the right index of the resulting span is guaranteed to be inside span. This is accomplished by checking if the right endpoint of the span is exclusive, and if so, decrementing the index after rounding when necessary.

Note: span may be of any type which which provides methods for AlignedSpans.start_index_from_time and AlignedSpans.stop_index_from_time.

source
AlignedSpans.AlignedSpanMethod
AlignedSpan(sample_rate, span, mode::ConstantSamplesRoundingMode)

Creates an AlignedSpan whose left endpoint is rounded according to mode.start, and whose right endpoint is determined so by the left endpoint and the number of samples, given by AlignedSpans.n_samples(sample_rate, duration(span)).

Interface: span may be of any type which which provides a method for AlignedSpans.start_index_from_time and TimeSpans.duration.

More detailed information

This is designed so that if AlignedSpan(sample_rate, span, mode::ConstantSamplesRoundingMode) is applied to multiple spans, with the same sample_rate, and the same durations, then the resulting AlignedSpan's will have the same number of samples.

For this reason, we ask for TimeSpans.duration(span) to be defined, rather than a n_samples(span) function: the idea is that we want to only using the duration and the starting time, rather than the actual number of samples in this particular span.

In contrast, AlignedSpan(sample_rate, span, RoundInward) provides an AlignedSpan which includes only (and exactly) the samples contained within span.

If one wants to create a collection of consecutive, non-overlapping, AlignedSpans each with the same number of samples, then use consecutive_subspans instead.

source
AlignedSpans.consecutive_subspansFunction
consecutive_subspans(span::AlignedSpan, duration::Period; keep_last=true)
-consecutive_subspans(span::AlignedSpan, n_window_samples::Int; keep_last=true)

Creates an iterator of AlignedSpan such that each AlignedSpan has consecutive indices which cover the original span's indices (when keep_last=true).

If keep_last=true (the default behavior), then the last span may have fewer samples than the others, and

  • Each span has n_window_samples samples (which is calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied), except possibly

the last one, which may have fewer.

  • The number of subspans is given by cld(n_samples(span), n_window_samples),
  • The number of samples in the last subspan is r = rem(n_samples(span), n_window_samples) unless r=0, in which

case the the last subspan has the same number of samples as the rest, namely n_window_samples.

  • All of the indices of span are guaranteed to be covered by exactly one subspan

If keep_last=false, then all spans will have the same number of samples:

  • Each span has n_window_samples samples (which is calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied)
  • The number of subspans is given by fld(n_samples(span), n_window_samples)
  • The last part of the span's indices may not be covered (when we can't fit in another subspan of length n_window_samples)
source
AlignedSpans.AlignedSpanMethod
AlignedSpan(sample_rate, span, mode::SpanRoundingMode)

Creates an AlignedSpan by rounding the left endpoint according to mode.start, and the right endpoint by mode.stop.

If mode.start==RoundUp, then the left index of the resulting span is guaranteed to be inside span. This is accomplished by checking if the left endpoint of the span is exclusive, and if so, incrementing the index after rounding when necessary.

Likewise, if mode.start==RoundDown, then the right index of the resulting span is guaranteed to be inside span. This is accomplished by checking if the right endpoint of the span is exclusive, and if so, decrementing the index after rounding when necessary.

Note: span may be of any type which which provides methods for AlignedSpans.start_index_from_time and AlignedSpans.stop_index_from_time.

source
AlignedSpans.AlignedSpanMethod
AlignedSpan(sample_rate, span, mode::ConstantSamplesRoundingMode)

Creates an AlignedSpan whose left endpoint is rounded according to mode.start, and whose right endpoint is determined so by the left endpoint and the number of samples, given by AlignedSpans.n_samples(sample_rate, duration(span)).

Interface: span may be of any type which which provides a method for AlignedSpans.start_index_from_time and TimeSpans.duration.

More detailed information

This is designed so that if AlignedSpan(sample_rate, span, mode::ConstantSamplesRoundingMode) is applied to multiple spans, with the same sample_rate, and the same durations, then the resulting AlignedSpan's will have the same number of samples.

For this reason, we ask for TimeSpans.duration(span) to be defined, rather than a n_samples(span) function: the idea is that we want to only using the duration and the starting time, rather than the actual number of samples in this particular span.

In contrast, AlignedSpan(sample_rate, span, RoundInward) provides an AlignedSpan which includes only (and exactly) the samples contained within span.

If one wants to create a collection of consecutive, non-overlapping, AlignedSpans each with the same number of samples, then use consecutive_subspans instead.

source
AlignedSpans.consecutive_subspansFunction
consecutive_subspans(span::AlignedSpan, duration::Period; keep_last=true)
+consecutive_subspans(span::AlignedSpan, n_window_samples::Int; keep_last=true)

Creates an iterator of AlignedSpan such that each AlignedSpan has consecutive indices which cover the original span's indices (when keep_last=true).

If keep_last=true (the default behavior), then the last span may have fewer samples than the others, and

  • Each span has n_window_samples samples (which is calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied), except possibly

the last one, which may have fewer.

  • The number of subspans is given by cld(n_samples(span), n_window_samples),
  • The number of samples in the last subspan is r = rem(n_samples(span), n_window_samples) unless r=0, in which

case the the last subspan has the same number of samples as the rest, namely n_window_samples.

  • All of the indices of span are guaranteed to be covered by exactly one subspan

If keep_last=false, then all spans will have the same number of samples:

  • Each span has n_window_samples samples (which is calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied)
  • The number of subspans is given by fld(n_samples(span), n_window_samples)
  • The last part of the span's indices may not be covered (when we can't fit in another subspan of length n_window_samples)
source
AlignedSpans.consecutive_overlapping_subspansFunction
consecutive_overlapping_subspans(span::AlignedSpan, duration::Period,
                                  hop_duration::Period)
-consecutive_overlapping_subspans(span::AlignedSpan, n_window_samples::Int, n_hop_samples::Int)

Create an iterator of AlignedSpan such that each AlignedSpan has n_window_samples (calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied) samples, shifted by n_hop_samples (calculated as n_samples(span.sample_rate, hop_duration) if hop_duration::Period is supplied) samples between consecutive spans.

Warning

When n_samples(span) is not an integer multiple of n_window_samples, only AlignedSpans with n_window_samples samples will be returned. This is analgous to consecutive_subspans with keep_last=false, which is not the default behavior for consecutive_subspans.

Note: If hop_duration cannot be represented as an integer number of samples, rounding will occur to ensure that all output AlignedSpans will have the same number of samples. When rounding occurs, the output hop_duration will be: Nanosecond(n_samples(samp_rate, hop_duration) / samp_rate * 1e9)

source
AlignedSpans.n_samplesFunction
n_samples(sample_rate, duration::Union{Period, Dates.CompoundPeriod})

Returns the minimal number of samples that can occur in a span of duration.

source
n_samples(aligned::AlignedSpan)

Returns the number of samples present in the span aligned.

source
AlignedSpans.indicesFunction
AlignedSpans.indices(span::AlignedSpan) -> UnitRange{Int64}

Returns the sample indices associated to an AlignedSpan.

source

Interface for conversion from continuous time spans

In order to support conversion of continuous time span types to AlignedSpan's, three methods may be defined. These are not exported, because they are generally not used directly, but rather defined in order to facilitate use of the AlignedSpan constructors.

+consecutive_overlapping_subspans(span::AlignedSpan, n_window_samples::Int, n_hop_samples::Int)

Create an iterator of AlignedSpan such that each AlignedSpan has n_window_samples (calculated as n_samples(span.sample_rate, duration) if duration::Period is supplied) samples, shifted by n_hop_samples (calculated as n_samples(span.sample_rate, hop_duration) if hop_duration::Period is supplied) samples between consecutive spans.

Warning

When n_samples(span) is not an integer multiple of n_window_samples, only AlignedSpans with n_window_samples samples will be returned. This is analgous to consecutive_subspans with keep_last=false, which is not the default behavior for consecutive_subspans.

Note: If hop_duration cannot be represented as an integer number of samples, rounding will occur to ensure that all output AlignedSpans will have the same number of samples. When rounding occurs, the output hop_duration will be: Nanosecond(n_samples(samp_rate, hop_duration) / samp_rate * 1e9)

source
AlignedSpans.n_samplesFunction
n_samples(sample_rate, duration::Union{Period, Dates.CompoundPeriod})

Returns the minimal number of samples that can occur in a span of duration.

source
n_samples(aligned::AlignedSpan)

Returns the number of samples present in the span aligned.

source
AlignedSpans.indicesFunction
AlignedSpans.indices(span::AlignedSpan) -> UnitRange{Int64}

Returns the sample indices associated to an AlignedSpan.

source

Interface for conversion from continuous time spans

In order to support conversion of continuous time span types to AlignedSpan's, three methods may be defined. These are not exported, because they are generally not used directly, but rather defined in order to facilitate use of the AlignedSpan constructors.

diff --git a/dev/index.html b/dev/index.html index 71cc4ea..637fb91 100644 --- a/dev/index.html +++ b/dev/index.html @@ -15,4 +15,4 @@ true julia> duration(aligned) == duration(ts) == Second(2) -true
Warning

For non-integer sample rates, roundtripping perfectly is not always possible.

Note on roundtripping

Quick example

Let's consider the following TimeSpan

julia> using TimeSpans, AlignedSpans, Dates
julia> span = TimeSpan(Millisecond(1500), Millisecond(3500))TimeSpan(00:00:01.500000000, 00:00:03.500000000)

If we have a 1 Hz signal, there are various ways we can index into it using this TimeSpan. One option is to round the endpoints down:

julia> down_span = AlignedSpan(1, span, RoundSpanDown)AlignedSpan(1.0, 2, 4)
julia> n_samples(down_span)3

The second sample of our signal occurs at time 1s (since we have a 1Hz signal that starts at 0s). When we round the starting endpoint down from 1.5s to the nearest sample, we find that sample. This can be seen as "the last sample that occurred before time 1.5s".

Perhaps instead we would like to round the endpoints "inward" to only consider samples occurring with the time span:

julia> in_span = AlignedSpan(1, span, RoundInward)AlignedSpan(1.0, 3, 4)
julia> n_samples(in_span)2

Motivation

Let's say I want to plot some samples over time, and I have a nice function plot(::TimeSpan, ::Samples) to use.

julia> using TimeSpans, Onda, Dates
julia> sample_rate = 1 # 1 Hz -> slow to exaggerate the effect1
julia> samples = Samples(permutedims(0:10), SamplesInfo("feature", ["a"], "microvolt", 0.5, 0.0, UInt16, sample_rate), false)ERROR: UndefVarError: `SamplesInfo` not defined
julia> span = TimeSpan(Millisecond(1500), Millisecond(4000))TimeSpan(00:00:01.500000000, 00:00:04.000000000)

Now I want to execute some call

plot(span, samples[:, span])

for some plot that understands TimeSpans – doesn't matter what function, exactly.

What is wrong with this?

Let's take a look at the samples we are plotting:

julia> samples[:, span] # TimeSpans v0.2; v0.3 will have one more sampleERROR: UndefVarError: `samples` not defined

These are three samples that correspond to times 1s, 2s, and 3s. However, what we gave to the x-axis of our plotting function is TimeSpan(Millisecond(1500), Millisecond(3500)), which starts at 1.5s and goes to 3.5s. In other words, our plot will have an incorrect 0.5s offset!

Note that plot is just an example; any function where one is separately passing both a "timespan of interest" and "feature values from that timespan" will have similar issues if one isn't careful about what exactly samples[:, span] is doing.

The fix

Let's take the same setup, with our

julia> spanTimeSpan(00:00:01.500000000, 00:00:04.000000000)

This time, we do

julia> using AlignedSpans
julia> aligned_span = AlignedSpan(samples.info.sample_rate, span, RoundSpanDown)ERROR: UndefVarError: `samples` not defined
julia> samples[:, aligned_span]ERROR: UndefVarError: `samples` not defined

Here, I get the same samples. However, now I have the actual span corresponding to those samples, namely aligned_span. So if I call my

plot(aligned_span, samples[:, aligned_span])

I'll have the correct alignment between the points on the x-axis and y-axis.

+true
Warning

For non-integer sample rates, roundtripping perfectly is not always possible.

Note on roundtripping

Quick example

Let's consider the following TimeSpan

julia> using TimeSpans, AlignedSpans, Dates
julia> span = TimeSpan(Millisecond(1500), Millisecond(3500))TimeSpan(00:00:01.500000000, 00:00:03.500000000)

If we have a 1 Hz signal, there are various ways we can index into it using this TimeSpan. One option is to round the endpoints down:

julia> down_span = AlignedSpan(1, span, RoundSpanDown)AlignedSpan(1.0, 2, 4)
julia> n_samples(down_span)3

The second sample of our signal occurs at time 1s (since we have a 1Hz signal that starts at 0s). When we round the starting endpoint down from 1.5s to the nearest sample, we find that sample. This can be seen as "the last sample that occurred before time 1.5s".

Perhaps instead we would like to round the endpoints "inward" to only consider samples occurring with the time span:

julia> in_span = AlignedSpan(1, span, RoundInward)AlignedSpan(1.0, 3, 4)
julia> n_samples(in_span)2

Motivation

Let's say I want to plot some samples over time, and I have a nice function plot(::TimeSpan, ::Samples) to use.

julia> using TimeSpans, Onda, Dates
julia> sample_rate = 1 # 1 Hz -> slow to exaggerate the effect1
julia> samples = Samples(permutedims(0:10), SamplesInfo("feature", ["a"], "microvolt", 0.5, 0.0, UInt16, sample_rate), false)ERROR: UndefVarError: `SamplesInfo` not defined
julia> span = TimeSpan(Millisecond(1500), Millisecond(4000))TimeSpan(00:00:01.500000000, 00:00:04.000000000)

Now I want to execute some call

plot(span, samples[:, span])

for some plot that understands TimeSpans – doesn't matter what function, exactly.

What is wrong with this?

Let's take a look at the samples we are plotting:

julia> samples[:, span] # TimeSpans v0.2; v0.3 will have one more sampleERROR: UndefVarError: `samples` not defined

These are three samples that correspond to times 1s, 2s, and 3s. However, what we gave to the x-axis of our plotting function is TimeSpan(Millisecond(1500), Millisecond(3500)), which starts at 1.5s and goes to 3.5s. In other words, our plot will have an incorrect 0.5s offset!

Note that plot is just an example; any function where one is separately passing both a "timespan of interest" and "feature values from that timespan" will have similar issues if one isn't careful about what exactly samples[:, span] is doing.

The fix

Let's take the same setup, with our

julia> spanTimeSpan(00:00:01.500000000, 00:00:04.000000000)

This time, we do

julia> using AlignedSpans
julia> aligned_span = AlignedSpan(samples.info.sample_rate, span, RoundSpanDown)ERROR: UndefVarError: `samples` not defined
julia> samples[:, aligned_span]ERROR: UndefVarError: `samples` not defined

Here, I get the same samples. However, now I have the actual span corresponding to those samples, namely aligned_span. So if I call my

plot(aligned_span, samples[:, aligned_span])

I'll have the correct alignment between the points on the x-axis and y-axis.

diff --git a/dev/search/index.html b/dev/search/index.html index b44e32f..d07b2b4 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · AlignedSpans

Loading search...

    +Search · AlignedSpans

    Loading search...