From 337dc705f83711406b83d386c81778079effd75b Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Wed, 27 Mar 2024 08:59:25 +0000 Subject: [PATCH] build based on 11b25d1 --- dev/.documenter-siteinfo.json | 2 +- dev/conversion.html | 2 +- dev/frequencyFilter.html | 2 +- dev/gettingStarted.html | 2 +- dev/index.html | 2 +- dev/lowlevel.html | 2 +- dev/measurements.html | 2 +- dev/positions.html | 2 +- dev/reconstruction.html | 2 +- dev/systemmatrix.html | 2 +- dev/transferfunction.html | 10 +++++----- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 9797183f..b7c3739c 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-27T08:58:12","documenter_version":"1.3.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-27T08:59:14","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/dev/conversion.html b/dev/conversion.html index 727cd6a3..b44e59ff 100644 --- a/dev/conversion.html +++ b/dev/conversion.html @@ -1,4 +1,4 @@ Conversion · MPI Files

Conversion

With the support for reading different file formats and the ability to store data in the MDF, it is also possible to convert files into MDF. This can be done by calling

saveasMDF(filenameOut, filenameIn)

The second argument can alternatively also be an MPIFile handle.

Alternatively, there is also a more low level interface which gives the user the control to change parameters before storing. This look like this

params = loadDataset(f)
 # do something with params
-saveasMDF(filenameOut, params)

Here, f is an MPIFile handle and the command loadDataset loads the entire dataset including all parameters into a Julia Dict, which can be modified by the user. After modification one can store the data by passing the Dict as the second argument to the saveasMDF function.

Note

The parameters in the Dict returned by loadDataset have the same keys as the corresponding accessor functions listed in the Low Level Interface.

+saveasMDF(filenameOut, params)

Here, f is an MPIFile handle and the command loadDataset loads the entire dataset including all parameters into a Julia Dict, which can be modified by the user. After modification one can store the data by passing the Dict as the second argument to the saveasMDF function.

Note

The parameters in the Dict returned by loadDataset have the same keys as the corresponding accessor functions listed in the Low Level Interface.

diff --git a/dev/frequencyFilter.html b/dev/frequencyFilter.html index 7f29cc3b..273beaed 100644 --- a/dev/frequencyFilter.html +++ b/dev/frequencyFilter.html @@ -7,4 +7,4 @@ numUsedFreqs=-1, stepsize=1, maxMixingOrder=-1, - sortByMixFactors=false)

Usually one will apply an SNR threshold SNRThresh > 1.5 and a minFreq that is larger than the excitation frequencies. The frequencies are specified in Hz. Also useful is the opportunity to select specific receive channels by specifying recChannels.

The return value of filterFrequencies is of type Vector{Int64} and can be directly passed to getMeasurements, getMeasurementsFD, and getSystemMatrix.

+ sortByMixFactors=false)

Usually one will apply an SNR threshold SNRThresh > 1.5 and a minFreq that is larger than the excitation frequencies. The frequencies are specified in Hz. Also useful is the opportunity to select specific receive channels by specifying recChannels.

The return value of filterFrequencies is of type Vector{Int64} and can be directly passed to getMeasurements, getMeasurementsFD, and getSystemMatrix.

diff --git a/dev/gettingStarted.html b/dev/gettingStarted.html index 4283b6a0..cded14a5 100644 --- a/dev/gettingStarted.html +++ b/dev/gettingStarted.html @@ -6,4 +6,4 @@ [:, :, 1] = 0.014 0.014 0.0

Now let us load some measurement data. This can be done by calling

u = getMeasurementsFD(f, frames=1:100, numAverages=100)

Then we can display the data using the PyPlot package

using PyPlot
 figure(6, figsize=(6,4))
-semilogy(abs.(u[1:400,1,1,1]))

Spectrum

This shows a typical spectrum for a 2D Lissajous sampling pattern. The getMeasurementsFD is a high level interface for loading MPI data, which has several parameters that allow to customize the loading process. Details on loading measurement data are outlined in Measurements.

In the following we will first discuss the low level interface.

+semilogy(abs.(u[1:400,1,1,1]))

Spectrum

This shows a typical spectrum for a 2D Lissajous sampling pattern. The getMeasurementsFD is a high level interface for loading MPI data, which has several parameters that allow to customize the loading process. Details on loading measurement data are outlined in Measurements.

In the following we will first discuss the low level interface.

diff --git a/dev/index.html b/dev/index.html index d3dba4ed..4c042d66 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · MPI Files

MPIFiles.jl

Magnetic Particle Imaging Files

Introduction

