【问题标题】:Rust hdf5 crate: reading a scalar dataset of unknown typeRust hdf5 crate:读取未知类型的标量数据集
【发布时间】:2023-01-31 18:57:45
【问题描述】:

给定一个 hdf5 Dataset,有一个 is_scalar 方法来检查它是否是一个标量。

但是,当我读取该标量时,我需要指定我希望将该标量读入的类型,如下面的代码所示。

let ds: Dataset = group.handler
    .dataset(dataset_name.as_ref())
    .unwrap();
if ds.is_scalar() {
    let x: hdf5::types::VarLenUnicode = ds.read_scalar();
}

在上面的这个例子中,我指定我希望将标量读入 hdf5::types::VarLenUnicode 类型。

当我确切地知道期望的类型时,这很好用。

然而,在其他一些情况下,我事先没有 hdf5 数据集的类型信息。

根据数据类型,我希望以不同方式处理数据集。有没有办法在读取标量之前检查它的数据类型?

读取可能包含字符串或浮点数的 hdf5 数据集的惯用方式是什么?

同样,是否可以读取 hdf5 数据集并将其转换为字符串,即使它包含浮点数?

【问题讨论】:

  • id_type 没有提供您需要的信息吗?
  • 无论标量类型如何,它总是返回 H5I_DATASET
  • 你可以从.dtype()获得Datatype,然后从.to_descriptor()获得它的TypeDescriptor
  • 或者,您可以使用 Datatype.is() 方法来测试特定类型。
  • 谢谢。这就提出了另一个问题。 H5 有很多类型可以用 Rust 中的 f32 类型表示。你将如何进行从 H5 类型到 Rust 标量的映射?

标签: rust hdf5


【解决方案1】:

这是一个以 to_descriptor() 方法开头的工作解决方案,eggyal 在 cmets 上发布。

获得TypeDescriptor 值后,我们需要处理所有可能的情况(Rust 方式)。

match ds_type.to_descriptor().unwrap() {
    hdf5::types::TypeDescriptor::Float(_) => {
        self.show_dataset::<f64>(&ds, dataset, ctx, &mut is_open);
    }
    hdf5::types::TypeDescriptor::VarLenUnicode => {
        self.show_dataset::<hdf5::types::VarLenUnicode>(
            &ds,
            dataset,
            ctx,
            &mut is_open,
        );
    }
    hdf5::types::TypeDescriptor::Integer(_) => {
        self.show_dataset::<i64>(&ds, dataset, ctx, &mut is_open);
    }
    hdf5::types::TypeDescriptor::Unsigned(_) => {
        self.show_dataset::<u64>(&ds, dataset, ctx, &mut is_open);
    }
    hdf5::types::TypeDescriptor::Boolean => {
        self.show_dataset::<bool>(&ds, dataset, ctx, &mut is_open);
    }
    hdf5::types::TypeDescriptor::Enum(_) => todo!(),
    hdf5::types::TypeDescriptor::Compound(_) => todo!(),
    hdf5::types::TypeDescriptor::FixedArray(_, _) => todo!(),
    hdf5::types::TypeDescriptor::FixedAscii(_) => todo!(),
    hdf5::types::TypeDescriptor::FixedUnicode(_) => todo!(),
    hdf5::types::TypeDescriptor::VarLenArray(_) => todo!(),
    hdf5::types::TypeDescriptor::VarLenAscii => {
        self.show_dataset::<hdf5::types::VarLenAscii>(
            &ds,
            dataset,
            ctx,
            &mut is_open,
        );
    }
}

在稍后的处理中,如果是标量,我只需通过std::fmt::Display 显示标量类型的内容。我在那里使用了 generic types 以避免在处理不同类型时代码重复。

在非标量(矢量)的情况下,我使用read_raw 加载它。

fn show_dataset<T: hdf5::H5Type + std::fmt::Display>(
    &mut self,
    ds: &hdf5::Dataset,
    dataset: &str,
    ctx: &egui::Context,
    is_open: &mut bool,
) {
    if ds.is_scalar() {
        let x_data: T = ds.read_scalar().unwrap();
        Window::new(dataset.to_owned())
            .open(is_open)
            .vscroll(true)
            .resizable(true)
            .default_height(300.0)
            .show(ctx, |ui| {
                ui.label(format!("{}", x_data));
            });
    } else {
        let x_data: Vec<T> = ds.read_raw().unwrap();
        let mut table_box = Box::<super::table::TableWindow<T>>::default();
        table_box.set_name(dataset.to_owned());
        table_box.set_data(x_data);
        table_box.show(ctx, is_open);
    }
}

不过,此解决方案有一个警告。

正如您可能已经注意到的,下面这些类型没有被处理。在我的应用程序中,不需要处理这些类型,但通常我不知道如何处理这些类型。

    hdf5::types::TypeDescriptor::FixedArray(_, _) => todo!(),
    hdf5::types::TypeDescriptor::FixedAscii(_) => todo!(),
    hdf5::types::TypeDescriptor::FixedUnicode(_) => todo!(),

【讨论】:

    猜你喜欢
    • 2019-08-14
    • 2019-08-02
    • 2014-09-12
    • 2016-10-27
    • 2021-02-24
    • 2019-03-04
    • 2022-10-12
    • 2015-09-20
    • 2019-11-15
    相关资源
    最近更新 更多