Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/write complex valued data #106

Merged
merged 28 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
21d4678
some basic support for reading and writing complex64 and complex128 data
twitzelbos Jun 16, 2023
2f72444
ripped out the different types of linear transforms and added a Nifti…
twitzelbos Jun 16, 2023
914ebca
added RGB8 and RGBA8 types
twitzelbos Jun 16, 2023
ad8cb39
sort of working now
twitzelbos Jun 16, 2023
c1cac1f
some magic right there
twitzelbos Jun 17, 2023
416a76b
remove safe_transmute from writing
twitzelbos Jun 19, 2023
dcf6987
added a couple of test files generated by nibabel for validating the …
twitzelbos Jun 19, 2023
3ac2e3f
adding a 4D RGBA test file created with nibabel
twitzelbos Jun 19, 2023
ae66016
remove safe_transmute entirely
twitzelbos Jun 19, 2023
09f6947
a bit more cleanup
twitzelbos Jun 20, 2023
f09e531
some more cleanup
twitzelbos Jun 20, 2023
45c1834
added some documentation
twitzelbos Jun 20, 2023
8d33d49
added some testing, and made some fixes to the conversion to ndarray
twitzelbos Jun 20, 2023
defeed8
added tests for reading complex valued nifti files
twitzelbos Jun 20, 2023
7ed5610
added some verification for RGB and RGBA reading
twitzelbos Jun 20, 2023
8c05978
added a missing feature flag
twitzelbos Jun 20, 2023
2b37ca1
remove an incorrect feature flag
twitzelbos Jun 20, 2023
8c3c7a2
and some final formating
twitzelbos Jun 20, 2023
ac828b5
minor doc string update
twitzelbos Jun 20, 2023
51623df
remove unused commented out code
twitzelbos Jun 20, 2023
4ccc374
removed the duplicated code from write_rgb_nifti
twitzelbos Jun 20, 2023
f9f671d
changed some clippy stuff
twitzelbos Jun 20, 2023
d672af8
updated comments
twitzelbos Jun 20, 2023
00cf85e
renamed the write_nifti_tt to something more descriptive.
twitzelbos Jun 20, 2023
dbadf34
removed excess underscores
twitzelbos Jun 20, 2023
32a3a5a
removed offensive underscores
twitzelbos Jun 20, 2023
7ef1f39
addressed review comments
twitzelbos Jun 30, 2023
2c3ce84
removed DataElement support for u8 tuples, settling on using RGB and …
twitzelbos Jul 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ flate2 = "1.0"
num-derive = "0.3"
num-traits = "0.2"
quick-error = "2.0"
safe-transmute = "0.11"
either = "1.6"
num-complex = {version = "0.4.3", features=["bytemuck"]}
rgb = "0.8.36"
bytemuck = {version = "1.13.1", features=["extern_crate_alloc"]}

[dependencies.nalgebra]
optional = true
Expand Down
Binary file added resources/complex/complex32.nii
Binary file not shown.
Binary file added resources/complex/complex64.nii
Binary file not shown.
Binary file added resources/rgba/4D.nii
Binary file not shown.
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ quick_error! {
display("Could not reserve {} bytes of memory for extended data", bytes)
source(err)
}

/// Attempted a type conversion that is not supported by this crate
InvalidTypeConversion(from: NiftiType, to: &'static str) {
display("Invalid type conversion from {:?} to {}", from, to)
}
}
}

Expand Down
24 changes: 13 additions & 11 deletions src/typedef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! converted to these types and vice-versa.