MPIFiles.jl is a Julia package for handling files that are related to the tomographic imaging method magnetic particle imaging. It supports different file formats:

For all of these formats there is full support for reading the files. Write support is currently only available for MDF files. All files can be converted to MDF files using this capability.

MPIFiles.jl provides a generic interface for different MPI files. In turn it is possible to write generic algorithms that work for all supported file formats.

MPI files can be divided into three different categories

Each of these file types is supported and discussed in the referenced pages.

Installation

Start julia and open the package mode by entering ]. Then enter

add MPIFiles

This will install the packages MPIFiles.jl and all its dependencies.

License / Terms of Usage

The source code of this project is licensed under the MIT license. This implies that you are free to use, share, and adapt it. However, please give appropriate credit by citing the project.

Community Guidelines

If you have problems using the software, find bugs, or have feature requests please use the issue tracker to contact us. For general questions we prefer that you contact the current maintainer directly by email.

We welcome community contributions to MPIFiles.jl. Simply create a pull request with your proposed changes.

Contributors

+Home · MPI Files

MPIFiles.jl

Magnetic Particle Imaging Files

Introduction

MPIFiles.jl is a Julia package for handling files that are related to the tomographic imaging method magnetic particle imaging. It supports different file formats:

For all of these formats there is full support for reading the files. Write support is currently only available for MDF files. All files can be converted to MDF files using this capability.

MPIFiles.jl provides a generic interface for different MPI files. In turn it is possible to write generic algorithms that work for all supported file formats.

MPI files can be divided into three different categories

Each of these file types is supported and discussed in the referenced pages.

Installation

Start julia and open the package mode by entering ]. Then enter

add MPIFiles

This will install the packages MPIFiles.jl and all its dependencies.

License / Terms of Usage

The source code of this project is licensed under the MIT license. This implies that you are free to use, share, and adapt it. However, please give appropriate credit by citing the project.

Community Guidelines

If you have problems using the software, find bugs, or have feature requests please use the issue tracker to contact us. For general questions we prefer that you contact the current maintainer directly by email.

We welcome community contributions to MPIFiles.jl. Simply create a pull request with your proposed changes.

Contributors

diff --git a/dev/lowlevel.html b/dev/lowlevel.html index b522eebf..8dd54d8f 100644 --- a/dev/lowlevel.html +++ b/dev/lowlevel.html @@ -42,4 +42,4 @@ recoData, recoFov, recoFovCenter, recoSize, recoOrder, recoPositions # additional functions that should be implemented by an MPIFile -filepath, systemMatrixWithBG, systemMatrix, selectedChannels

The interface is structured in a similar way as the parameters within the MDF. Basically, there is a direct mapping between the MDF parameters and the MPIFiles interface. For instance the parameter acqNumAvarages maps to the MDF parameter /acquisition/numAverages. Also the dimensionality of the parameters described in the MDF is preserved. Thus, the MDF specification can be used as a documentation of the low level interface of MPIFiles.

In-memory MDF

Since during data acquisition it is not advisable to write the data directly to an MDF file, there is also an in-memory representation. It can be created either empty by mdf = MDFv2InMemory() or with default values set by mdf = defaultMDFv2InMemory(). The same interface as described above applies to the in-memory version. When writing it to disk using saveasMDF("your/file/path/file.mdf", mdf) it is checked for consistency. If this check should fail with an error, use saveasMDF("your/file/path/file.mdf", mdf, failOnInconsistent=true). The default is to not fail in order to not lose measurement data in case of an error.

Note

Note that the dimensions in the MDF documentation are flipped compared to the dimensions in Julia. This is because Julia stores the data in column major order, while HDF5 considers row major order

+filepath, systemMatrixWithBG, systemMatrix, selectedChannels

The interface is structured in a similar way as the parameters within the MDF. Basically, there is a direct mapping between the MDF parameters and the MPIFiles interface. For instance the parameter acqNumAvarages maps to the MDF parameter /acquisition/numAverages. Also the dimensionality of the parameters described in the MDF is preserved. Thus, the MDF specification can be used as a documentation of the low level interface of MPIFiles.

In-memory MDF

Since during data acquisition it is not advisable to write the data directly to an MDF file, there is also an in-memory representation. It can be created either empty by mdf = MDFv2InMemory() or with default values set by mdf = defaultMDFv2InMemory(). The same interface as described above applies to the in-memory version. When writing it to disk using saveasMDF("your/file/path/file.mdf", mdf) it is checked for consistency. If this check should fail with an error, use saveasMDF("your/file/path/file.mdf", mdf, failOnInconsistent=true). The default is to not fail in order to not lose measurement data in case of an error.

