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

Introducing Two Compartment exchange Model #48

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Conversation

MohamedNasser8
Copy link
Collaborator

This PR adds:

1. Model Function: Implemented the 2CXM.

2. Documentation: Added detailed documentation explaining the model.

3. Testing: Conducted some tests to validate the model’s performance and accuracy.

@plaresmedima
Copy link
Collaborator

plaresmedima commented Sep 3, 2024 via email

@MohamedNasser8
Copy link
Collaborator Author

Hello @plaresmedima ,
In this case, what should the output be if ​Vp=0? My understanding is that the original model equation wouldn't be valid under this condition. The compartment equation from which the model is derived would change, meaning we can't simply apply the same model equation as before.

Is that correct?

@plaresmedima
Copy link
Collaborator

plaresmedima commented Sep 3, 2024 via email

@MohamedNasser8
Copy link
Collaborator Author

No, it's still waiting for review.

@plaresmedima
Copy link
Collaborator

plaresmedima commented Sep 3, 2024 via email

@MohamedNasser8
Copy link
Collaborator Author

Yes, I used the OSIPI DCE code collection as a reference for my implementation. Additionally, I've included a plot of the model in the documentation to help ensure it's been implemented correctly.

@ltorres6
Copy link
Collaborator

ltorres6 commented Sep 3, 2024

@plaresmedima Thanks for your input, I agree that we need to ensure proper handling of edge cases as well as non-sensical numbers (negatives, nan's, etc). I will make sure to keep my eyes peeled for these things when I get a chance to review. By chance do you have an implementation Mohamed can use as another example of the 2cx model?

@MohamedNasser8 We will want to ensure we handle the edge cases here carefully. As Steven mentions, when Vp is zero, we effectively are effectively stating that the plasma compartment in the 2 compartment model is non-existent, which simplifies the model to the Tofts variation with only the extravascular extracellular compartment.

@plaresmedima
Copy link
Collaborator

plaresmedima commented Sep 4, 2024 via email

@LucyKershaw
Copy link
Collaborator

I have a few things that need looking at:

  1. The osipi name is the two compartment exchange model - please change in _tissue line 377
  2. Lexicon units for Fp are ml/min/100 ml tissue. You have stated ml/min/100g tissue. My code (that I think you've used) is in ml/min/ml tissue. You have stated time in units of seconds but I see no conversions between any units. Please check that the curves produced are correct.
  3. Add a reference to the paper that defines the 2CXM using these parameters (TE, TB etc)
  4. In test_tissue some of the comments have been cut off, for example in line 128 it says '1. Basic operation of the function - test that the peak tissue' which no longer makes sense. This has happened for test 2 and (I think) test 3
  5. @plaresmedima and @MohamedNasser8 this is my implementation of the model that was compared to the others here:
    https://osipi.github.io/DCE-DSC-MRI_TestResults/2CXM.html
    It has bias so it would be better to use one of the other contributed versions instead - they all seem to match well.
  6. We will need to think carefully about how to test edge cases, but I don't think we've done this extensively for the other models either. I agree that vp=0 shouldn't throw an exception. Perhaps my implantation is lazy, but for now it's the way that the lexicon defines the model so it will probably do. In future we can add more ways to calculate.

@plaresmedima
Copy link
Collaborator

plaresmedima commented Sep 11, 2024 via email

@MohamedNasser8
Copy link
Collaborator Author

@LucyKershaw I’ve converted all the units to the correct values and added a corner case for when vp equals zero.
Can you provide the reference for this implementation to include it in the documentation?

@LucyKershaw
Copy link
Collaborator

Hi Mohamed,

Are you still working on this? If so, I think this needs to change a bit more - having discussed with others I think a different implementation of this model would be better. We tested all the contributed versions and in some cases this implementation ended up with outliers (https://osipi.github.io/DCE-DSC-MRI_TestResults/2CXM.html) Obviously this is entirely my fault so if you don't want to change it feel free to assign this to me instead! The MB, MJT and OGJ versions all give similar answers over a wider set of parameter space so they would be a better addition to the package.

@MohamedNasser8
Copy link
Collaborator Author

Okay, I'll take a look into the other implementations

@MohamedNasser8
Copy link
Collaborator Author

Hello @LucyKershaw, I changed the implemented model to MJT; a lot of testing is required.
If you could please take a look; if it's good, I'll complete the tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Permeability-surface area product is PS not Ps
volume fractions are small letters not capitals
Volume fractions in CAPLEX are ml/100ml
Flow in CAPLEX is in ml/100ml/min
PS is in ml/100ml/min

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MohamedNasser8 if you have fixed these please resolve this comment

Copy link
Collaborator

@LucyKershaw LucyKershaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've added comments to the files, but the units need looking at again, there's a factor of 100 that I'm unsure about and the units and symbols don't match the CAPLEX units. CAPLEX codes are missing for inputs.
Did MJT include a reference for this implementation of the model?

src/osipi/_tissue.py Show resolved Hide resolved
@MohamedNasser8
Copy link
Collaborator Author

MohamedNasser8 commented Nov 15, 2024

Hey @LucyKershaw, sorry for this delay, I fixed your comments.
this is an example of the output by changing values, I want to make sure it looks right!
image

mkd_glr_plot_two_cxm_001

@LucyKershaw
Copy link
Collaborator

I'm sorry, I can't tell just from looking at the curves whether they're correct or not. You could try generating test curves and seeing if they match the data detailed here:
https://osipi.github.io/DCE-DSC-MRI_TestResults/2CXM.html

And in the file here:
https://github.com/OSIPI/DCE-DSC-MRI_CodeCollection/blob/develop/test/DCEmodels/data/2cxm_sd_0.001_delay_0.csv

Let me know how you go on

@MohamedNasser8
Copy link
Collaborator Author

MohamedNasser8 commented Nov 15, 2024

It generates identical curves now using the same data here: https://github.com/OSIPI/DCE-DSC-MRI_CodeCollection/blob/develop/test/DCEmodels/data/2cxm_sd_0.001_delay_0.csv
But I can't find the reference to this implementation on mjt code.

Fixed some errors in the implementation, some units and naming
@MohamedNasser8
Copy link
Collaborator Author

Hey @ltorres6, @LucyKershaw, @stadmill all, I've added some tests, but I think a lot is yet to be covered.
I validated the output using the example files Dr. Lucy provided above.

Copy link
Collaborator

@ltorres6 ltorres6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Mohamed, good start on the testing. Here are some improvements you can make for testing this function:

  • You test 4 different scenarios within one function here. It's best to separate these tests into subtests for debugging purposes, as well as to avoid simply failing on the first test and not running consecutive tests.
  • Two of the assertions are asserting the same thing (tissue concentration is less than AIF), just for different input arguments.
  • Your test function doesn't really provide information on failures.

Can you please try the following:

  • Use pytest. You'll need to ensure it's included as a dependency and imported in the tests file.
  • Create separate test functions for the offset test and edge cases tests (Vp=0) from the first two (basic functionality).
  • Use parameterization decorators to assign variables and expected results.
@pytest.mark.parametrize("a,b,c", [(np.linspace(0, 6 * 60, 360), 10, 5)])
def test_function_here(a,b,c):
  • You also have to remember to test the invalid arguments in these cases. What happens when your variables/arguments are negative? You should create a separate test function for this.
    All in all, you should have 4 different test functions, one for the basic functionality, one for the offset test, one for the tofts behavior, and one for invalid inputs.

Please take a crack at it and reach out on slack if you have any questions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MohamedNasser8 if you have fixed these please resolve this comment

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

Successfully merging this pull request may close these issues.

4 participants