re_types/archetypes/
tensor.rs

1// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/rust/api.rs
2// Based on "crates/store/re_types/definitions/rerun/archetypes/tensor.fbs".
3
4#![allow(unused_braces)]
5#![allow(unused_imports)]
6#![allow(unused_parens)]
7#![allow(clippy::clone_on_copy)]
8#![allow(clippy::cloned_instead_of_copied)]
9#![allow(clippy::map_flatten)]
10#![allow(clippy::needless_question_mark)]
11#![allow(clippy::new_without_default)]
12#![allow(clippy::redundant_closure)]
13#![allow(clippy::too_many_arguments)]
14#![allow(clippy::too_many_lines)]
15
16use ::re_types_core::try_serialize_field;
17use ::re_types_core::SerializationResult;
18use ::re_types_core::{ComponentBatch as _, SerializedComponentBatch};
19use ::re_types_core::{ComponentDescriptor, ComponentType};
20use ::re_types_core::{DeserializationError, DeserializationResult};
21
22/// **Archetype**: An N-dimensional array of numbers.
23///
24/// ## Example
25///
26/// ### Simple tensor
27/// ```ignore
28/// use ndarray::{Array, ShapeBuilder as _};
29/// use rand::prelude::*;
30///
31/// fn main() -> Result<(), Box<dyn std::error::Error>> {
32///     let rec = rerun::RecordingStreamBuilder::new("rerun_example_tensor").spawn()?;
33///
34///     let mut data = Array::<u8, _>::default((8, 6, 3, 5).f());
35///     let mut rng = rand::rngs::SmallRng::seed_from_u64(42);
36///     data.map_inplace(|x| *x = rng.r#gen());
37///
38///     let tensor =
39///         rerun::Tensor::try_from(data)?.with_dim_names(["width", "height", "channel", "batch"]);
40///     rec.log("tensor", &tensor)?;
41///
42///     Ok(())
43/// }
44/// ```
45/// <center>
46/// <picture>
47///   <source media="(max-width: 480px)" srcset="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/480w.png">
48///   <source media="(max-width: 768px)" srcset="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/768w.png">
49///   <source media="(max-width: 1024px)" srcset="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/1024w.png">
50///   <source media="(max-width: 1200px)" srcset="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/1200w.png">
51///   <img src="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/full.png" width="640">
52/// </picture>
53/// </center>
54#[derive(Clone, Debug, PartialEq, Default)]
55pub struct Tensor {
56    /// The tensor data
57    pub data: Option<SerializedComponentBatch>,
58
59    /// The expected range of values.
60    ///
61    /// This is typically the expected range of valid values.
62    /// Everything outside of the range is clamped to the range for the purpose of colormpaping.
63    /// Any colormap applied for display, will map this range.
64    ///
65    /// If not specified, the range will be automatically estimated from the data.
66    /// Note that the Viewer may try to guess a wider range than the minimum/maximum of values
67    /// in the contents of the tensor.
68    /// E.g. if all values are positive, some bigger than 1.0 and all smaller than 255.0,
69    /// the Viewer will guess that the data likely came from an 8bit image, thus assuming a range of 0-255.
70    pub value_range: Option<SerializedComponentBatch>,
71}
72
73impl Tensor {
74    /// Returns the [`ComponentDescriptor`] for [`Self::data`].
75    ///
76    /// The corresponding component is [`crate::components::TensorData`].
77    #[inline]
78    pub fn descriptor_data() -> ComponentDescriptor {
79        ComponentDescriptor {
80            archetype: Some("rerun.archetypes.Tensor".into()),
81            component: "Tensor:data".into(),
82            component_type: Some("rerun.components.TensorData".into()),
83        }
84    }
85
86    /// Returns the [`ComponentDescriptor`] for [`Self::value_range`].
87    ///
88    /// The corresponding component is [`crate::components::ValueRange`].
89    #[inline]
90    pub fn descriptor_value_range() -> ComponentDescriptor {
91        ComponentDescriptor {
92            archetype: Some("rerun.archetypes.Tensor".into()),
93            component: "Tensor:value_range".into(),
94            component_type: Some("rerun.components.ValueRange".into()),
95        }
96    }
97}
98
99static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> =
100    once_cell::sync::Lazy::new(|| [Tensor::descriptor_data()]);
101
102static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> =
103    once_cell::sync::Lazy::new(|| []);
104
105static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> =
106    once_cell::sync::Lazy::new(|| [Tensor::descriptor_value_range()]);
107
108static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> =
109    once_cell::sync::Lazy::new(|| [Tensor::descriptor_data(), Tensor::descriptor_value_range()]);
110
111impl Tensor {
112    /// The total number of components in the archetype: 1 required, 0 recommended, 1 optional
113    pub const NUM_COMPONENTS: usize = 2usize;
114}
115
116impl ::re_types_core::Archetype for Tensor {
117    #[inline]
118    fn name() -> ::re_types_core::ArchetypeName {
119        "rerun.archetypes.Tensor".into()
120    }
121
122    #[inline]
123    fn display_name() -> &'static str {
124        "Tensor"
125    }
126
127    #[inline]
128    fn required_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
129        REQUIRED_COMPONENTS.as_slice().into()
130    }
131
132    #[inline]
133    fn recommended_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
134        RECOMMENDED_COMPONENTS.as_slice().into()
135    }
136
137    #[inline]
138    fn optional_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
139        OPTIONAL_COMPONENTS.as_slice().into()
140    }
141
142    #[inline]
143    fn all_components() -> ::std::borrow::Cow<'static, [ComponentDescriptor]> {
144        ALL_COMPONENTS.as_slice().into()
145    }
146
147    #[inline]
148    fn from_arrow_components(
149        arrow_data: impl IntoIterator<Item = (ComponentDescriptor, arrow::array::ArrayRef)>,
150    ) -> DeserializationResult<Self> {
151        re_tracing::profile_function!();
152        use ::re_types_core::{Loggable as _, ResultExt as _};
153        let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect();
154        let data = arrays_by_descr
155            .get(&Self::descriptor_data())
156            .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_data()));
157        let value_range = arrays_by_descr
158            .get(&Self::descriptor_value_range())
159            .map(|array| {
160                SerializedComponentBatch::new(array.clone(), Self::descriptor_value_range())
161            });
162        Ok(Self { data, value_range })
163    }
164}
165
166impl ::re_types_core::AsComponents for Tensor {
167    #[inline]
168    fn as_serialized_batches(&self) -> Vec<SerializedComponentBatch> {
169        use ::re_types_core::Archetype as _;
170        [self.data.clone(), self.value_range.clone()]
171            .into_iter()
172            .flatten()
173            .collect()
174    }
175}
176
177impl ::re_types_core::ArchetypeReflectionMarker for Tensor {}
178
179impl Tensor {
180    /// Create a new `Tensor`.
181    #[inline]
182    pub fn new(data: impl Into<crate::components::TensorData>) -> Self {
183        Self {
184            data: try_serialize_field(Self::descriptor_data(), [data]),
185            value_range: None,
186        }
187    }
188
189    /// Update only some specific fields of a `Tensor`.
190    #[inline]
191    pub fn update_fields() -> Self {
192        Self::default()
193    }
194
195    /// Clear all the fields of a `Tensor`.
196    #[inline]
197    pub fn clear_fields() -> Self {
198        use ::re_types_core::Loggable as _;
199        Self {
200            data: Some(SerializedComponentBatch::new(
201                crate::components::TensorData::arrow_empty(),
202                Self::descriptor_data(),
203            )),
204            value_range: Some(SerializedComponentBatch::new(
205                crate::components::ValueRange::arrow_empty(),
206                Self::descriptor_value_range(),
207            )),
208        }
209    }
210
211    /// Partitions the component data into multiple sub-batches.
212    ///
213    /// Specifically, this transforms the existing [`SerializedComponentBatch`]es data into [`SerializedComponentColumn`]s
214    /// instead, via [`SerializedComponentBatch::partitioned`].
215    ///
216    /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
217    ///
218    /// The specified `lengths` must sum to the total length of the component batch.
219    ///
220    /// [`SerializedComponentColumn`]: [::re_types_core::SerializedComponentColumn]
221    #[inline]
222    pub fn columns<I>(
223        self,
224        _lengths: I,
225    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>>
226    where
227        I: IntoIterator<Item = usize> + Clone,
228    {
229        let columns = [
230            self.data
231                .map(|data| data.partitioned(_lengths.clone()))
232                .transpose()?,
233            self.value_range
234                .map(|value_range| value_range.partitioned(_lengths.clone()))
235                .transpose()?,
236        ];
237        Ok(columns.into_iter().flatten())
238    }
239
240    /// Helper to partition the component data into unit-length sub-batches.
241    ///
242    /// This is semantically similar to calling [`Self::columns`] with `std::iter::take(1).repeat(n)`,
243    /// where `n` is automatically guessed.
244    #[inline]
245    pub fn columns_of_unit_batches(
246        self,
247    ) -> SerializationResult<impl Iterator<Item = ::re_types_core::SerializedComponentColumn>> {
248        let len_data = self.data.as_ref().map(|b| b.array.len());
249        let len_value_range = self.value_range.as_ref().map(|b| b.array.len());
250        let len = None.or(len_data).or(len_value_range).unwrap_or(0);
251        self.columns(std::iter::repeat(1).take(len))
252    }
253
254    /// The tensor data
255    #[inline]
256    pub fn with_data(mut self, data: impl Into<crate::components::TensorData>) -> Self {
257        self.data = try_serialize_field(Self::descriptor_data(), [data]);
258        self
259    }
260
261    /// This method makes it possible to pack multiple [`crate::components::TensorData`] in a single component batch.
262    ///
263    /// This only makes sense when used in conjunction with [`Self::columns`]. [`Self::with_data`] should
264    /// be used when logging a single row's worth of data.
265    #[inline]
266    pub fn with_many_data(
267        mut self,
268        data: impl IntoIterator<Item = impl Into<crate::components::TensorData>>,
269    ) -> Self {
270        self.data = try_serialize_field(Self::descriptor_data(), data);
271        self
272    }
273
274    /// The expected range of values.
275    ///
276    /// This is typically the expected range of valid values.
277    /// Everything outside of the range is clamped to the range for the purpose of colormpaping.
278    /// Any colormap applied for display, will map this range.
279    ///
280    /// If not specified, the range will be automatically estimated from the data.
281    /// Note that the Viewer may try to guess a wider range than the minimum/maximum of values
282    /// in the contents of the tensor.
283    /// E.g. if all values are positive, some bigger than 1.0 and all smaller than 255.0,
284    /// the Viewer will guess that the data likely came from an 8bit image, thus assuming a range of 0-255.
285    #[inline]
286    pub fn with_value_range(
287        mut self,
288        value_range: impl Into<crate::components::ValueRange>,
289    ) -> Self {
290        self.value_range = try_serialize_field(Self::descriptor_value_range(), [value_range]);
291        self
292    }
293
294    /// This method makes it possible to pack multiple [`crate::components::ValueRange`] in a single component batch.
295    ///
296    /// This only makes sense when used in conjunction with [`Self::columns`]. [`Self::with_value_range`] should
297    /// be used when logging a single row's worth of data.
298    #[inline]
299    pub fn with_many_value_range(
300        mut self,
301        value_range: impl IntoIterator<Item = impl Into<crate::components::ValueRange>>,
302    ) -> Self {
303        self.value_range = try_serialize_field(Self::descriptor_value_range(), value_range);
304        self
305    }
306}
307
308impl ::re_byte_size::SizeBytes for Tensor {
309    #[inline]
310    fn heap_size_bytes(&self) -> u64 {
311        self.data.heap_size_bytes() + self.value_range.heap_size_bytes()
312    }
313}