Giter Club home page Giter Club logo

qmrlab's Introduction

Build Status OCTAVE_CI_TESTS codecov Documentation Status License Website Compile Twitter Follow

hdr

qMRLab is an open-source software for quantitative MR image analysis.

Our main goal is to provide the community with an intuitive tool for data fitting, plotting, simulation and protocol optimization for a myriad of different quantitative models. The modularity of the qMRLab framework makes it easy to add any additional modules and we encourage everyone to contribute their favorite recipe for qMR!

For documentation 📖, visit the Documentation website.

If you are a developer 🛠, please visit the Wiki page.

Please report any bug 🐛 or suggestions 💭 in GitHub.

For interactive tutorials 🎚, blog posts 🖋 and more, you can visit qMRLab portal.

qMRLab is a fork from the initial project qMTLab.


FROM SCANNER

Version controlled, fully transparent & vendor-neutral pulse sequences 🌀.

⬇️

Data-driven, container-mediated, platform-agnostic & BIDS compatible workflows 🔀.

⬇️

Reproducible & modern publication 📚 objects.

TO PUBLICATION


References

qMRLab

Applications

Interactive Tutorials

Awards

  • Karakuzu A. ISMRM Research Exchange Grant 2020
  • Karakuzu A. et al. Quantitative MR Study Group Competition, second place, ISMRM 2019
  • Boudreau M. et al. Junior Fellows Symposium Challenge, Africa challenge winner, ISMRM 2019
  • Karakuzu A. et al. Magnetic Moments, People's Choice Award, ISMRM 2018

Sponsored by

Citation

If you use qMRLab in you work, please cite:

Karakuzu A., Boudreau M., Duval T.,Boshkovski T., Leppert I.R., Cabana J.F., Gagnon I., Beliveau P., Pike G.B., Cohen-Adad J., Stikov N. (2020), qMRLab: Quantitative MRI analysis, under one umbrella doi: 10.21105/joss.02343

OSF


The MIT License (MIT)

Copyright (c) 2016 NeuroPoly, Ecole Polytechnique, Universite de Montreal

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

qmrlab's People

Contributors

agahkarakuzu avatar beliveaup avatar busrabulut222 avatar harrisnami avatar iangagnon7 avatar ileppe avatar jcohenadad avatar jvelazquez-reyes avatar kthyng avatar mathieuboudreau avatar nekohayo avatar tanguyduval avatar tommyboshkovski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qmrlab's Issues

Bugs in Viewer

1- initial viewing slice is 16 --> bug when less that 16slices
2- initial colormap is "min"/"max"--> non numeric --> crash

Gabriel todo

  • clean examples, publish and integrate in sphinx
  • investigate compatibility with Octave
  • qMRLab change window position on opening
  • add push button on Protocol Optimization plot (CRLB) to stop migrations
  • compute G(0) in IRFSE and bSSFP
  • add legend for single voxel curves (circles vs cross?)
  • add qMRusage in a parent class qMRMETHOD (if possible)
  • work on CPU parallelization (to avoid looping across single voxels)
  • add test to check if all methods can be called without inputs
  • Add module to generate protocols
  • sinc --> rename because it's a core matlab function

Urgent Bug: R1f parameter fixed by default in SPGR fitting options upon startup

Conventionally, R1r is fixed to a value of 1. I noticed yesterday while debugging an issue of a new user that R1f is also being fixed by default (see red circle in screenshot below), even though the option of using R1maps is also checked. Using this configuration will lead to severe errors in the F and kf fitted parameters, as R1f, R1map, F and kf are all related through equation 7 of Sled's 2001 paper.

If R1maps are used, I can't think of a situation where R1f should be fixed, however particularly not as the default option of the software. R1maps are used to constrain R1f, so that F and kf fit better.

qmtlab_bug

I'm not very familiar with editing Matlab GUIs, however I'm fairly certain this would be an easy fix, and would make it more user-friendly for new users trying to fit their first protocols.

Ian todo

