Menu

getting started with the network protocol for real-time reconstruction

2014-06-11
2014-06-17
  • Ghislain Vaillant

    Hi everyone,

    I intend to implement the real-time communication between Philips hardware and Gadgetron. Philips is now keen in supporting this effort and but resources are limited on their side.

    Right now, we have a somewhat working converter, which can read a finished scan saved in a proprietary Philips format and translate it to an ISMRMRD file. This file can then be sent to Gadgetron via the mriclient.

    Now, we want to move to real-time communication bewteen the Philips scanner and Gadgetron, which is the interesting bit. Philips is happy to help converting the real-time raw data to a format suitable for streaming and implementing the streaming part if an example / mockup were available.

    I am a bit confused regarding where to start on this, hence this post. Should I get to know a bit of ACE first, and if so how far ? Would making a mockup real-time client, for instance taking an ISMRMRD file, sending the acq data one by one and displaying an update of the reconstruction in a visualization window, be of any use ? Should I wait for you guys whilst you're making the networking components of Gadgetron independent ?

    Thoughts ?

    Any suggestion will be warmly welcome. Maybe a topic for next Friday's meeting.

     
    • Michael Hansen

      Michael Hansen - 2014-06-12

      Hi Ghislain,

      The mriclient included with the Gadgetron does the mockup that I think you
      are talking about. It basically simulates what a scanner would do when
      sending the data and receiving the images. If that is not helpful, we can
      discuss in more detail on one of the Friday meetings. But I would start by
      walking through that client.

      BTW, at the moment that client depends on a lot of Gadgetron components and
      in the long run it would be nice to make it more standalone so it is easy
      to install a client on a local computer to send and receive data and the
      recon could then be done on a "server".

      On Wed, Jun 11, 2014 at 3:22 PM, Ghislain Vaillant ghisvail@users.sf.net
      wrote:

      Hi everyone,

      I intend to implement the real-time communication between Philips hardware
      and Gadgetron. Philips is now keen in supporting this effort and but
      resources are limited on their side.

      Right now, we have a somewhat working converter, which can read a finished
      scan saved in a proprietary Philips format and translate it to an ISMRMRD
      file. This file can then be sent to Gadgetron via the mriclient.

      Now, we want to move to real-time communication bewteen the Philips
      scanner and Gadgetron, which is the interesting bit. Philips is happy to
      help converting the real-time raw data to a format suitable for streaming
      and implementing the streaming part if an example / mockup were available.

      I am a bit confused regarding where to start on this, hence this post.
      Should I get to know a bit of ACE first, and if so how far ? Would making a
      mockup real-time client, for instance taking an ISMRMRD file, sending the
      acq data one by one and displaying an update of the reconstruction in a
      visualization window, be of any use ? Should I wait for you guys whilst
      you're making the networking components of Gadgetron independent ?

      Thoughts ?

      Any suggestion will be warmly welcome. Maybe a topic for next Friday's
      meeting.


      getting started with the network protocol for real-time reconstruction
      https://sourceforge.net/p/gadgetron/discussion/general/thread/adcc4e0a/?limit=25#8720


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/gadgetron/discussion/general/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Ghislain Vaillant

    So far, my understanding is that the connection is handled in 3 steps, which I named initialisation, transfer and termination.

    On initialisation, a GagdetronConnector instance is created, a connection request is made with the right port and hostname config, and the general parameters are sent:

    GagdetronConnector connector;
    connector.register_writer(...);
    connector.register_reader(...);
    connector.open(hostname, port);
    connector.send_gadgetron_configuration_file(xml_config_file);
    connector.send_gadgetron_parameters(xml_header);
    

    On data transfer, an Acquisition instance is filled, then wrapped to a GadgetContainerMessage instance with the right ID:

    ISMRMRD::Acquisition acq;
    acq.setFlags(0)  // reset acquisition flags
    acq.setData(data)  // concatenated coil data as vector of float
    acq.setTraj(traj)  // optional trajectory as vector of float
    acq.getIdx().kspace_encode_step_1 = kes1;  // current PE index 
    acq.getIdx().kspace_encode_step_2 = kes2;  // current SE index, for M2D or 3D
    // plus many other set stuff for NumberOfSamples, ActiveChannels...
    GadgetContainerMessage<ISMRMRD::Acquisition> gcm_acq = 
        new GadgetContainerMessage<ISMRMRD::Acquisition>();
    *(gcm_acq->getObjectPtr()) = acq;
    GadgetContainerMessage<GadgetMessageIdentifier>* message =
        new GadgetContainerMessage<GadgetMessageIdentifier>();
    message->getObjectPtr()->id = GADGET_MESSAGE_ISMRMRD_ACQUISITION;
    message->cont(gcm_acq);
    error = connector.putq(message);
    

    On termination, an empty GadgetContainerMessage instance is sent with an id corresponding for a request to close the connection:

    GadgetContainerMessage<GadgetMessageIdentifier>* message =
        new GadgetContainerMessage<GadgetMessageIdentifier>();
    message->getObjectPtr()->id = GADGET_MESSAGE_CLOSE;
    error = connector.putq(message);
    

    Please feel free to comment on or rectify this set of steps if some things are inaccurate.

    How can the client read back the images reconstructed by Gadgetron ? Do I need to manage a separate event loop for it ?

     
    • Souheil Inati

      Souheil Inati - 2014-06-17

      The client reader is what handles images sent back from the gadgetron. You registered it at the top with:

      connector.register_reader(...);

      On Jun 17, 2014, at 10:42 AM, Ghislain Vaillant ghisvail@users.sf.netamp#103;amp#104;amp#105;amp#115;amp#118;amp#97;amp#105;amp#108;amp#64;amp#117;amp#115;amp#101;amp#114;amp#115;amp#46;amp#115;amp#102;amp#46;amp#110;amp#101;amp#116; wrote:

      So far, my understanding is that the connection is handled in 3 steps, which I named initialisation, transfer and termination.

      On initialisation, a GagdetronConnector instance is created, a connection request is made with the right port and hostname config, and the general parameters are sent:

      GagdetronConnector connector;
      connector.register_writer(...);
      connector.register_reader(...);
      connector.open(hostname, port);
      connector.send_gadgetron_configuration_file(xml_config_file);
      connector.send_gadgetron_parameters(xml_header);

      On data transfer, an Acquisition instance is filled, then wrapped to a GadgetContainerMessage instance with the right ID:

      ISMRMRD::Acquisition acq;
      acq.setFlags(0) // reset acquisition flags
      acq.setData(data) // concatenated coil data as vector of float
      acq.setTraj(traj) // optional trajectory as vector of float
      acq.getIdx().kspace_encode_step_1 = kes1; // current PE index
      acq.getIdx().kspace_encode_step_2 = kes2; // current SE index, for M2D or 3D
      // plus many other set stuff for NumberOfSamples, ActiveChannels...
      GadgetContainerMessage<ismrmrd::acquisition> gcm_acq =
      new GadgetContainerMessage<ismrmrd::acquisition>();
      (gcm_acq->getObjectPtr()) = acq;
      GadgetContainerMessage<gadgetmessageidentifier></gadgetmessageidentifier>
      message =
      new GadgetContainerMessage<gadgetmessageidentifier>();
      message->getObjectPtr()->id = GADGET_MESSAGE_ISMRMRD_ACQUISITION;
      message->cont(gcm_acq);
      error = connector.putq(message);</gadgetmessageidentifier></ismrmrd::acquisition></ismrmrd::acquisition>

      On termination, an empty GadgetContainerMessage instance is sent with an id corresponding for a request to close the connection:

      GadgetContainerMessage<gadgetmessageidentifier>* message =
      new GadgetContainerMessage<gadgetmessageidentifier>();
      message->getObjectPtr()->id = GADGET_MESSAGE_CLOSE;
      error = connector.putq(message);</gadgetmessageidentifier></gadgetmessageidentifier>

      Please feel free to comment on or rectify this set of steps if some things are inaccurate.

      How can the client read back the images reconstructed by Gadgetron ? Do I need to manage a separate event loop for it ?


      getting started with the network protocol for real-time reconstructionhttps://sourceforge.net/p/gadgetron/discussion/general/thread/adcc4e0a/?limit=25#b020


      Sent from sourceforge.nethttp://sourceforge.net because you indicated interest in https://sourceforge.net/p/gadgetron/discussion/general/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
    • Michael Hansen

      Michael Hansen - 2014-06-17

      It's hard to answer your questions in general.

      I would not describe it like you do exactly. I wrote this in the manual:

      http://sourceforge.net/p/gadgetron/home/Gadgetron%20Streaming%20Architecture/

      Does that help?

      There has to be something reading the images as they return. You can choose to manage your own threading for that or use the GadgetronConnector class and build your application around that. You just need something that reads and writes on the socket, you are free to implement that from scratch or use the helper classes that are provided.

      Hope this helps,
      Michael


      Sent from a mobile device - please excuse brevity and/or typos.

      On Jun 17, 2014, at 10:42 AM, "Ghislain Vaillant" ghisvail@users.sf.net wrote:

      So far, my understanding is that the connection is handled in 3 steps, which I named initialisation, transfer and termination.

      On initialisation, a GagdetronConnector instance is created, a connection request is made with the right port and hostname config, and the general parameters are sent:

      GagdetronConnector connector;
      connector.register_writer(...);
      connector.register_reader(...);
      connector.open(hostname, port);
      connector.send_gadgetron_configuration_file(xml_config_file);
      connector.send_gadgetron_parameters(xml_header);
      On data transfer, an Acquisition instance is filled, then wrapped to a GadgetContainerMessage instance with the right ID:

      ISMRMRD::Acquisition acq;
      acq.setFlags(0) // reset acquisition flags
      acq.setData(data) // concatenated coil data as vector of float
      acq.setTraj(traj) // optional trajectory as vector of float
      acq.getIdx().kspace_encode_step_1 = kes1; // current PE index
      acq.getIdx().kspace_encode_step_2 = kes2; // current SE index, for M2D or 3D
      // plus many other set stuff for NumberOfSamples, ActiveChannels...
      GadgetContainerMessage<ismrmrd::acquisition> gcm_acq =
      new GadgetContainerMessage<ismrmrd::acquisition>();
      (gcm_acq->getObjectPtr()) = acq;
      GadgetContainerMessage<gadgetmessageidentifier></gadgetmessageidentifier>
      message =
      new GadgetContainerMessage<gadgetmessageidentifier>();
      message->getObjectPtr()->id = GADGET_MESSAGE_ISMRMRD_ACQUISITION;
      message->cont(gcm_acq);
      error = connector.putq(message);
      On termination, an empty GadgetContainerMessage instance is sent with an id corresponding for a request to close the connection:</gadgetmessageidentifier></ismrmrd::acquisition></ismrmrd::acquisition>

      GadgetContainerMessage<gadgetmessageidentifier>* message =
      new GadgetContainerMessage<gadgetmessageidentifier>();
      message->getObjectPtr()->id = GADGET_MESSAGE_CLOSE;
      error = connector.putq(message);
      Please feel free to comment on or rectify this set of steps if some things are inaccurate.</gadgetmessageidentifier></gadgetmessageidentifier>

      How can the client read back the images reconstructed by Gadgetron ? Do I need to manage a separate event loop for it ?

      getting started with the network protocol for real-time reconstruction

      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/gadgetron/discussion/general/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
MongoDB Logo MongoDB