Note

Note that the dimensions in the MDF documentation are flipped compared to the dimensions in Julia. This is because Julia stores the data in column major order, while HDF5 considers row major order

diff --git a/dev/measurements.html b/dev/measurements.html index de61b453..b76e4297 100644 --- a/dev/measurements.html +++ b/dev/measurements.html @@ -12,4 +12,4 @@ transposed=false, frequencies=nothing, tfCorrection=measIsTFCorrected(f), - kargs...)

The function has basically the same parameters as getMeasurements but, additionally, it is possible to load the data in real form (useful when using a solver that cannot handle complex numbers), it is possible to specify the frequencies (specified by the indices) that should be loaded, and it is possible to transpose the data in a special way, where the frame dimension is changed to be the first dimension. getMeasurementsFD returns a 4D array where of type ComplexF32 with dimensions

  1. frequency dimension
  2. receive channel dimension
  3. patch dimension
  4. frame dimension
+ kargs...)

The function has basically the same parameters as getMeasurements but, additionally, it is possible to load the data in real form (useful when using a solver that cannot handle complex numbers), it is possible to specify the frequencies (specified by the indices) that should be loaded, and it is possible to transpose the data in a special way, where the frame dimension is changed to be the first dimension. getMeasurementsFD returns a 4D array where of type ComplexF32 with dimensions

  1. frequency dimension
  2. receive channel dimension
  3. patch dimension
  4. frame dimension
diff --git a/dev/positions.html b/dev/positions.html index 5682fb12..31ddebc8 100644 --- a/dev/positions.html +++ b/dev/positions.html @@ -1,2 +1,2 @@ -Positions · MPI Files

Positions

MPIFiles contains several types describing point sets.

+Positions · MPI Files

Positions

MPIFiles contains several types describing point sets.

diff --git a/dev/reconstruction.html b/dev/reconstruction.html index 1d99db40..6dadd185 100644 --- a/dev/reconstruction.html +++ b/dev/reconstruction.html @@ -4,4 +4,4 @@ function recoFovCenter(f::MPIFile) function recoSize(f::MPIFile) function recoOrder(f::MPIFile) -function recoPositions(f::MPIFile)

Instead, one can also combine these data into an ImageMetadata object from the Images.jl package by calling the functions

function loadRecoData(filename::AbstractString)

The ImageMetadata object does also pull all relevant metadata from an MDF such that the file can be also be stored using

function saveRecoData(filename, image::ImageMeta)

These two functions are especially relevant when using the package MPIReco.jl

+function recoPositions(f::MPIFile)

Instead, one can also combine these data into an ImageMetadata object from the Images.jl package by calling the functions

function loadRecoData(filename::AbstractString)

The ImageMetadata object does also pull all relevant metadata from an MDF such that the file can be also be stored using

function saveRecoData(filename, image::ImageMeta)

These two functions are especially relevant when using the package MPIReco.jl

diff --git a/dev/systemmatrix.html b/dev/systemmatrix.html index 37c4fe89..90e89ef3 100644 --- a/dev/systemmatrix.html +++ b/dev/systemmatrix.html @@ -3,4 +3,4 @@ frequencies=1:rxNumFrequencies(f)*rxNumChannels(f); bgCorrection=false, loadasreal=false, - kargs...)

loadasreal can again be used when using a solver requiring real numbers. The most important parameter is frequencies, which defaults to all possible frequencies over all receive channels. In practice, one will determine the frequencies using the the Frequency Filter functionality. The parameter bgCorrection controls if a background correction is applied while loading the system matrix. The return value of getSystemMatrix is a matrix of type ComplexF32 or Float32 with the rows encoding the spatial dimension and the columns encoding the dimensions frequency, receive channels, and patches.

+ kargs...)

loadasreal can again be used when using a solver requiring real numbers. The most important parameter is frequencies, which defaults to all possible frequencies over all receive channels. In practice, one will determine the frequencies using the the Frequency Filter functionality. The parameter bgCorrection controls if a background correction is applied while loading the system matrix. The return value of getSystemMatrix is a matrix of type ComplexF32 or Float32 with the rows encoding the spatial dimension and the columns encoding the dimensions frequency, receive channels, and patches.

diff --git a/dev/transferfunction.html b/dev/transferfunction.html index e8d423df..c773d719 100644 --- a/dev/transferfunction.html +++ b/dev/transferfunction.html @@ -11,20 +11,20 @@ 1001 frequency samples from 0.0 Hz to 1.0e6 Hz
julia> RL([0,100e3])2-element Vector{Unitful.Quantity{ComplexF64, 𝐋^2 𝐌 𝐈^-2 𝐓^-3, Unitful.FreeUnits{(A^-1, V), 𝐋^2 𝐌 𝐈^-2 𝐓^-3, nothing}}}: (1.0 + 0.0im) V A^-1 (1.0 + 6.283185307179586im) V A^-1

