FloatToShort Gadget is not executer after a Matlab gadget

116 views
Skip to first unread message

Karyna Isaieva

unread,
Jun 29, 2020, 10:19:29 AM6/29/20
to Gadgetron
Dear Gadgetron community,

I would like to return an image reconstructed with a Matlab gadget back to the scanner and for that I need to convert it to ushort format. I am trying to use FloatToUShortGadget, but it just does nothing. At the same time the writer works fine and I can read the resulting h5 files with images, but they are in double format. One of the images is of magnitude type, another is of phase type, which was set in the header before passing them further. I also have a third image which is a matlab figure transformed to the array, just to test how it works, I also set magnitude type to it. But in any case, if I don't pass the third image, it still doesn't work. I verified that the new xml file was copied to the /usr/local/share/gadgetron/config and that the Gadgetron server was restarted after the copy. I am using a Docker image (Ubuntu 2004).

There is also no errors in the log (attached as a file).

Of course I could transform the images to ushort type directly in the Matlab, but obviously I made a mistake and I would like to understand what did I do wrong. Just to make my words clearer, I am attaching the code of the gadget and of the xml config file. Could someone explain me what is wrong please?

Thank you in advance!
Sincerely,
Karyna
config_rtpc.xml
rtpc_gadget.m
gadgetron_log_29062020.log

Oliver Josephs

unread,
Jun 29, 2020, 12:27:54 PM6/29/20
to Gadgetron
Hi Karyna,

Look like it should work. Here some possibilities to try.

I have the writers, with the readers, before the stream. That should not matter.

And my MATLAB data is defined as 'single'. E.g. your line would be:

   new_data = zeros(E0, CHA, E1 * REP * SET, 'like', single(1i));

N.B. the gadgetron_ismrmrd_client appends to the out.h5 file. So delete out.h5 before running to check you are definitely examining the latest images. Can you examine with h5info like the following? As you see I get Type: 'H5T_STD_U16LE' in out.h5.

Oliver

>> a=h5info('out.h5')

a = 

  struct with fields:

      Filename: '/media/mr/Backup Plus/EPI3D_data/raw_data_20200616/out.h5'
          Name: '/'
        Groups: [2×1 struct]
      Datasets: []
     Datatypes: []
         Links: []
    Attributes: []


>> a.Groups(1).Groups

ans = 

  struct with fields:

          Name: '/2020-06-29 12:09:08/image_0'
        Groups: []
      Datasets: [3×1 struct]
     Datatypes: []
         Links: []
    Attributes: []

>> a.Groups(1).Groups.Datasets

ans = 

  3×1 struct array with fields:

    Name
    Datatype
    Dataspace
    ChunkSize
    FillValue
    Filters
    Attributes

>> a.Groups(1).Groups.Datasets(1)

ans = 

  struct with fields:

          Name: 'attributes'
      Datatype: [1×1 struct]
     Dataspace: [1×1 struct]
     ChunkSize: 1
     FillValue: []
       Filters: []
    Attributes: []

>> a.Groups(1).Groups.Datasets(2)

ans = 

  struct with fields:

          Name: 'data'
      Datatype: [1×1 struct]
     Dataspace: [1×1 struct]
     ChunkSize: [240 240 88 1 1]
     FillValue: 0
       Filters: []
    Attributes: []

>> a.Groups(1).Groups.Datasets(2).Datatype

ans = 

  struct with fields:

          Name: ''
         Class: 'H5T_INTEGER'
          Type: 'H5T_STD_U16LE'
          Size: 2
    Attributes: []

Karyna Isaieva

unread,
Jun 30, 2020, 3:24:25 AM6/30/20
to Gadgetron
Dear Oliver,

Thanks a lot! Setting the output data to single type array resolved the issue

Sincerely,
Karyna

понедельник, 29 июня 2020 г., 18:27:54 UTC+2 пользователь Oliver Josephs написал:

Karyna Isaieva

unread,
Jun 30, 2020, 11:46:40 AM6/30/20
to Gadgetron
Hi,

