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

MP2RAGE #255

mathieuboudreau opened this issue Aug 8, 2018 · 12 comments

MP2RAGE #255

mathieuboudreau opened this issue Aug 8, 2018 · 12 comments


Copy link

mathieuboudreau commented Aug 8, 2018

branch: mp2rage

We might be able to write one, the original author has MATLAB code available to do this on github:

He just doesn't have a license, we could open an issue and ask if he'd be willing to upload a license that's permissive that allows for reuse (e.g. MIT).

@mathieuboudreau mathieuboudreau changed the title MP2RAGE module MP2RAGE model Aug 8, 2018
Copy link
Member Author

Spoke with Jose Marques by email today, and he gave us the green light to integrate his code into a qMRLab model. I'll get started on it after the VFA interactive notebook gets released, as the MP2RAGE notebook will be the next interactive notebook.

@mathieuboudreau mathieuboudreau self-assigned this Nov 14, 2018
@agahkarakuzu agahkarakuzu added this to the Add MP2RAGE milestone Dec 5, 2018
@mathieuboudreau mathieuboudreau changed the title MP2RAGE model [Mathieu] MP2RAGE Dec 11, 2018
@mathieuboudreau mathieuboudreau changed the title [Mathieu] MP2RAGE MP2RAGE Dec 11, 2018
Copy link
Member Author

mathieuboudreau commented Sep 12, 2019

To do:

  • Copy files from into repo
  • Upload data files to OSF
  • Create empty template MP2RAGE model, and make sure it opens.
  • Copy demo script from Marques' repo into MP2RAGE template, and make it run when "Fit data" is clicked.
  • Refactor how data inputs are handled
  • Refactor how options are handled, but still use hardcoded values
  • Create GUI options, but don't replace the hardcoded values in the code yet
  • Assert that the default input options are equal to the hardcoded demo values
  • Replace hardcoded values by passed options values
  • Refactor to handle optional B1 map case

Copy link

agahkarakuzu commented Oct 8, 2019

Difference between T1corrected.nii (B1 corrected, original output, uint16) and T1.nii.gz (B1 corrected in qMRLab, double).


Differences may be due to compression and data type. To ensure, fit using orig code and compare outputs in matlab workspace.

  • Do one more comparison
  • Add B1map range control/correction

This is how the mp2rage panel looks like:


Copy link

ileppe commented Dec 4, 2019

Hi @mathieuboudreau @agahkarakuzu! I'm trying out this model for some data that I have, I want to test different B1maps. Can I make a couple of comments/suggestions, that either I can incorporate if we agree or whoever is working on this?
1 - It's not clear which combination of inputs is required, I tried inputting just the 2 magnitude images and got an error
2 - RepetitionTimes-Exc(s): that's the echo spacing right? I think this should be named the same as it is on the protocol (Siemens or other), otherwise it's difficult to know what it's referring to
3 - How would someone find the NumberOfShots. Can we give them an idea based on the other parameters? Maybe more info in the tooltip?
4 - Inversion Efficiency: should we have a more extensive tooltip describing what this should be? How would a user know what to put here?


Copy link
Member Author

Hi @ileppe!

Thanks for the feedback! I think @agahkarakuzu was the last one to work on this just prior to the ISMRM deadline, and I don't think it's been touched since.

Brief explanation of a few things: the code used for this model is from this repo, from the author that wrote the initial paper. As far as I know, this model has only been tested for example data in that repository, so there might be a lot of use cases that we'll need to figure out as we encounter other data.

1 - I believe that the data required is the magnitude images of from both measurements (both inversion times); that's from reading the documented class. But maybe @agahkarakuzu refactored it to use the combined MP2RAGE image (what Marques calls "UNI" in his example data I think), but he'll have to chime in.

2- I think that's a naming convention that Agah used from BIDS. If I were to guess, it's the repetition time in MP2RAGE between the excitation pulses (as opposed to between the inversion pulses). If you see two repetition times in your protocol, it should be the short one.

3- re: number of shots, I was always curious as to how this would pan out in practice. I'm not entirely sure without seeing the pulse sequence or protocol files how this can be extracted (and how other groups extract it). Essentially, if it there is no accelerations or partial Fourier, it will be half of the number of acquisitions within one of the inversion time measurements (you have to look at the pulse sequence figure to understand it better), assuming that the center of k-space is acquired at that point. I'm not sure how this is automatically extracted from BIDS, @agahkarakuzu do you know?

4- Yes, a tooltip would be helpful. I think it's mostly guesswork, as I've only seen 0.96 being used. It's an estimate of how good your 180 degree pulse is I think.

Hope some of this helps, please feel free to contribute to this branch (unless @agahkarakuzu says otherwise).

Copy link


QUIT has an MP2-RAGE program here

1 - The MP2-RAGE sequence produces two raw complex volumes. These then get combined into what Siemens calls the UNIform image, and from there you can make a T1 map via a lookup table (I went a step further and used spline interpolation in QUIT). You need the complex data to correctly deal with the signal null. I prefer to start from the raw data and produce my own UNI image, because the Siemens product recon does not implement the regularisation in this paper: and so you get background noise. In QUIT, the user can produce a regularised UNI image but the T1 map is always calculated from the unregularised image to avoid bias.

