use polars::frame::DataFrame;
use avin_utils as utils;
use crate::{Cluster, Iid, Tic, TimeFrame};
#[derive(Debug)]
pub struct Footprint {
iid: Iid,
tf: TimeFrame,
clusters: Vec<Cluster>,
now: Option<Cluster>,
}
impl Footprint {
pub fn new(
iid: &Iid,
tf: &TimeFrame,
clusters: Vec<Cluster>,
) -> Footprint {
Self {
iid: iid.clone(),
tf: *tf,
clusters,
now: None,
}
}
pub fn from_tics(iid: &Iid, tf: TimeFrame, tics: &[Tic]) -> Footprint {
Self {
iid: iid.clone(),
clusters: Self::split(tics, tf),
tf,
now: None,
}
}
pub fn iid(&self) -> &Iid {
&self.iid
}
pub fn tf(&self) -> &TimeFrame {
&self.tf
}
pub fn clusters(&self) -> &Vec<Cluster> {
&self.clusters
}
pub fn now(&self) -> Option<&Cluster> {
self.now.as_ref()
}
pub fn df(&self) -> DataFrame {
assert!(!self.clusters.is_empty());
let mut all = self.clusters[0].df();
for i in 1..self.clusters.len() {
let df = self.clusters[i].df();
all.extend(&df).unwrap();
}
all
}
fn split(tics: &[Tic], tf: TimeFrame) -> Vec<Cluster> {
let mut clusters = Vec::new();
if tics.is_empty() {
return clusters;
}
let key = |x: &Tic| x.ts_nanos;
let mut ts1 = tics.first().unwrap().ts_nanos;
let mut ts2 = tf.next_ts(ts1);
let mut b = 0;
let mut e;
while b < tics.len() {
b = utils::bisect_right(tics, ts1, key).unwrap();
e = utils::bisect_right(tics, ts2, key).unwrap_or(tics.len());
let selected = &tics[b..e];
if !selected.is_empty() {
let cluster = Cluster::new(selected, tf);
clusters.push(cluster);
}
ts1 = tf.next_ts(ts1);
ts2 = tf.next_ts(ts2);
b = e;
}
clusters
}
}
impl AsRef<Footprint> for Footprint {
fn as_ref(&self) -> &Footprint {
self
}
}
#[cfg(test)]
mod tests {
}