-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
[Ecat2Nii] Only apply ECAT_CALIBRATION_FACTOR if it has not already b… #268
Conversation
…een applied; check CALIBRATION_UNITS to see if calibration has been applied, if it has, return input image, otherwise multiply by calibration factor. This change will correctly account for whether the calibration factor has already been applied to Ecat data. In the current version of PET2BIDS, ecat2nii will erroneously reapply the calibration factor on data that has already been calibrated, resulting in Nifti files with incorrect data objects.
Tagging @CPernet as this would include changes to the similarly functioning ecat2nii.m. |
What BIDS field is that? All the ecat we have seen are scaled but there is no 'calibration factor' as far as I remember - happy to change things. |
dose calibration is not the same as the image scaling -- this happens at two different locations, which is why I am asking what are we talking about image scaling can not be changed - would make no sense, calibration factor could -- but how do you know in the ecat data if this was apply? i have not see a field that tells anything about that -- I have never seen CALIBRATION_UNITS at 1 |
Coming back to this, if you can take a look at p9816fvat1_fbp_fixed.nii.gz, and look at the later frames- the voxel values for the background artifacts far exceed those inside the brain. Typically we might see a ratio of 10-1000 from the brightest brain voxels to the background artifacts in a later frame using our previously trusted software. PET2BIDS is doing something funny to the values, and I can't confirm necessarily that the change I made for this PR is the correct change, so I'd like your opinion on how the FBP image looks before proceeding. |
@noahg-neuroimage I haven't shared the ecat's with anyone yet for comparison, with your permission I can forward them securely via email to @CPernet and @mnoergaard. |
@noahg-neuroimage I would need to see the ecat file - not the nifti - are you fine with sharing privately via @bendhouseart |
@CPernet I confirmed with @bendhouseart last week permission to share the Ecat files with you. Can you confirm whether that was communicated? |
@noahg-neuroimage I sent over only the nifti's like a blockhead, @CPernet and @mnoergaard now have the original ecat's as well. |
I think I found the issue, see: |
Remove extra scaling applied again via nifti `scl_slope`.
@bendhouseart i don't think we should play with the slope of the nifti - instead we should apply or not directly on the data |
I'll share that previous methods we've used result in the nifti header's scl_slope set to nan. I'd presume that in this version of the code, when the calibration factor is explicitly applied, and then set in scl_slope, the result is the calibration is applied twice. This would be ignorant to whether the calibration factor has already been applied to the data, in which case the factor is applied a total of three times. |
I agree with @CPernet. In readECAT7.m there is an optional input argument to the function, where it is possible to specify whether the calibration should be 'on'. It is per default set to being uncalibrated i.e. 'off'. When it is specified as 'on', the lines of code on 183-186 are activated
since we are doing this last step outside readECAT7.m in ecat2nii.m as pointed out by @CPernet, we should apply the conditional statement here. |
@mnoergaard actually it was few lines below we needed to add the conditional statement -- info is the json I we should? report that value not matter what @bendhouseart just to be super transparent to users, I now always issue a statement about the state of the dose calibration see #271 |
Hey all, I went ahead and checked out the branch It's probably easier to describe this with a table, so I'll edit or reply to this comment after I calculate, say, the average or total value of frame X for the original ecat's, turku ecat2nii output, and pet2bids ecat2nii output. In the meanwhile feel free to examine the nifti's labeled as described that I'm about to share with you. |
overkill sounds good - thx! i guess mean square differences across the entire image would be good |
I am still not quite happy with the output from pet2bids after these recent changes. After carrying out some more testing, I can reproduce the outputs from Turku (i.e. ecat2nii), which are also in line with the ecat viewer in Vinci. But to get the same outputs as Turku, I do indeed need to apply the ecat_calibration_factor despite calibration_units being set to 1 (= calibrated), which seems counterintuitive. So that suggests that 1=calibrated means that calibration should be carried out, and 0=uncalibrated means that calibration should not be carried out? Or are the Turku ecat2nii and Vinci wrong? @CPernet and @bendhouseart I will send you some code to reproduce the behavior. |
I understood it the other way around, but as mentioned on slack I am also very confused about that |
I can confirm that, after some digging, the code we use for file conversion from Ecat at my institution does apply the calibration factor without an option not to apply it. The issue I brought up here, it turns out has to do with the python version doubly applying the calibration via scl_slope, rather than relating to CALIBRATION_UNITS in the header, at least from the user's perspective. |
Additionally, I looked at the header info on some of our Ecat phantom scans, and these scans also have CALIBRATION_UNITS=1, which may not make sense for a phantom. This field may not be informative the way I initially suggested, it's even possible our scanner was set with CALIBRATION_UNITS=1 as a default value and not changed on a per-scan basis. EDIT: For the sake of sharing information, I checked the header of an Ecat sinogram file. The unconstructed sinogram header has ECAT_CALIBRATION_FACTOR=0 and CALIBRATION_UNITS=0. So it seems the CALIBRATION_UNITS field is changed during reconstruction. |
I don't know if it all makes sense to me, but it is becoming clear. I mentioned to Cyril and Martin in another discussion, but my best guess is that someone at Siemens wanted to code the calibration factor scaling such that:
It seems like we're all on the page it this point. |
Alright, the current state of the PR contrasted with some of the previous commits, the important take away is that |
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.
👍
I'm struggling with running this fork as an independent instance of pypet2bids in order to test with my data. What's the preferred way to do this? |
Hmm, I've been using the github cli to checkout and push changes to your branch via this PR:
You should be able to |
@noahg-neuroimage if it's easier you should be able unzip (github won't let me upload a .whl file) and then pip install the attached file to test out the changes from this branch: |
I've had the chance to do some testing. It seems to work fine on OSEM images, and values within the brain for FBP look fine but values outside the brain in FBP still seem off. These seem to match up with the negative valued voxels in the original FBP ECAT image. As far as I know, negative values are valid in FBP reconstructions, however this version of ecat2nii takes the negative values in the FBP image and scales them to brighter than the brain values, which will cause issues during processing. Can the PET2BIDS team confirm whether this issue occurs when converting the supplied FBP ECAT file under the current version of ecatpet2bids? |
@noahg-neuroimage closing this PR as the original issue has been addressed and branches are all diverging, see issue #272 for continued discussion relating to FBP. Also, @CPernet @mnoergaard you've been notified too. |
@mnoergaard tracked the error and I remember we 'fixed' it because of negative values 11dca7a obviously we were wrong, mostly because we thought it was not making sense -- for to update the python reader for negative values @bendhouseart an I'm guessing reverting the matlab one |
…een applied; check CALIBRATION_UNITS to see if calibration has been applied, if it has, return input image, otherwise multiply by calibration factor.
This change will correctly account for whether the calibration factor has already been applied to Ecat data. In the current version of PET2BIDS, ecat2nii will erroneously reapply the calibration factor on data that has already been calibrated, resulting in Nifti files with incorrect data objects.
📚 Documentation preview 📚: https://pet2bids--268.org.readthedocs.build/en/268/