I tried to run the code on the scanner. And unfortunately, it does not work. I used exactly the same sequence to generate the rawdata which I use on my standalone computer and this time on the scanner. I also use the same docker image. Here is the log:
06-30 10:04:51.182 INFO [Server.cpp:42] Accepted connection from: ::ffff:192.168.2.2
06-30 10:04:51.183 INFO [ConfigConnection.cpp:113] Connection state: [CONFIG]
06-30 10:04:51.383 DEBUG [ConfigConnection.cpp:55] Reading config file: "/usr/local/share/gadgetron/config/config_rtpc.xml"
06-30 10:04:51.384 INFO [HeaderConnection.cpp:82] Connection state: [HEADER]
06-30 10:04:51.391 INFO [StreamConnection.cpp:75] Connection state: [STREAM]
06-30 10:04:51.391 DEBUG [Stream.cpp:52] Loading Gadget  of class NoiseAdjustGadget from gadgetron_mricore
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:270] Folder to store noise dependencies is /tmp/gadgetron
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:271] NoiseAdjustGadget::perform_noise_adjust_ is 1
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:272] NoiseAdjustGadget::pass_nonconformant_data_ is 1
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:273] receiver_noise_bandwidth_ is 0.793000
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:285] Measurement ID is 166008_348214405_348214414_128
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:300] Measurement ID of noise dependency is 166008_348214405_348214414_122
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:305] Stored noise dependency is /tmp/gadgetron/GadgetronNoiseCovarianceMatrix_166008_348214405_348214414_122
06-30 10:04:51.406 DEBUG [NoiseAdjustGadget.cpp:310] Stored noise dependency is NOT found : /tmp/gadgetron/GadgetronNoiseCovarianceMatrix_166008_348214405_348214414_122
06-30 10:04:51.406 DEBUG [Stream.cpp:52] Loading Gadget  of class RemoveROOversamplingGadget from gadgetron_mricore
06-30 10:04:51.408 DEBUG [RemoveROOversamplingGadget.cpp:43] RemoveROOversamplingGadget:omp_set_num_threads(1) ... 
06-30 10:04:51.408 DEBUG [Stream.cpp:52] Loading Gadget AccTrig of class AcquisitionAccumulateTriggerGadget from gadgetron_mricore
06-30 10:04:51.408 DEBUG [Stream.cpp:52] Loading Gadget Buff of class BucketToBufferGadget from gadgetron_mricore
06-30 10:04:51.408 DEBUG [Stream.cpp:64] Loading External Connect block on port 18000 
06-30 10:04:51.409 DEBUG [Stream.cpp:52] Loading Gadget AutoScale of class AutoScaleGadget from gadgetron_mricore
06-30 10:04:51.409 INFO [External.cpp:53] Connecting to external module on address: 192.168.139.79:18000
06-30 10:04:51.410 DEBUG [Stream.cpp:52] Loading Gadget FloatToShort of class FloatToUShortGadget from gadgetron_mricore
06-30 10:04:51.411 ERROR [Core.cpp:18] [Connection Main Thread/Connection Input Thread] ERROR: Received second ISMRMRD header. Only one allowed.
06-30 10:04:51.412 DEBUG [AcquisitionAccumulateTriggerGadget.cpp:159] Trigger (1) occurred, sending out 0 buckets
06-30 10:05:14.667 ERROR [Core.cpp:18] [Connection Main Thread//external] ERROR: map::at
06-30 10:05:14.668 DEBUG [Gadget.h:130] Shutting down Gadget ()
06-30 10:05:14.668 DEBUG [Gadget.h:130] Shutting down Gadget ()
06-30 10:05:14.669 DEBUG [Gadget.h:130] Shutting down Gadget ()
06-30 10:05:14.669 INFO [Core.cpp:76] Connection state: [FINISHED]


Unfortunately, I didn't save the error text from the Matlab side. But it crashes on the line acquisition = connection.next;

Does anyone have a guess why it does not work? What could be the difference between the data pushed during the acquisition directly and the result of conversion of a rawdata taken after the acquisition? Maybe it goes to the chain in another way, by different portions?

Sincerely,
Karyna


вторник, 30 июня 2020 г., 9:24:25 UTC+2 пользователь Karyna Isaieva написал:

Oliver Josephs

unread,
Jun 30, 2020, 12:41:43 PM6/30/20
to Gadgetron
Hi,

This error looks strange:

06-30 10:04:51.411 ERROR [Core.cpp:18] [Connection Main Thread/Connection Input Thread] ERROR: Received second ISMRMRD header. Only one allowed.

Check that your IceGadgetron xml config file (i.e. the file that e.g. specifies where emitter functor is placed) is not specifying to send a local gadgetron config file, but asking for the server-based config. Perhaps could you post the whole file here?

Oliver

Karyna Isaieva

unread,
Jul 1, 2020, 3:48:46 AM7/1/20
to Gadgetron
Dear Oliver,

Unfortunately access to the scanner is now restricted because of the COVID, so I will be able to take the exact file only on Friday. But it should be like the attached one (it is almost unchanged example file which was provided together with Gadgetron ICE). In any case, I didn't add any new tags there. And I hope I didn't make a stupid typo there, otherwise it will be a shame :)

Sincerely,
Karyna


вторник, 30 июня 2020 г., 18:41:43 UTC+2 пользователь Oliver Josephs написал:
IceProgramGadgetron_RTPC.xml

Karyna Isaieva

unread,
Jul 1, 2020, 10:10:09 AM7/1/20
to Gadgetron
I am sorry for the "spamming"

I succeeded to take the exact file from the scanner, here it is.

Thank you!
Karyna