2 - There is indeed a lot of confusion about what to call this value. I can't remember what it is called in the Siemens protocol, but:
a) It's not the same across vendors - on GE this will be called TR
b) "Echo Spacing" is a term more associated with Fast-Spin Echo, where you have an "Echo Train" from a single excitation and multiple refocussing pulses. I argue strongly against using this term for MP2-RAGE for the very practical reason that there are people doing multi-echo MP2-RAGE, and at that point the echo-spacing naturally refers to the spacing between echoes from a single excitation, not the time between excitations.

3 - Something doesn't look right here. There should only be one value for the number of "shots", and the number of shots is more likely to be 1 or 2 than >30. I think there is a confusion between the number of shots/segments and the number of k-space lines acquired per shot/segment. It's the latter that is required for the MP2-RAGE signal equation. In QUIT I used the term SegLength for this. In principal, you can work out the segment length from the number of PE steps and the number of segments/shots, but in practice that is hard because of partial k-space/parallel imaging, so I strongly recommend changing to this.

Anyway - tl;dr the number you want from a Siemens protocol is the Turbo Factor, which is also a term inherited from Turbo Spin Echo (Fast Spin Echo).

Copy link

Hi @ileppe @mathieuboudreau and thanks @spinicist for the input!

  1. There are two common MP2RAGE inputs to calculate T1 maps that I've observed so far: i) UNI image and ii) 2 magnitude and 2 phase images. Given that (i) is the combination of (ii), all input data are optional for this model, yet the inputs are controlled in this fashion:
    if noINV1mag && noINV1phase && noINV2mag && noINV2phase && ~noUNI
    availabledata.onlyUNI = true;
    elseif ~noINV1mag && ~noINV1phase && ~noINV2mag && ~noINV2phase && noUNI
    availabledata.allbutUNI = true;
    elseif ~noINV1mag && ~noINV1phase && ~noINV2mag && ~noINV2phase && ~noUNI
    availabledata.all = true;
    warning(sprintf(['=============== qMRLab::Fit ======================\n' ...
    'MP2RAGE data is available. Data from the following fields will not be used for T1 mapping:\n' ...
    '- Inv1mag \n -INV1phase \n -INV2mag \n -INV2phase' ...
    'If you would like to use the data listed above for fitting, please leave MP2RAGE directory empty.']));
    error(sprintf(['=============== qMRLab::Fit ======================\n' ...
    'Required data is not provided to perform T1 fitting.']));

That's why you ran into an error with 2 magnitude images only.

  1. @mathieuboudreau is right, implementation is from this repo but the naming is a mixture of BIDS and pymp2rage at the moment. @spinicist summarized this clearly. I don't know its Siemens equivalent off the top of my head either, will try looking at some Siemens data.

  2. The definition of number shots in BIDS is here. It indeed corresponds to the excitations before and after kspace center, but I see the confusion you had with the naming. I think pinging @Gilles86 here is a good idea , he can let us know how widely adopted is the parameter name NumberShots by MP2RAGE users.

As for regularized robust combination, the implementation is included in our repo , however we decided not to add it to the model for simplicity.

Copy link

ileppe commented Dec 5, 2019

Thanks all for the discussion!
2- I guess that's the issue, Siemens calls it Echo spacing and it refers to the spacing between excitation pulses. Wouldn't you agree that when you have multiple echoes (ME-MP2RAGE), they would be specified by different TEs?
3- I opened up Xbuilder on the Siemens console, and there are parameters called #exc. before and #exc. after, which must be what is being referred to in that repo? So not NumberOfShots but NumberOfLines. I don't know if that makes into the DICOM header though. For my protocol, #exc. before=60 and #exc. after=120, TurboFactor=16. So if I understand correctly, the QUIT code and JosePMarques code differ in how they choose to read in the # of lines per shot/segment. TurboFactor is definitely easier to find, at least on the Siemens protocol.

Copy link


2 - This totally depends what platform you are on, how many TEs you have, etc. I am pretty sure Echo Spacing was re-used from Turbo Spin Echo because it was already in the header (that's the kind of thing that happens on GE all the time). It doesn't make much sense for single-echo MP2-RAGE because they aren't echoes from the same excitation.
3 - This actually brings up another issue, and also indicates that I have misunderstood TurboFactor. To get accurate T1 values, you need to know the excitation in the segment that corresponds to the center of k-space. For "centric" ordering (GE default) this is the first excitation, for "linear" ordering with full k-space (Siemens default), it's N/2 where N is the segment length. This is the k0 parameter in the QUIT input. Your before and after are asymmetric, which I haven't seen before! Did you have partial k-space switched on? What was your matrix size?

I thought TurboFactor was the segment length, but a value of 16 suggests it's the number of segments - but 16 would be a weird value for that, so I'm very confused!

Copy link

Gilles86 commented Dec 5, 2019


To be honest I do not know anymore where the term NumberShots comes from. I thought I got this term from the scripts of @JosePMarques, but there he uses the term nZslices (also in the 2012 paper). Note that this can both be an integer containing the number of segments, or two numbers, representing the number of segments before and after the center of k-space...

I think that is why in my pymp2rage-package I used a new term NumberShots: it automatically derives the two set of slices by also looking for a PartialFourier metadata field (in addition to NumberShots).

"Number shots" is also a term we used in the MP2RAGE-ME paper (

Googling a bit on mri-tip and suggests that it is a proper term?

Maybe @JosePMarques has a more-informed opinion about the term "Number of Shots"?


Copy link

JosePMarques commented Dec 10, 2019 via email

Copy link

aTrotier commented Dec 10, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

7 participants