This repository has been archived by the owner on May 18, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 5
Rt/issue75 shim specs json #92
Draft
rtopfer
wants to merge
24
commits into
master
Choose a base branch
from
rt/issue75-ShimSpecs-json
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
4409f83
add +img.read_nii.m from dev branch rt/+img
rtopfer fedca0d
Merge branch 'master' into rt/issue75-ShimSpecs-json
rtopfer a78565d
REF,DOC: Replace getnactivechannels() method with nChannels dependent…
rtopfer 386664f
BUG: Replace calls to ShimUse.customdisplay (deprecated) with fprintf
rtopfer 0089d5c
BUG: correct variable name
rtopfer fce7622
REF: Enable ShimSpecs object as optional input to ShimOpt() constructor
rtopfer 04b75c3
NEW: +b0shim/+coils/+greg package, containing specs.json (converted f…
rtopfer b00fd74
NEW: package +valid for generic validation functions; add mustBeA.m—c…
rtopfer b88c7cf
NEW: b0shim.Specs class to create ShimSpecs object from json file (pa…
rtopfer 2dbcb66
NEW: draft save_json() method in b0shim.Specs
rtopfer 19f8527
DOC: b0shim.Specs reformat
rtopfer a6ad608
BUG: ShimUse.m : Replace curly brackets with parentheses
rtopfer 93298ab
Merge branch 'master' into rt/issue75-ShimSpecs-json
rtopfer dfda2d4
DEL: +img folder (renamed on master to +imutils)
rtopfer 89d7ebf
REF: Minor changes to Shim -Com,-Specs and -Opt classes for _Greg/_re…
rtopfer ce9a8b4
NEW: +parts classes to form Shim Specs config: Channel.m and Port.m
rtopfer 091800e
REF: b0shim.Specs properties now include +parts.Channel, .Port
rtopfer 02c45e2
DOC,NEW: +b0shim.parts (class docs) and Contents.m (package doc)
rtopfer f60aa6f
NEW: read_/write_json standalone functions added to ./misc
rtopfer dc54fb5
DOC: +b0shim/+parts/ Channel.m and Port.m
rtopfer 9404bbe
REF, DOC: +b0shim.Specs simplify (move json I/O to standalone functio…
rtopfer 0209c5e
REF: Rename Specs --> Config (the class bears little semblance to the…
rtopfer 28c75ab
BUG: Add Parity property to b0shim.parts.Port
rtopfer c8224e2
NEW,DOCS: add example configuration scripts and documentation
rtopfer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
%b0shim.coil.greg 8-channel AC/DC 3T neck coil | ||
% | ||
% Nicknamed "greg", after its creator: | ||
% [Germain G. et al., ISMRM 2016](https://cds.ismrm.org/protected/16MPresentations/abstracts/1154.html) | ||
% | ||
% [Topfer et al., ISMRM 2018](https://www.slideshare.net/neuropoly/integrated-rf-and-shim-coils-for-mri-105560384) | ||
% | ||
% <iframe src="//www.slideshare.net/slideshow/embed_code/key/lhvoyKuHLsgc8L" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/neuropoly/integrated-rf-and-shim-coils-for-mri-105560384" title=" Integrated RF and Shim coils for MRI" target="_blank"> Integrated RF and Shim coils for MRI</a> </strong> from <strong><a href="https://www.slideshare.net/neuropoly" target="_blank">NeuroPoly </a></strong> </div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
{ | ||
"Adc": { | ||
"mVPerAdcCount": 2 | ||
}, | ||
"Id": { | ||
"systemName": "Greg", | ||
"channelNames": [ | ||
"Ch1", | ||
"Ch2", | ||
"Ch3", | ||
"Ch4", | ||
"Ch5", | ||
"Ch6", | ||
"Ch7", | ||
"Ch8" | ||
], | ||
"channelUnits": [ | ||
"[A]", | ||
"[A]", | ||
"[A]", | ||
"[A]", | ||
"[A]", | ||
"[A]", | ||
"[A]", | ||
"[A]" | ||
] | ||
}, | ||
"Amp": { | ||
"maxCurrentPerChannel": [ | ||
2.5, | ||
2.5, | ||
2.5, | ||
2.5, | ||
2.5, | ||
2.5, | ||
2.5, | ||
2.5 | ||
], | ||
"maxCurrentPerBank": 20, | ||
"nChannels": 8, | ||
"nActiveChannels": 8, | ||
"maxVoltagePerChannel": 2500, | ||
"staticChannels": [ | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true | ||
], | ||
"dynamicChannels": [ | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true, | ||
true | ||
] | ||
}, | ||
"Com": { | ||
"baudRate": 115200, | ||
"readTimeout": 500, | ||
"dataBits": 8, | ||
"stopBits": 1, | ||
"flowControl": "NONE", | ||
"parity": "NONE", | ||
"byteOrder": "bigEndian", | ||
"txRxDelay": 0.005, | ||
"updatePeriod": 0.1 | ||
}, | ||
"Dac": { | ||
"resolution": 8, | ||
"maxCurrent": 5, | ||
"referenceVoltage": 1250, | ||
"maximum": 26214 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
function [ filename ] = write_config( filename ) | ||
%WRITE_CONFIG Writes system configuration file for the 8 ch. AC/DC neck coil | ||
% | ||
% filename = b0shim.coils.greg.write_config(); | ||
% b0shim.coils.greg.write_config( filename ); | ||
% | ||
% Defines the system configuration and saves it to the coil's package folder under | ||
% ``` | ||
% ./+b0shim/+coils/+greg/config.json | ||
% ``` | ||
% b0 | ||
% | ||
% and saves the system configuration for | ||
% the 3T 8-channel AC/DC neck-coil | ||
% | ||
% See also | ||
% [ b0shim.coils.greg.Contents ]( ./Contents.md ) | ||
arguments | ||
filename(1,:) char = [mfilename('fullpath') filesep 'config_' datestr(date,'yymmdd') ]; | ||
end | ||
warning('Untested commit - may contain bugs') | ||
|
||
%% 1. Create an instance of the default configuration object | ||
config = b0shim.Config; | ||
|
||
%% 2. *As the object's properties are immutable*, convert to struct: | ||
% NOTE: Conversion elicits a warning. Not a concern. Mute it momentarily) | ||
warning('OFF', msgId); | ||
config = struct( config ); | ||
warning('ON', msgId); | ||
|
||
%% 3. Assign fields according to system specs | ||
|
||
% System/package name | ||
config.name = "greg"; | ||
|
||
%% Channel configuration | ||
|
||
% Add 8 channels | ||
config.channels(1:8) = b0shim.parts.Channel ; | ||
|
||
% Assign channel properties | ||
for iCh = 1 : numel(config.channels) | ||
config.channels(iCh).name = strcat( "Ch. ", num2str(iCh) ); | ||
config.channels(iCh).units = "A"; % Amperes | ||
config.limits(iCh) = [-2.5 2.5]; % [min. max.] in Amperes | ||
config.positioning = "table-fixed"; % shim position is table-dependent | ||
end | ||
|
||
%% Configuration of serial port parameters | ||
config.ports(1) = b0shim.parts.Port(); | ||
|
||
% NOTE: These parameters are actually set *in the source code of the Teensy | ||
% microcontroller.* | ||
% TODO: Rather than hardcode the values in two places, some consistency ought | ||
% to be enforced between the C++ and MATLAB sources, e.g. by MATLAB parsing the | ||
% .cpp/.hpp files, or the config.json values being transfered over serial, or | ||
% some other alternative. (Same goes for the Arduino-based respiratory bellows...) | ||
|
||
config.ports(1).BaudRate = 115200; | ||
config.ports(1).DataBits = 8; | ||
config.ports(1).StopBits = 1; | ||
config.ports(1).Parity = "none" | ||
config.ports(1).FlowControl = "none"; | ||
config.ports(1).ByteOrder = "big-endian"; | ||
|
||
%% Configure remaining properties related to the microcontroller | ||
|
||
%% 4. With everything configured, convert back to object | ||
config = b0shim.Config( config ); | ||
|
||
%% 5. Save as .json | ||
write_json( config, filename ) | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
classdef Channel | ||
%b0shim.parts.Channel Defines a shim coil element | ||
% | ||
% self = b0shim.parts.Channel() | ||
% | ||
% `Channel` provides a template description of a single coil element. The | ||
% properties of a `Channel` object-array thereby describe an array of coils. | ||
% | ||
% See also | ||
% [ b0shim.parts.Contents ](./Contents.md) | ||
% [ b0shim.Config ](../Config.md) | ||
|
||
properties | ||
|
||
% Shim channel ID as a string-scalar. | ||
% | ||
% `name` defines the row names when tabulating optimization results | ||
% in `b0shim.Opt.optimizeshimcurrents` (i.e. for print display). | ||
% | ||
% __EXAMPLE__ | ||
% | ||
% % Generically, this could simply be | ||
% `name = "Ch. 1"`; | ||
% | ||
% % Or, for a 2nd-order spherical harmonic term | ||
% `name = "XY (B22)"`; | ||
name(1,1) string = "Ch" ; | ||
|
||
% Shim channel physical units as a string-scalar. | ||
% | ||
% `units` is used when tabulating optimization results in | ||
% `b0shim.Opt.optimizeshimcurrents` (i.e. for print display). | ||
% | ||
% __EXAMPLE__ | ||
% | ||
% % Units are often expressed in Amperes | ||
% `units = "A"`; | ||
% | ||
% % Alternatively, for a 2nd-order spherical harmonic shim, units could be | ||
% `units = "mT/m^2"`; | ||
units(1,1) string = "A" ; | ||
|
||
% Range of permitted values as 2-element vector. | ||
% | ||
% `limits` defines the default constraints during shim optimization: | ||
% `limits(1)` specifies the minimum value; | ||
% `limits(2)` specifies the maximum value. | ||
% | ||
% Both elements should be given in the corresponding `units`. | ||
% | ||
% __EXAMPLE__ | ||
% | ||
% For an "AC/DC" multi-coil array, with `units="A"`, the value might be | ||
% `limits = [-2.5 2.5];`. | ||
limits(1,2) {mustBeNumeric,mustBeReal} ; | ||
|
||
% Label specifying coil positioning mode as a string-scalar. | ||
% | ||
% Options for `positioning` are: | ||
% | ||
% - "iso-fixed": The coil is immobile relative to isocenter (e.g. a gradient coil) | ||
% | ||
% - "table-fixed": The coil position changes with the patient-table (e.g. spine shim array) | ||
% | ||
% - "": Otherwise (e.g. coils can be freely rearranged) | ||
positioning(1,1) string {mustBeMember(positioning,["iso-fixed" "table-fixed" ""])} = "iso-fixed"; | ||
end | ||
|
||
% ========================================================================= | ||
% ========================================================================= | ||
methods | ||
% ========================================================================= | ||
function self = Channel( props ) | ||
return | ||
end | ||
% ========================================================================= | ||
|
||
end | ||
% ========================================================================= | ||
% ========================================================================= | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
% b0shim.parts — Shim system components | ||
% | ||
% Classes in `+b0shim/+parts` define parameter templates for specific shim | ||
% system components. Practically, the classes define properties of the general | ||
% system configurations (namely, config.json files on disk and `b0shim.Config` | ||
% objects in memory). The classes consist only of properties and their | ||
% constructors likely won't need to be called except when creating a new | ||
% configuration. | ||
% | ||
% Files | ||
% Channel - A shim coil element | ||
% Port - Serial port protocol parameters |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
classdef Port | ||
%b0shim.parts.Port Serial port protocol parameters | ||
% | ||
% self = b0shim.parts.Port() | ||
% | ||
% `Port` properties are simply 6 of the 7 the parameters passed to MATLAB's | ||
% `serialport` function when opening the communication line between a PC and | ||
% the microcontroller directing the shim amplifiers. Hence, the properties are | ||
% only relevant for hardware systems permitting direct control via MATLAB—USB | ||
% (i.e. systems that subclass `b0shim.Com` to define a communication interface). | ||
% For a host MRI, or a virtual shim array, this classdef is likely irrelevant. | ||
% | ||
% __NOTES__ | ||
% | ||
% 1. While `Port` properties all correspond to `serialport()` arguments, | ||
% some of the default assignments are different (`Port` defaults are informed | ||
% by the microcontrollers in use at our lab). | ||
% | ||
% 2. As a safety feature, the mandatory first argument to `serialport()`—the | ||
% device ID—is not included as a `Port` property: when connecting to a device, | ||
% a user still needs to specify the port name. (The parameter, in any case, | ||
% tends to vary as device names are determined by the OS.) | ||
% | ||
% See also | ||
% [ serialport ](https://www.mathworks.com/help/matlab/ref/serialport.html) | ||
% [ b0shim.parts.Contents ](./Contents.md) | ||
% [ b0shim.Config ](../Config.md) | ||
|
||
properties | ||
|
||
% 2nd argument to serialport | ||
BaudRate(1,1) uint32 {mustBeInteger,mustBePositive} = 9600; | ||
|
||
% Name-value argument to serialport | ||
DataBits(1,1) uint8 {mustBeMember(DataBits, [8 7 6 5] )} = 8; | ||
|
||
% Name-value argument to serialport | ||
Parity(1,1) string {mustBeMember(Parity, ["none" "even" "odd"])} = "none"; | ||
|
||
% Name-value argument to serialport | ||
StopBits(1,1) single {mustBeMember(StopBits, [1 1.5 2] )} = 1; | ||
|
||
% Name-value argument to serialport | ||
FlowControl(1,1) string {mustBeMember(FlowControl, ["none" "hardware" "software"] )} = "none"; | ||
|
||
% Name-value argument to serialport | ||
ByteOrder(1,1) string {mustBeMember(ByteOrder, ["little-endian" "big-endian"] )} = "big-endian"; | ||
|
||
% Name-value argument to serialport | ||
Timeout(1,1) single {mustBeNumeric, mustBePositive} = 10; | ||
|
||
end | ||
|
||
% ========================================================================= | ||
% ========================================================================= | ||
methods | ||
% ========================================================================= | ||
function self = Port( ) | ||
return | ||
end | ||
% ========================================================================= | ||
|
||
end | ||
% ========================================================================= | ||
% ========================================================================= | ||
|
||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to look nice on matlab's doc:
i suggest applying this format to the other Contents.m files. Also see shimming-toolbox/shimming-toolbox#134 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is the most appropriate thread to post this, but I found a very fast way to interpolate the shim coil profile maps into the grid used by the target volume (for example the EPI volume) to prepare the coil field maps for shim optimization calculations. I'm not sure how Ryan handled this in the original code.
unix('flirt -in coil_field_maps.nii -ref epi_target.nii -applyxfm -usesqform -out coil_field_maps_interp')
This seems to be ~100x faster than my previous approach which used scatteredInterpolant in Matlab. Matlab is extremely slow if you use "scattered" coordinates for the interpolation rather than monotonically increasing points such as those generated by meshgrid. The trick is to use the -usesqform flag in FLIRT, so that it will just apply a coordinate transform/interpolation without rotating or moving the image to register them.
However, I'm not sure if we want to commit to relying on FSL in the GUI. We might want to implement our own fast interpolator using the same methods as FLIRT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @jaystock, I moved the discussion to a specific issue thread shimming-toolbox/shimming-toolbox#159