среда, 1 июля 2020 г., 9:48:46 UTC+2 пользователь Karyna Isaieva написал:
IceProgramGadgetron_RTPC.xml

Karyna Isaieva

unread,
Jul 3, 2020, 9:42:17 AM7/3/20
to Gadgetron
Apparently my problem is related not to the matlab gadget. Today I tried another config files and I have the same problem. The chain with matlab gadget just was the last thing which I tested on Tuesday, and everything before worked fine. So we will try to see what can be wrong with out scanner/servers...

среда, 1 июля 2020 г., 16:10:09 UTC+2 пользователь Karyna Isaieva написал:

Karyna Isaieva

unread,
Jul 8, 2020, 10:50:41 AM7/8/20
to Gadgetron
Dear Gadgetron community,

I updated Gadgetron ICE on the scanner and now the Gadgetron code itself works. But not mine :) The Matlab gadget successfully executes and I see all the graphs on the Matlab side. But then nothing returns to the scanner.

The only error which I see in the log is:
07-07 16:27:47.646 ERROR [Core.cpp:18] [Connection Main Thread//external] ERROR: std::bad_alloc
What does it mean? The full log is attached

Also I am attaching sceenshots of the image which I am sending back to the chain, and its header. The only thing which is not nice, for me, it is the size in phase encoding direction from two points of view: 1) It is not round, 2) It is greater than size in frequency encoding direction which normally does not exist. Could you please say if it really can cause the problems or the reason of this error is something else?

I am sorry for asking a lot, but our scanner is not easily accessible so I have to fix the code before going there... And Gadgetron ICE simulation doesn't work for the moment (I will ask this on Gadgetron ICE github if I will not resolve this issue)

Thanks!
Karyna

пятница, 3 июля 2020 г., 15:42:17 UTC+2 пользователь Karyna Isaieva написал:
gadgetron_matlab_07_07_2020.log
image.png
header.png

kristoffe...@gradientsoftware.net

unread,
Jul 14, 2020, 8:47:10 AM7/14/20
to Gadgetron

Hi Karyna,

You posted some code and a config file earlier in this thread; are they still up to date? I'll assume they are reasonably representative of what you are trying to do.

The bad allocation presumably happens within the image reader used by the external connection to Matlab. Presumably, something in the images written from Matlab confuses the Gadgetron reader. There's probably some unexpected extra bytes somewhere; the reader then gets 'offset'; it reads an image header wrong, and attempts to allocate nonsense (a very large array, an array with negative dimensions, etc.). The issue is presumably a problem with the C++ reader, the Matlab writer, or in the image header you are sending.

I see output from AutoScaleGadget (Max: <number>) in the log. This message is printed very late in the autoscale process, and presumably autoscale manages to operate successfully on the first image. I'll assume this successful image is the image featured in the screenshots (those all look pretty reasonable, at a cursory glance).

If you are still sending multiple images, I'd like to suggest a closer look at the second image; the phase image. If you can post a .mat file (or something) with the images, I'd be happy to see if I can't track down the issue.

Best regards,
Kristoffer

Karyna Isaieva

unread,
Jul 15, 2020, 4:56:39 AM7/15/20
to Gadgetron

Dear Kristoffer,

Thanks a lot for yor answer! I tried see which gadgets are executed normally using the debug mode, and I found that all of the gadgets including FloatToUShort work fine (it seems), at least the expected lines are executed and the arrays content seem fine. Then the message goes to the image writer which is more complicated to understand, but at least one time per image writer->accepts returns true. So it looks that everything is fine, but somewhere it doesn't work. I am attaching also the mat-files for each of the images.

Then I tried to just increase the size of the images like this: mag = [mag(:, 1), mag]; just after the reconstruction, before all the manipulations with the headers and so on. So, now the size is not 256x2559, but 256x2560. And suddenly it works! I succeeded to configure ICE simulation, so before it generated no output files, now it generates 3 dicom files as expected. This Friday I am going to test if it works on the scanner.

So it seems that it is possible that my question is resolved (I will let you know if it works on the scanner). But it is still not clear for me why it didn't work...

Sincerely,
Karyna

вторник, 14 июля 2020 г., 14:47:10 UTC+2 пользователь kristoffe...@gradientsoftware.net написал:
magnitude.mat
phase.mat
graph.mat

Karyna Isaieva

unread,
Jul 17, 2020, 4:34:29 PM7/17/20
to Gadgetron
The test on the scanner was successful. So I would close the question and the response is that for some reason it didn't like the size of the image (maybe the odd sizes are not allowed?). Moreover, I had to change the size even more strictly, because actually the size of the output image should correspond to the slice size defined in the sequence, otherwise the the scanner is not happy (however the dicoms are still generated). Thanks a lot everybody who helped me!

среда, 15 июля 2020 г., 10:56:39 UTC+2 пользователь Karyna Isaieva написал:
Reply all
Reply to author
Forward
0 new messages