Temporal Windows
Extracting and Comparing Time Intervals
When a query includes a QueryOntologyCatalog filter, a matched topic doesn't just tell you that its condition was satisfied but also when. Starting from a query response, you can compute and compare these time intervals: split a single topic's matches into distinct windows, or check whether two different signals were true at the same moment. This guide walks through the two operations you'll reach for most often:
clusterize(): retrieve and merge all the time intervals associated to one topic where the query is satisfied.intersect()on aQueryResponseItem: retrieve and compare time intervals across all of a sequence's topics at once, finding whether they were simultaneously true.
Two related operations are covered only in Key Concepts below, with a link to the full reference: clusterize_all() (the sequence-wide counterpart of clusterize()) and the topic-level intersect() (for correlating a hand-picked set of topics, even across different queries or sequences).
- Python
- C++
- Rust
The C++ SDK is currently in development.
The Rust SDK is currently in development.
Splitting a Topic's Matches with clusterize()
clusterize() takes the overall samples timestamps where a single topic's query condition held true and merges them into distinct clusters: timestamps nearer than clustering_dt_ns nanoseconds are merged into the same cluster, timestamps further apart become separate ones.
clustering_dt_ns controls how many clusters a topic's own matches form: a small gap threshold keeps nearby-but-distinct matches apart, a large one merges them.
- Python
- C++
- Rust
from mosaicolabs import IMU, MosaicoClient, Query, QueryOntologyCatalog, QuerySequence
with MosaicoClient.connect("localhost", 6726) as client:
query = Query(
QuerySequence().with_name_match("test_drive"),
QueryOntologyCatalog().with_expression(IMU.Q.acceleration.x.gt(5.0)),
)
qresponse = client.query(query=query)
if qresponse is not None:
for item in qresponse:
for topic in item.topics:
for cluster in topic.clusterize(clustering_dt_ns=int(1e8)): # 100ms
print(f"{topic.name}: {cluster}")
The C++ SDK is currently in development.
The Rust SDK is currently in development.
See Topic clusterize for the full parameter reference and visual examples of how clustering_dt_ns shapes the result.
Correlating All of a Sequence's Topics with intersect()
intersect() can be called directly on a QueryResponseItem, correlating every topic matched within that sequence at once instead of picking topics one by one. It merges every topic's query expressions into a single server-side request and returns only the time windows where all of them were simultaneously true. This is how you answer questions that span more than one sensor, such as "was the IMU spiking while pressure was low and temperature was exactly at the target value?"
Every window where all topics are simultaneously true becomes a cluster; tuning intersect_dt_ns lets near-miss windows across topics count as correlated too.
- Python
- C++
- Rust
from mosaicolabs import IMU, MosaicoClient, Pressure, Query, QueryOntologyCatalog, QuerySequence, Temperature
with MosaicoClient.connect("localhost", 6726) as client:
query = Query(
QuerySequence().with_name_match("robot-1"),
QueryOntologyCatalog()
.with_expression(IMU.Q.acceleration.z.gt(5.0))
.with_expression(Pressure.Q.value.lt(1.0))
.with_expression(Temperature.Q.value.eq(500.0)),
)
qresponse = client.query(query=query)
if qresponse is not None:
for item in qresponse:
intersected_clusters = item.intersect(override_clustering_dt_ns=2000)
print(f"{item.sequence.name}: {[str(c) for c in intersected_clusters]}")
The C++ SDK is currently in development.
The Rust SDK is currently in development.
See Sequence intersect for the full parameter reference, including intersect_dt_ns for correlating events that are close in time but not perfectly simultaneous.
Key Concepts
clusterize()splits a single topic's matching window into distinct time clusters, tunable viaclustering_dt_ns.intersect()on aQueryResponseItemmerges every topic in the sequence into one request, returning only the windows where all of them were simultaneously true, withintersect_dt_nsto tolerate near-misses.clusterize_all()applies the same clustering idea to every topic in a sequence at once, independently per topic, instead of merging them.- The topic-level
intersect()works the same way but lets you pick exactly which topics participate, even across different queries or sequences.
For the full walkthrough, parameter reference, and visual examples of every operation, see Temporal Windows in the Python SDK documentation.