Reading the profile¶
tsdive profile reports what the historian did to one tag over one
window, before any statistic is trusted. This is the full report on the
demo flow, then every line in plant terms.
$ tsdive profile data/demo/fic101_demo.parquet \
--window 2024-03-30T20:00:00Z/2024-03-31T06:00:00Z \
--tz Europe/London --flatline
demo:FIC101.PV FIC-101 flow
coverage 0.933 GOOD 561/562 censored yes gaps 1 flatline NOT ASSESSED
window 2024-03-30 20:00:00Z -> 2024-03-31 06:00:00Z (10 h)
contract TIME_WEIGHTED RECORDED NONE stepped no digest d59d433d9c62
units m3/h -> cubic meters per hour
Coverage
coverage 0.933 valid 0.998 gaps 1 data-loss gaps 1 longest 40 min
2024-03-30 23:00:00Z -> 23:40:00Z 40 min unknown (no rule matched)
Quality
GOOD 561 UNCERTAIN 1 BAD 0
unmapped codes, treated UNCERTAIN: SENSOR DRIFT
Range
clipped 0.0516 censored yes
Timestamps
audited 562 duplicates 0 non-monotonic 0
DST (Europe/London) 2024-03-31 01:00:00Z +0h -> +1h
Values GOOD n=561
min 60.86 p05 61.20 median 62.32 p95 100.0 max 100.0
mean 63.95 (time-weighted) std 8.399 mad 0.4017
distinct 533 stall 0 s changes/h 53.20
constant run 2024-03-31 02:01:00Z -> 02:29:00Z 28 min n=29
interval 60 s (p05 60 s, p95 60 s) declared 60 s
Flatline
NOT ASSESSED (window censored; saturated != frozen)
Headline¶
demo:FIC101.PV FIC-101 flow: the tag's identity, historian and point, then its display name.coverage 0.933: the share of the window not lost to a data-loss gap.GOOD 561/562: samples whose quality reads GOOD, out of all samples.censored yes: at least one sample sits at an end of the engineering range.nomeans none does;unknownmeans no range is declared.gaps 1: gaps of any class.flatline NOT ASSESSED: the frozen-sensor check did not run; the Flatline section says why. Without--flatlinethe field is absent.
Read the headline first. When it reads well (coverage near 1, nearly
every sample GOOD, censored no, no gaps, flatline none), the
statistics below describe the process and not the historian.
flatline SUSPECTED means one of the flatline signals fired.
What was read¶
window: the span read, in UTC, and its length.contract: the sampling contract, four fields and a digest of them.units m3/h -> cubic meters per hour:unit_rawfrom the metadata and what it resolved to.unresolved (null)means the spelling is not in the alias table.
Coverage¶
coverage 0.933 valid 0.998: time not lost to gaps, and rows that are GOOD and a number. See coverage and gap classes.gaps 1 data-loss gaps 1 longest 40 min: every gap, the data-loss ones, and the longest.- One line per gap: start, end, length, class and rule.
unknown (no rule matched)is a data-loss class. edge slack, when present: time at the window's edges shorter than the gap threshold, counted as covered.
Quality¶
GOOD 561 UNCERTAIN 1 BAD 0: samples per severity.unmapped codes, treated UNCERTAIN: SENSOR DRIFT: codes no rule knows. Declare each in the tag'squality_codes. See quality codes and severity.
Range¶
clipped 0.0516: the share of samples at an end of the engineering range, 29 of 562.censored yes: the verdict the headline repeats. See clipping and censoring.
Timestamps¶
audited 562 duplicates 0 non-monotonic 0: samples checked, repeated timestamps, and timestamps that go backwards. A backwards timestamp stops the read withNonMonotonicIndexinstead of reaching this line.DST (Europe/London) 2024-03-31 01:00:00Z +0h -> +1h: a clock change inside the window in a zone--tznamed. The archive is in UTC, so no sample moved; a local shift report has an hour less that night.
Values¶
Statistics over the GOOD samples only, n=561 here.
min 60.86 p05 61.20 median 62.32 p95 100.0 max 100.0: the range and the 5th, 50th and 95th percentiles in m3/h. A p95 at the range end says at least 5% of the samples are clipped.mean 63.95 (time-weighted): each sample counts for the time until the next one.std 8.399 mad 0.4017: standard deviation and median absolute deviation. The half hour at 100 m3/h inflates the standard deviation to 8.4 m3/h, while 1.4826 times the MAD is 0.60 m3/h.distinct 533: how many different values the GOOD samples hold. A handful on a measurement points at heavy rounding or a frozen value.stall 0 s: time since the value last changed, at the end of the window. Hours on a measurement point at a frozen sensor. A value that froze and moved again before the window end has a stall of 0 s.constant run 2024-03-31 02:01:00Z -> 02:29:00Z 28 min n=29: the constant run, the longest stretch of GOOD samples holding one value. The line gives its first and last sample, the time between them and the sample count. Here it is the half hour at full scale. A freeze that ended before the window end shows here and not install. The line carries no verdict, because a tag archived on exception or compression settings also holds one value for hours.changes/h 53.20: value changes per hour. A 60 s tag that changes every sample makes about 60.interval 60 s (p05 60 s, p95 60 s) declared 60 s: the median spacing between samples, its 5th and 95th percentiles, andsample_rate_s.(differs from declared)follows when they disagree.
Flatline¶
NOT ASSESSED (window censored; saturated != frozen): the flatline check compares the window's stall time and distinct count with the tag's own history in earlier windows of the same length, and reports each signal on its own. A censored window is not assessed, because a transmitter pinned at full scale also reads flat. A MODE tag, a window with no valid sample and a window with no history to compare against are not assessed either.
What to do next¶
- Coverage below 1: find the gap lines and check the collector for those times.
- Unmapped codes: declare them, then profile again.
censored yes: keep the clipped stretch out of any baseline.censored unknown: declare the engineering range.- The whole report as one JSON object:
tsdive profile --json, orProfile.to_dict()in Python.