From 7c63595fcfcb53e8912d18140258f682bbebe099 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Fri, 22 Nov 2024 20:50:50 +0000 Subject: [PATCH] build based on 83d4359 --- 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 7f78560..faa005b 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-14T13:55:42","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-22T20:50:36","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/conversion.html b/dev/conversion.html index 52492d7..d5d6457 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 4007ace..280f25c 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 ab6ab64..25eebfc 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 c54de6c..b889e34 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 0ba5291..ae49419 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 f0a7814..4b674bb 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 391859d..249e2b4 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 346aaab..492b2f5 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 761f3b4..4189ecb 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 c1f6387..ee52bf7 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) -> TransferFunction
-

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) -> TransferFunction
+

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