use crate::error::{NiftiError, Result};
use crate::volume::element::{DataElement, LinearTransform};
use crate::volume::element::{DataElement, NiftiDataRescaler};
use byteordered::{Endian, Endianness};
use num_derive::FromPrimitive;
use std::io::Read;
Expand Down Expand Up @@ -96,88 +96,90 @@ impl NiftiType {
T: Mul<Output = T>,
T: Add<Output = T>,
T: DataElement,
T: NiftiDataRescaler<T>,
{
match self {
NiftiType::Uint8 => {
let raw = u8::from_raw(source, endianness)?;
Ok(<u8 as DataElement>::Transform::linear_transform(
Ok(<u8 as DataElement>::DataRescaler::nifti_rescale(
T::from_u8(raw),
slope,
inter,
))
}
NiftiType::Int8 => {
let raw = i8::from_raw(source, endianness)?;
Ok(<i8 as DataElement>::Transform::linear_transform(
Ok(<i8 as DataElement>::DataRescaler::nifti_rescale(
T::from_i8(raw),
slope,
inter,
))
}
NiftiType::Uint16 => {
let raw = endianness.read_u16(source)?;
Ok(<u16 as DataElement>::Transform::linear_transform(
Ok(<u16 as DataElement>::DataRescaler::nifti_rescale(
T::from_u16(raw),
slope,
inter,
))
}
NiftiType::Int16 => {
let raw = endianness.read_i16(source)?;
Ok(<i16 as DataElement>::Transform::linear_transform(
Ok(<i16 as DataElement>::DataRescaler::nifti_rescale(
T::from_i16(raw),
slope,
inter,
))
}
NiftiType::Uint32 => {
let raw = endianness.read_u32(source)?;
Ok(<u32 as DataElement>::Transform::linear_transform(
Ok(<u32 as DataElement>::DataRescaler::nifti_rescale(
T::from_u32(raw),
slope,
inter,
))
}
NiftiType::Int32 => {
let raw = endianness.read_i32(source)?;
Ok(<i32 as DataElement>::Transform::linear_transform(
Ok(<i32 as DataElement>::DataRescaler::nifti_rescale(
T::from_i32(raw),
slope,
inter,
))
}
NiftiType::Uint64 => {
let raw = endianness.read_u64(source)?;
Ok(<u64 as DataElement>::Transform::linear_transform(
Ok(<u64 as DataElement>::DataRescaler::nifti_rescale(
T::from_u64(raw),
slope,
inter,
))
}
NiftiType::Int64 => {
let raw = endianness.read_i64(source)?;
Ok(<i64 as DataElement>::Transform::linear_transform(
Ok(<i64 as DataElement>::DataRescaler::nifti_rescale(
T::from_i64(raw),
slope,
inter,
))
}
NiftiType::Float32 => {
let raw = endianness.read_f32(source)?;
Ok(<f32 as DataElement>::Transform::linear_transform(
Ok(<f32 as DataElement>::DataRescaler::nifti_rescale(
T::from_f32(raw),
slope,
inter,
))
}
NiftiType::Float64 => {
let raw = endianness.read_f64(source)?;
Ok(<f64 as DataElement>::Transform::linear_transform(
Ok(<f64 as DataElement>::DataRescaler::nifti_rescale(
T::from_f64(raw),
slope,
inter,
))
}

// TODO(#3) add support for more data types
_ => Err(NiftiError::UnsupportedDataType(self)),
}
Expand Down
10 changes: 3 additions & 7 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,24 @@ use crate::NiftiHeader;
use byteordered::Endian;
use either::Either;
use flate2::bufread::GzDecoder;
use safe_transmute::{transmute_vec, TriviallyTransmutable};
use std::borrow::Cow;
use std::fs::File;
use std::io::{BufReader, Read, Result as IoResult, Seek};
use std::mem;
use std::path::{Path, PathBuf};

/// A trait that is both Read and Seek.
pub trait ReadSeek: Read + Seek {}
impl<T: Read + Seek> ReadSeek for T {}

pub fn convert_bytes_to<T, E>(mut a: Vec<u8>, e: E) -> Vec<T>
where
T: TriviallyTransmutable,
T: bytemuck::Pod,
E: Endian,
{
adapt_bytes_inline::<T, _>(&mut a, e);
match transmute_vec(a) {
match bytemuck::allocation::try_cast_vec(a) {
Ok(v) => v,
Err(safe_transmute::Error::IncompatibleVecTarget(e)) => e.copy(),
Err(safe_transmute::Error::Unaligned(e)) => e.copy(),
_ => unreachable!(),
Err((_, v)) => bytemuck::allocation::pod_collect_to_vec(&v),
}
}

Expand Down
Loading