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

volOps.createResampledPrimaryVolume : 'Unsupported operation' #28

Open
mfizyczka opened this issue Apr 15, 2022 · 5 comments
Open

volOps.createResampledPrimaryVolume : 'Unsupported operation' #28

mfizyczka opened this issue Apr 15, 2022 · 5 comments

Comments

@mfizyczka
Copy link

I'm loading CT as primaryVolume and CBCT as secondaryVolume. Then I do registrations:

cbctRegistration = regOps.createNewRegistration('cbctRegistration')
rigidRegistrationSettings = velocity.DefaultRigidRegistrationSettings()
# PreprocessingFilterMethod: CBCTCorrectionSecondary = 4
rigidRegistrationSettings.preprocessingMethod = 4
regOps.performRigidRegistrationDICOM(rigidRegistrationSettings)
regOps.saveRegistration()

deformableRegistrationSettings = velocity.DefaultBSplineDeformableRegistrationSettings()
# PreprocessingFilterMethod: CBCTCorrectionSecondary = 4
deformableRegistrationSettings.preprocessingMethod = 4
# Deformable registration Type:
deformableRegistrationSettings.type = velocity.DeformableMultiPass
regOps.performBsplineRegistrationDICOM(deformableRegistrationSettings)
regOps.saveRegistration()

With that registration I'm trying to resample CT (primary volume) to CBCT FOR:
vCtVolumeId = volOps.createResampledPrimaryVolume(0, 'vCT')
volOps.getErrorMessage() returns 'Unsupported operation' why is that?

@aanghele
Copy link
Member

from the guide:

createResampledPrimaryVolume(elementOperation, name = “”, scalingCoefficient = 1.0)
Description
Performs the resampling of the specified element operation for the loaded primary volume
An error will occur if the specified element operation must be performed on multiple volumes
Returns the volume id of the created volume unless there is an error, in which -1 is returned
The only elementOperation available for single volume resampling is VolumeResampleScale = 7

Are you trying to use the adaptive workflow to reshape the CT ? You can use createResampledVolume() with VolumeResampleReshape op , it will create the deform-back registration automatically.

@mfizyczka
Copy link
Author

Thanks for the answer. I read this description before and it wasn't clear for me. I don't want to perform resampling on multiple volumes just on Primary volume. I understand now that what you meant here was that Secondary Volume cannot be loaded.

Indeed I want to create CT - CBCT(corrected) deformable registration and then use this registration to create synthetic CT.

If I understand this correctly deformed(CT-CBCT) registration is not equal to reversed deformed(CBCT-CT) registration. That is why I was looking for solution to use the deformed(CT-CBCT).

@aanghele
Copy link
Member

When you use the Reshape operation, the system is designed to use the inverse deform. The assumption is that the deformable loaded when creating the synthetic CT is built on the rigid registration corresponding to the onlinematch ( or table shifts) because the rigid component also plays a part in the reshape. That is how the GUI workflow ACTOR works as well, there is no way to bypass using the inverse deform if you want to use the Reshape operation in Velocity.

@afwaller
Copy link

The reshape operation (create adaptive CT) is fairly complex. It can be manually executed using just volume operations (rigid resample, deformable resample, add, subtract) but this is considerably more time consuming and will introduce errors due to aliasing, floating point math, voxel boundary alignment issues, and multiple deformable registrations (which may disagree in some slight ways). Reshape has been optimized internally to provide the highest quality result and avoid these issues, but part of that optimization is that the reshape operation does internally use the inverse transform, and also requires that your table shifts (ONLINEMATCH) are baked into the deformable - it does not use a separate rigid registration object for this.

We can schedule a call if you would like to understand more about this function and the clinical background as well as technical reasons why it was implemented in this fashion. There is also some Varian IP around the internals of how the operation works.

@mfizyczka
Copy link
Author

@aanghele @afwaller thank you for your answers and explanations.

I'd certainly like to understand more about the Reshape function and adaptive CT generation. It would be great if we can schedule a call. Thanks for the offer.

At this moment I have these questions:

  • What is the difference between ResampleReplace and ResampleReshape? Do you have a recomendation which Resample Operation (also other operations) should be used when?
  • In which FOR is adaptive CT (aka virtual CT / synthetic CT) created - is it CBCT?
  • for volOps.createResampledVolume with ResampleReshape - which volume should be loaded as primary and which as secodary

If I aim to reproduce adaptive CT creation as is done with ACTOR Navigator (but without loading a plan) would it be done in that way (at this moment without resampling structures):

# load pCT as secondary:
primaryVolume = engine.loadPrimaryVolume(pCtId)
print('\t\tLoading pCT as primary volume.', engine.getErrorMessage())
# load CBCT as secondary:
secondaryVolume = engine.loadSecondaryVolume(cbctId)
print('\t\tLoading CBCT as secondary volume.', engine.getErrorMessage())

# select online match registration:
for r in primaryVolume.getLinkedRegistrations(): 
  if r.getTargetVolume().getVelocityId() == cbctId and 'ONLINEMATCH' in r.getName():
    #  registrationId = r.getVelocityId()
    cbctRegistration = engine.loadRegistration(r.getVelocityId())
    print('\t\tLoading pCT-CBCT ONLINEMATCH.', engine.getErrorMessage())

# perform deformable registration:
deformableRegistrationSettings = velocity.DefaultBSplineDeformableRegistrationSettings()
# PreprocessingFilterMethod: CBCTCorrectionSecondary = 4
deformableRegistrationSettings.preprocessingMethod = 4
# Deformable registration Type:
deformableRegistrationSettings.type = velocity.DeformableMultiPass
regOps.performBsplineRegistrationDICOM(deformableRegistrationSettings)
print('\t\tCBCT to pCT deformable registration (MultiPass with CBCTCorrectionSecondary).', regOps.getErrorMessage())
regOps.saveRegistration()
print('\t\tSaving registration.', regOps.getErrorMessage())

# reshape pCT into CBCT FOR:
# VolumeResampleReshape = 9
vCtVolumeId = volOps.createResampledVolume(9, 'vCT' + str(i) + '_cbctCorrFOR_' + secondaryVolume.getAcquisitionDate(), 1.0)
print('\t\tResampling pCT to CBCT FOR (=creating vCT).', volOps.getErrorMessage())

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

No branches or pull requests

3 participants