Fail to reconstruct a 3D cartesian accelerated acquisition

162 views
Skip to first unread message

Franck Mauconduit

unread,
Jun 12, 2020, 8:11:03 AM6/12/20
to Gadgetron
Dear Gadgetron Users, 

I fail to reconstruct a 3D cartesian accelerated acquisition. It is a iPat 2x2 accelerated acquisition with no partial fourrier and a 32x32 integrated reference lines.
I have compared to another raw data that reconstructs successfully through gadgetron and I find the following difference.

The working dataset begins at indice line #0 and acquires even lines in both phase directions.
The failing dataset begins at indice line #1 and acquires odd lines in phase encod 1, and same as above in phase encod 2

I tried to setup the raw data h5 header but I am not sure what is the correct solution. Anyway, I have (with a modified Siemens xsl file to adapt encodingLimits) :
  encodedSpace.matrixSize.x/y/z = 384/168/128
  encodingLimits.kspace_encoding_step_1.min/max/center = 1/167/85
  encodingLimits.kspace_encoding_step_2.min/max/center = 0/126/64


The server does not complain, but the client terminates with an error and no output data.
See both log info below:


Does someone have an idea about the problem I'm facing ?
If someone wants to dig a bit more, here is the Siemens raw dataset:

Thank you for any help,
Frank


LOG INFO :

Gadgetron ISMRMRD client
  -- host            :      localhost
  -- port            :      9002
  -- hdf5 file  in   :      meas_MID30_mod.h5
  -- hdf5 group in   :      /dataset
  -- conf            :      Generic_Cartesian_Grappa.xml
  -- loop            :      1
  -- hdf5 file out   :      meas_MID30_reco.h5
  -- hdf5 group out  :      2020-06-12 13:50:25
terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>'
  what():  read: End of file
Aborted (core dumped)