implement:

  • GenerateButtonsWithPanels
  • button_handle2opts
  • integrate GenerateButtonsWithPanels in Custom_OptionGUI
  • Correct VarNames in all functions
  • Change Protocol files in folder data (Create a Parameters.mat for all methods)
  • Finish implementing Sim_Single_Voxel_Curve into qMT_SPGR ....
  • elargir bouttons de GenerateButtonsWithPanels (hors panels). Add Scale when calling GenerateButtonsWithPanels in CustomOption_GUI
  • Delete SfTable if user cancel
  • Update function FitGo_FitData(hObject, eventdata, handles) (e.g. remove 'Prot','FitOpt)
  • Write a batch for each model
  • Add license for all external files
  • In B0Mapping Replace FSL prelude to unwarp the Phase With a Matlab function (better than unwarp.m) + add license
  • Put MTV in folder UnderDevelopment. The implementation is very specific to ex vivo dataset only... Many options need to be added to the model.
  • In ROI panel, change mouse design ( set pointer )to indicate to the user that he needs to draw on the image
  • Histogram button should use data within ROI, But should not include the 0 from mask!
  • Statistics and Histogram is redundant.. Show statistics on the histogram plot..
  • Remove button Fit Data Menu
  • In MWF, cutoff should be in Options panel not in Protocol.
  • Add simulation addon for MWF
  • Update Model in Simulations (currently you have to open the simulator each time you change in option panel)
  • clear Data when method is changed
  • Normalize Generatebuttonswithpanel using getpixelposition(ParentHandle)
  • Replace all FitDataCustom from all example
  • Remove modulaire from data_demo
  • remove bug if no starting point
  • ROI load not working
  • Add test functions that call the batch
  • Add Mew "Model" Noise/PIESNO. Ouput sigma + mask
  • In "Diffusion" batch. Use PIENO to measure sigma of noise

qMT-SPGR fitting without B1 or B0 map

Normally we do fitting qMT-SPGR with B1 and B0 maps but when we tried to remove either map, the software still takes into account the previous map which might be buffered in the memory.
We need options to fit without these maps. @jfcabana

Unit Test Template

Hi everyone,

I was speaking to Ilana today, and she mentioned that the unit tests that I currently pushed to the repo might not have been clear enough to be a template, as she was a bit confused when reading the files.

I created a repo (matlab_tests) that shows how to unit test a very simple function (sum of two numbers) using Matlab's class-based testing framework, and I've highly commented the test file for the function.

I also added some additional tips and ressources in the README.

Hope this helps some of you - let me know if anything isn't clear or could be improved!

Mathieu

Data: compress all data as nii.gz

ideally they should be hosted on another server (e.g. OSF) and downloaded during installation, to avoid adding big binaries inside the history of github repos

bug with repmat on R2013a

L162 to 166 should be modify as follows

    FitDataPanelObj = findobj('Tag', 'FitDataFileBrowserPanel');
    for ii=1:MethodCount
        FileBrowserList(ii) = MethodBrowser(FitDataPanelObj);
    end
    SetAppData(FileBrowserList);

qMTLab calls startup.m on opening --> conflicts

1- startup.m is a matlab function.. change the name to qMTstartup.m . Can produce crashes
2- Would be great to be able to work in a different folder than qMTLab. Currently if users changes the Matlab folder while qMTLab is running it creates a bug as soon as he click on a button

MTV

Test on the open source phantom data shared by Aviv's group

Create Wiki based off of ReadMe.docx

This is just a heads up to all that I intend to move the information from ReadMe.docx into a GitHub wiki. It seems that there are new features being continuously created for the software, and it would be great if information about these new features and how to use them could be added to the Wiki documentation as the project moves along. In addition, the Wiki lends itself better to version control than the *.docx filetype.

I'll probably start off by simply cutting and pasting more of the information from the *.docx into different Wiki pages, and from then on we can update any of those pages if the information is outdated (which is probably likely, since the *.docx was last updated 10 months ago).

Cheers,

Mathieu

Rendre qMTLab modulaire

Dans l'idéal, il faudrait pouvoir ajouter n'importe quel model (e.g. MTSAT / Diffusion), et pouvoir toujours bénéficier de la partie Simulation qui est très bien faite + fitting + génération des cartes.

Par exemple créer un dossier dans lequel on met tous les models. C'est à dire des script matlab qui prennent en entrée (1) variables à fitter (2) fichier de parametre d'acquisition (offsets + FA, ou bvalue + bvecs) et qui sortent (1) Signal IRM et (2) nom des variables.

Cela serait-il possible facilement tu crois JF??!! Bref je lance l'idée ici.. à développer..
Tanguy

[DTI] noise + outliers

current DTI implementation is very basic (lsq). Simulation show large bias due to rician noise (20% estimation error with SNR = 1000).
Also it would be interesting to implement RESTORE (more robust to noise)

remove choose.m in Commons

This function is already defined as local function in all scripts.
Also there is a conflict with other scripts choose.m in other toolboxes

qMRILab Meeting feedbacks

  • add colorbar
  • Move select method from menu bar to scroll list next to default menu
  • Popup for NODDI should appear only if user select NODDI
  • open viewer 4D data
  • matlab fileexchange copyright
  • write a technical paper with the new qMRI methods?
  • change readme.docx
  • Script that automatically finds citations for each model, and adds them to Readme --> George can do that (julien edits: maybe we don't need a script to do that, it's not like we have 500 models, and once the model is coded, the readme can be updated as well. Not a big management task).
  • Update Model in Simulations

Fitting crashed at first iter because of corrupted Sf Table

Build Sf Table button completes successfully but creates non monotically increasing angles using SPGR example dataset.
Produce an error at 1st iter of Fit Data:

Error using griddedInterpolant
The grid vectors are not strictly monotonic increasing.

Error in interp3 (line 130)
        F = griddedInterpolant({X, Y, Z}, V, method,extrap);

Error in GetSf (line 9)
Sfi(ii) = interp3(SfTable.offsets, SfTable.angles, SfTable.T2f, SfTable.values, xi, yi, zi);

Error in SPGR_Srp_fun (line 46)
Sf = GetSf(Angles,Offsets,T2f,Prot.Sf);

Indeed the issue is:
SfTable.angles =
0
300
400
500
600
800
1000
900
1200
1500
1800

Here is the protocol:
image

Add test functions

All example in folder data should have

  • batch_example.m
  • FitResults

Write a test script that call all the "batch_example.m" and compare the FitResults

Add B0 and/or B1 correction for SIR-FSE

Hi,
I see we dont take into account B0/B1 correction for SIRFSE, I looked in the model and feel that B1 can affect how we compute Sr as follows:
File: computeSr.m
InvPulse = GetPulse(180,0,Trf,PulseShape);

Also if we assume the Gaussian lineshape, B0 may have some effect because the offset may not be zero.
Do you see anywhere that relates to B0/B1 as well? Could you please add B0/B1 correction into the codes?

I know it is less complicated to make some assumption but it is great if we can investigate how much B0/B1correction affects the fitting results. Then using B0/B1map or not is up to the users.

Mathieu To-Do

Sharing my to-do list of tasks I plan on doing during some of my free time, usually Friday afternoons (for Open Source Fridays!).

  • If you notice that I'm working on any files that are removed or changed in a branch you're working on, let me know which branch/file so that I can redirect my work.

  • If you have any suggestions to add on my To-Do list, let me know in a comment below.

Tests

I plan on writing unit or integration tests for the following functions/files:

Refactor

  • Replace hard-coded R1f calculations (e.g. here_1 and here_2) by calls to the existing function computeR1.m.
  • Resolve the naming conflict between computeR1.m (which calculates R1f), and the FitOpt struct field R1 (which actually represents R1obs, as calculated here_1, here_2, here_3, here_4, and here_5).
  • Switch kr->kf as a default SPGR qMT fit option parameter, which is more used (kf = F*kr).
  • Move G outside of the Param structs, and instead calculated it within the Bloch and BlochSol functions. Right now, Bloch/BlochSol take delta as a param, but it's already needed to calculate G. Keeping them separate like this could lead to a delta mismatch between G and the Bloch/BlochSol delta arguments.

Documentation

  • Write help documentation for Common/pulse/*.m functions.
  • Write help documentation for Common/sim/Bloch*.m functions.
  • Add paper references to relevant qMT equations/functions.

Bug fixes

  • Fix issue where Common/sim/BlochSol.m returns a magnetization vector of type single even when the initial magnetization is of type double. Discovered while writing unit tests for this function.

Sinc function naming conflict with Matlab's built-in sinc function

I just noticed that one of our functions (sinc.m) overrides Matlab's built-in sinc function.

This could create a conflict/bug if qMRLab is in the user's path with another package that needs to use Matlab's built-in function.

It should be an easy fix, we only need to change our built in function to a unique filename & function name, and then change where it's called (I think it only gets called at one location, here).

I'm basically just opening this issue so I don't forget to fix it, but if anyone else wants to do it feel free to jump in.

[MWF] sigma of noise not used in fitting

Rician noise bias not taken into account in MWF. Sigma is used only to compute the chi2..
Resulting in an additional peak at very long T2:
image

the rician likelihood should be used as objective function: see scd_model_likelihood_rician

Fitting Panel: Use R1 map checkbox

When using the "Use R1 map" checkbox, the Fix R1f checkbox is automatically checked. This is misleading because it seems like R1f will be fixed to the value in the start column, rather than constrained by the R1 map provided.

It seems like a more natural use of this panel would be if the "Use R1 map" box was titled something like "Use R1map to constrain R1f" and the "Fix R1f" button was prevented from being checked simultaneously.
The fact that the Fix R1f button means different things in two different configurations is confusing, even after reading the manual section 5.3.

Thanks,
Melany Mclean

Biomedical Engineering, M.Sc. Candidate
Supervised by Dr. Bruce Pike

Do not delete this repo please.

Hi all,

I see that a private qMRILab repo has been created in neuropoly, and all the files of a branch of this repo have been copied into that one. That is not a great way to share between repos, as the entire commit history of this repo is no longer contained in qMRILab. I'm not quite sure why this is being done, as it is not the correct way to track commits between two repositories.

The correct method would be to make qMTLab a submodule of qMRI lab. If you were not aware of this feature, please read up on it here: https://git-scm.com/book/en/v2/Git-Tools-Submodules

Ideally, qMTLab and qDLab (and whichever else q_Labs) would be kept separate repositories, and would be added as submodules into qMRILab, where a common GUI could be created and handled...

B0 mapping: Phase unwrapping

The "prelude" unwrapping function of unix have been replace by a matlab function: 1a00c08
Here is the difference between B0map obtain with both function. As we can see, in the important region, the difference is negligible! So I supposed the new function works well enough to move forward with it.
*** The main goal of this replacement is to remove the dependence on unix. ***
What do you guys think? @mathieuboudreau @tanguyduval
screen shot 2017-07-28 at 2 41 05 pm

Issue with MWF noise calculation

We noticed that multi_comp_fit.m has a very poor way to estimate the sigma of the noise

function sigma = calc_bkgrnd_noise(data_vol, data_dim)

slices = data_dim(1,3);
height = data_dim(1,1);
width = data_dim(1,2);
voxels = height*width;
num_echoes = data_dim(1,4);

%--------------------------------------------------------------------------
% Calculate background noise 

% "default" noise level...
sigma(1:slices) = 1;

% Prepare noise mask
noise_mask = zeros(height,width,slices);

% Pick four corners of 5x5
noise_mask(1:5,1:5,:) = 1;
noise_mask(1:5,end-5:end,:) = 1;
noise_mask(end-5:end,1:5,:) = 1;
noise_mask(end-5:end,end-5:end,:) = 1;

% apply mask to the data
for slice = 1:slices
    for frame = 1:num_echoes
        noise_data(:,:,slice,frame) = data_vol(:,:,slice,frame).*noise_mask(:,:,slice); 
    end
end

noise_data = reshape(noise_data, voxels, slices, num_echoes);

for slice = 1:slices
    for frame = 1:num_echoes
        std_noise(slice,frame) = std(nonzeros(noise_data(:,slice,frame)));
    end
end

for slice = 1:slices
    sigma(slice) = mean(std_noise(slice,:));
end

end

Indeed, it simply picks the 4 corners of MET2 data, finds the standard deviation (std) for each slice and takes the mean of all std. Instead of that, we propose to use PIESNO algorithm to estimate the noise and therefore find sigma. https://www.ncbi.nlm.nih.gov/pubmed/19346143
To do so, there are 2 main possibilities:

  1. Ask Koay (the author) to obtain his Java script and consent to add it to qMRLab
  2. Directly implement the algorithm in Matlab

Let me know what's best! @jcohenadad @tanguyduval @mathieuboudreau
Ian

Magic number in superlorentzian function?

Hey Jean-François,

Could you explain how this "magic" number was chosen in the superlorentzian calculation?

https://github.com/neuropoly/qMTLab/blob/master/Common/lineshape/superlorentzianLineshape.m#L17

I understand that the purpose of the 0.00016 factor is to conserve continuity at exactly 1500 Hz, but why/how was the delta of 1140 Hz chosen for lowest possible value the on-res case? Won't this bias/underestimate the Sf table calculations for the protocol point values <1500 Hz, of which we've always used in our own protocols (see Levesque optimization paper, 2011, and Sled's 2001 paper)?

Cheers,

Mathieu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.