Saving and loading

A TransferFunction object can be saved to and loaded from a .h5 file.

FileIO.saveMethod
save(filename::String, tf::TransferFunction)
-

Save tf as a h5 file to filename

source
MPIFiles.TransferFunctionMethod
TransferFunction(
+

Save tf as a h5 file to filename

source
MPIFiles.TransferFunctionMethod
TransferFunction(
     filename::String;
     kargs...
 ) -> TransferFunction
-

Create a TransferFunction from a data file at filename.

The file can be either a h5-File created with this package. Keyword arguments will be passed to load_tf_fromVNA

source

Additional constructors

In addition to the constructor taking a single (complex) array it is also possible to give two arrays representing amplitude and phase.

It is also possible to construct a TransferFunction from the transfer function data included in an MPIFile.

MPIFiles.TransferFunctionMethod
TransferFunction(
+

Create a TransferFunction from a data file at filename.

The file can be either a h5-File created with this package. Keyword arguments will be passed to load_tf_fromVNA

source

Additional constructors

In addition to the constructor taking a single (complex) array it is also possible to give two arrays representing amplitude and phase.

It is also possible to construct a TransferFunction from the transfer function data included in an MPIFile.

MPIFiles.TransferFunctionMethod
TransferFunction(
     freq::Vector{<:Real},
     ampdata::Array{<:Real, N},
     phasedata::Array{<:Real, N};
     kwargs...
 ) -> TransferFunction
-

Create a TransferFunction from separate amplitude and phase arrays at frequencies freq.

ampdata and phasedata should have the following shape: [frequencies, channels]

source
MPIFiles.TransferFunctionMethod
TransferFunction(file::MPIFile)
-

Create a TransferFunction from the tf data saved in a MPIFile (see rxTransferFunction)

source

Other interesting functions

MPIFiles.TransferFunctionType
mutable struct TransferFunction
  • freq::Vector{Float64}

  • data::Matrix{ComplexF64}

  • interpolator::Vector{Interpolations.AbstractInterpolation}

  • inductionFactor::Vector{Float64}

  • units::Vector{Unitful.FreeUnits}

TransferFunction(freq_::Vector{<:Real}, datain::Array{<:Complex}; inductionFactor::Vector{<:Real}=ones(size(datain, 2)), units::Vector=Unitful.FreeUnits[Unitful.NoUnits for i in 1:size(datain, 2)])

Create a TransferFunction from a complex data array at frequencies freq_.

Optional Keyword-Arguments:

  • inductionFactor::Vector{<:Real}: induction factor for each channel
  • units::Vector: units for each channel, can be either Unitful.FreeUnits or a string that can be parsed as a Unitful unit
source
MPIFiles.combineMethod
combine(
+

Create a TransferFunction from separate amplitude and phase arrays at frequencies freq.

ampdata and phasedata should have the following shape: [frequencies, channels]

source
MPIFiles.TransferFunctionMethod
TransferFunction(file::MPIFile)
+

Create a TransferFunction from the tf data saved in a MPIFile (see rxTransferFunction)

source

Other interesting functions

MPIFiles.TransferFunctionType
mutable struct TransferFunction
  • freq::Vector{Float64}

  • data::Matrix{ComplexF64}

  • interpolator::Vector{Interpolations.AbstractInterpolation}

  • inductionFactor::Vector{Float64}

  • units::Vector{Unitful.FreeUnits}

TransferFunction(freq_::Vector{<:Real}, datain::Array{<:Complex}; inductionFactor::Vector{<:Real}=ones(size(datain, 2)), units::Vector=Unitful.FreeUnits[Unitful.NoUnits for i in 1:size(datain, 2)])

Create a TransferFunction from a complex data array at frequencies freq_.

Optional Keyword-Arguments:

  • inductionFactor::Vector{<:Real}: induction factor for each channel
  • units::Vector: units for each channel, can be either Unitful.FreeUnits or a string that can be parsed as a Unitful unit
source
MPIFiles.combineMethod
combine(
     tf1::TransferFunction,
     tf2::TransferFunction;
     interpolate
 ) -> TransferFunction
-

Combine two TransferFunctions along their channel dimension. If interpolate=false, will only work if the frequency samples are identical.

source
+

Combine two TransferFunctions along their channel dimension. If interpolate=false, will only work if the frequency samples are identical.

source