06-12 13:50:25.095 INFO [Server.cpp:42] Accepted connection from: ::ffff:127.0.0.1
06-12 13:50:25.103 INFO [ConfigConnection.cpp:113] Connection state: [CONFIG]
06-12 13:50:25.108 DEBUG [ConfigConnection.cpp:55] Reading config file: "/usr/local/share/gadgetron/config/Generic_Cartesian_Grappa.xml"
06-12 13:50:25.116 INFO [HeaderConnection.cpp:82] Connection state: [HEADER]
06-12 13:50:25.121 INFO [StreamConnection.cpp:75] Connection state: [STREAM]
06-12 13:50:25.121 DEBUG [Stream.cpp:52] Loading Gadget NoiseAdjust of class NoiseAdjustGadget from gadgetron_mricore
06-12 13:50:25.204 DEBUG [NoiseAdjustGadget.cpp:270] Folder to store noise dependencies is /tmp/gadgetron
06-12 13:50:25.204 DEBUG [NoiseAdjustGadget.cpp:271] NoiseAdjustGadget::perform_noise_adjust_ is 1
06-12 13:50:25.204 DEBUG [NoiseAdjustGadget.cpp:272] NoiseAdjustGadget::pass_nonconformant_data_ is 1
06-12 13:50:25.204 DEBUG [NoiseAdjustGadget.cpp:273] receiver_noise_bandwidth_ is 0.793000
06-12 13:50:25.204 DEBUG [NoiseAdjustGadget.cpp:285] Measurement ID is 18917_0273239_3351396_30
06-12 13:50:25.204 DEBUG [Stream.cpp:52] Loading Gadget AsymmetricEcho of class AsymmetricEchoAdjustROGadget from gadgetron_mricore
06-12 13:50:25.206 DEBUG [AsymmetricEchoAdjustROGadget.cpp:23] max RO for encoding space  0 : 384
06-12 13:50:25.206 DEBUG [Stream.cpp:52] Loading Gadget RemoveROOversampling of class RemoveROOversamplingGadget from gadgetron_mricore
06-12 13:50:25.207 DEBUG [RemoveROOversamplingGadget.cpp:43] RemoveROOversamplingGadget:omp_set_num_threads(1) ... 
06-12 13:50:25.207 DEBUG [Stream.cpp:52] Loading Gadget AccTrig of class AcquisitionAccumulateTriggerGadget from gadgetron_mricore
06-12 13:50:25.207 DEBUG [Stream.cpp:52] Loading Gadget BucketToBuffer of class BucketToBufferGadget from gadgetron_mricore
06-12 13:50:25.207 DEBUG [Stream.cpp:52] Loading Gadget PrepRef of class GenericReconCartesianReferencePrepGadget from gadgetron_mricore
06-12 13:50:25.210 DEBUG [GenericReconBase.cpp:41] Debug folder is not set ... 
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:42] Number of encoding spaces: 1
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:53] ---> Encoding space : 0 <---
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:54] Encoding matrix size: 384 168 128
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:55] Encoding field_of_view : 440 192.5 153.6
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:56] Recon matrix size : 192 168 128
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:57] Recon field_of_view :  220 192.5 153.6
06-12 13:50:25.210 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:68] acceFactorE1 is 2
06-12 13:50:25.211 DEBUG [GenericReconCartesianReferencePrepGadget.cpp:69] acceFactorE2 is 2
06-12 13:50:25.212 DEBUG [Stream.cpp:52] Loading Gadget CoilCompression of class GenericReconEigenChannelGadget from gadgetron_mricore
06-12 13:50:25.214 DEBUG [GenericReconBase.cpp:41] Debug folder is not set ... 
06-12 13:50:25.215 DEBUG [GenericReconEigenChannelGadget.cpp:42] Number of encoding spaces: 1
06-12 13:50:25.215 DEBUG [Stream.cpp:52] Loading Gadget Recon of class GenericReconCartesianGrappaGadget from gadgetron_mricore
06-12 13:50:25.215 DEBUG [GenericReconBase.cpp:41] Debug folder is not set ... 
06-12 13:50:25.215 DEBUG [ImageArraySendMixin.hpp:132] ---> Encoding space : 0 <---
06-12 13:50:25.215 DEBUG [ImageArraySendMixin.hpp:133] Encoding matrix size: 384 168 128
06-12 13:50:25.215 DEBUG [ImageArraySendMixin.hpp:136] Encoding field_of_view : 440 192.5 153.6
06-12 13:50:25.215 DEBUG [ImageArraySendMixin.hpp:139] Recon matrix size : 192 168 128
06-12 13:50:25.215 DEBUG [ImageArraySendMixin.hpp:142] Recon field_of_view :  220 192.5 153.6
06-12 13:50:25.215 DEBUG [GenericReconGadget.cpp:32] Number of encoding spaces: 1
06-12 13:50:25.215 DEBUG [GenericReconGadget.cpp:54] acceFactorE1 is 2
06-12 13:50:25.215 DEBUG [GenericReconGadget.cpp:55] acceFactorE2 is 2
06-12 13:50:25.216 DEBUG [GenericReconCartesianGrappaGadget.cpp:39] Number of encoding spaces: 1
06-12 13:50:25.216 DEBUG [Stream.cpp:52] Loading Gadget PartialFourierHandling of class GenericReconPartialFourierHandlingFilterGadget from gadgetron_mricore
06-12 13:50:25.216 DEBUG [Stream.cpp:52] Loading Gadget KSpaceFilter of class GenericReconKSpaceFilteringGadget from gadgetron_mricore
06-12 13:50:25.217 DEBUG [Stream.cpp:52] Loading Gadget FOVAdjustment of class GenericReconFieldOfViewAdjustmentGadget from gadgetron_mricore
06-12 13:50:25.217 DEBUG [Stream.cpp:52] Loading Gadget Scaling of class GenericReconImageArrayScalingGadget from gadgetron_mricore
06-12 13:50:25.225 DEBUG [Stream.cpp:52] Loading Gadget ImageArraySplit of class ImageArraySplitGadget from gadgetron_mricore
06-12 13:50:25.226 DEBUG [Stream.cpp:52] Loading Gadget ComplexToFloatAttrib of class ComplexToFloatGadget from gadgetron_mricore
06-12 13:50:25.226 DEBUG [Stream.cpp:52] Loading Gadget FloatToShortAttrib of class FloatToUShortGadget from gadgetron_mricore
06-12 13:50:25.226 DEBUG [Stream.cpp:52] Loading Gadget ImageFinish of class ImageFinishGadget from gadgetron_mricore
06-12 13:50:25.272 DEBUG [NoiseAdjustGadget.cpp:97] Saving noise to /tmp/gadgetron/GadgetronNoiseCovarianceMatrix_18917_0273239_3351396_30
06-12 13:50:28.520 DEBUG [AcquisitionAccumulateTriggerGadget.cpp:159] Trigger (1) occurred, sending out 1 buckets
06-12 13:50:28.520 DEBUG [BucketToBufferGadget.cpp:50] BUCKET_SIZE 5376 ESPACE 1
06-12 13:50:28.520 DEBUG [BucketToBufferGadget.cpp:184] Data dimensions [RO E1 E2 CHA N S SLC] : [192 168 128 32 1 1 1]
06-12 13:50:28.895 DEBUG [BucketToBufferGadget.cpp:389] Encoding space : 0 - FOV : [ 440 192.5 153.6 ]  - Matris size : [ 384 168 128 ] 
06-12 13:50:28.895 DEBUG [BucketToBufferGadget.cpp:396] Sampling limits : - RO : [ 0 96 191 ] - E1 : [ 0 84 166 ] - E2 : [ 0 64 126 ]
06-12 13:50:28.902 DEBUG [BucketToBufferGadget.cpp:184] Data dimensions [RO E1 E2 CHA N S SLC] : [192 168 128 32 1 1 1]
06-12 13:50:29.285 DEBUG [BucketToBufferGadget.cpp:389] Encoding space : 0 - FOV : [ 440 192.5 153.6 ]  - Matris size : [ 384 168 128 ] 
06-12 13:50:29.285 DEBUG [BucketToBufferGadget.cpp:396] Sampling limits : - RO : [ 0 96 191 ] - E1 : [ 0 84 166 ] - E2 : [ 0 64 126 ]
06-12 13:50:29.331 DEBUG [BucketToBufferGadget.cpp:90] End of bucket reached, sending out 1 ReconData buffers


Sen Jia

unread,
Jun 18, 2020, 1:22:19 AM6/18/20
to Gadgetron
Hi,

I have tried your dataset (.dat, Siemens VB data) on my local machine with the following information: siemens_to_ismrmrd 1.0.1, ismrmrd 1.3.2, gadgetron 3.12.0 (a very old version), and I could get a correct recon using Generic_Cartesian_Grappa.xml. See image Figure 1.

I also tried your h5 file with the same configuration, and could also get an image, but my Bucket_to_Buffer gadget complained (but still work) that the encoding limits provided in ismrmrd xsl header were wrong. So I changed your encodingLimits back to 

 encodingLimits.kspace_encoding_step_1.min/max/center = 0/168 /84
 encodingLimits.kspace_encoding_step_2.min/max/center = 0/128 /64

and get a recon image. See the images Figure 2.

The difference between Figure 1 & Figure 2 was due to the Native SPACE data on Siemens VB platform need a RawDataCorrection. The offline siemens_to_ismrmrd converter I used didn't provide the function of RawDataCorrection, thus you have to do it manually. After that, you may get the correct image.

Best wishes,
Jia Sen 

Figure 1
Figure 1.png
Figure 2
Figure 2.png

Franck Mauconduit

unread,
Jun 18, 2020, 9:54:48 AM6/18/20
to Gadgetron
Dear Sen,


Thank you for having taken the time to look at my issue. It seems you get a solution. The reconstructed image looks perfectly reconstructed as it is similar to what ICE provides.

Would you have more information to share on the RawDataCorrection you are talking about ?
Looking at ICE reconstruction, I do not see any particular raw correction. I don't understand what I am missing here.

Regards,
Franck

Sen Jia

unread,
Jun 18, 2020, 11:45:26 AM6/18/20
to Gadgetron
Hi,

The following matlab code do the RawDataCorrection to your h5 file:

%% get the rawdata correction factors from dat file using mapVBVD
dat_file_name = 'meas_MID30_NS_SPACE_Pat_2x2_PFoff_FID14643.dat';
twixobj = mapVBVD(dat_file_name,'removeos',1,'ignoresegments',1,'doAverage',1,'doRawDataCorrect',1);
dataobj = twixobj.image;
CorrectionFactors = dataobj.RawDataCorrectionFactors;

%% enter the h5 file given by siemens_to_ismrmrd converter
h5_file_name = 'meas_MID30_mod.h5';
dataset = ismrmrd.Dataset(h5_file_name,'dataset');
hdr = ismrmrd.xml.deserialize(dataset.readxml);

data = dataset.readAcquisition();    % the acquired lines are stored in data
mdh = data.head;                  % mdh header
total_scan_num = data.getNumber;


%% do rawdata correction
doRawDataCorrect = 1;
if (doRawDataCorrect)
    
    isNeedCorrection = data.head.flagIsSet('ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA');
    NeedCorrection_acqs = find(isNeedCorrection==1);
    if (length(NeedCorrection_acqs) > 1)
        disp('Need to do Surface Coil Correction!');
        NeedCorrection_data = data.select(NeedCorrection_acqs);
        for iter = 1:1:length(NeedCorrection_acqs)
            temp = NeedCorrection_data.data{iter};
            ncha = size(temp,2);
            for icha = 1:1:ncha
                temp(:,icha) = temp(:,icha).*CorrectionFactors(icha);
            end
            NeedCorrection_data.data{iter} = temp;
        end
        data.data(NeedCorrection_acqs) = NeedCorrection_data.data;
    else
        disp('No Need for Surface Coil Correction !');
    end
end

%% wirte corrected dataset to a new h5 file
disp('Create corrected h5 file')
corrected_h5_file_name = strcat(h5_file_name(1:1:(length(h5_file_name)-3)),'_corrected.h5');
dataset_new = ismrmrd.Dataset(corrected_h5_file_name);
dataset_new.appendAcquisition(data);

dataset_new.writexml(ismrmrd.xml.serialize(hdr));
dataset_new.close();


Best wishes,
Jia Sen

Franck Mauconduit

unread,
Jun 19, 2020, 5:09:12 AM6/19/20
to Gadgetron


Your remark regarding RawDataCorrection is right. To test your solution, my strategy was to send the reconstruction from ICE within IDEA so that the correction was applied. The reconstructed images was already better (thank you Jia) but ...


I also needed to downgrade to gadgetron 3.14.1 to obtain the expected reconstructed image. With gadgetron 3.17.0, it did not work anymore, nor with gadgetron 4.1.1
Here is a sreenshot of reconstructed images.


SPACE_reconstruction_problem.png

SPACE_reconstruction_problem.png

Sen Jia

unread,
Jun 19, 2020, 12:00:39 PM6/19/20
to Gadgetron
Hi, I can reproduce the image difference induced by different Gadgetron version (3.12.0 vs 4.1.1).  My test of 4.1.1 on my own 3D SPACE datasets (which work normally with 3.12.0) also fails. The magnitude & phase image difference suggested that this difference might be related to the coil map estimation algorithm or grappa unmixing coefficient calculation.

Figure1.png

Best wishes,
Jia Sen
Reply all
Reply to author
Forward
0 new messages