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

Siemens Special Tab #23

Open
mxlutz opened this issue Jul 18, 2023 · 13 comments
Open

Siemens Special Tab #23

mxlutz opened this issue Jul 18, 2023 · 13 comments
Labels
requirement Used in the beginning to flash out the requirements

Comments

@mxlutz
Copy link
Collaborator

mxlutz commented Jul 18, 2023

It would be nice if we could load in the attruibutes from the Siemens special tab automatically.

Would it be easiest to add a Dictionary Attribute to the KData Header?

Also to save the Special Tab in the ismrmrd files some small changes in the xls and xlm of siemens_to_ismrmrd are necessary, is that something we want to standardize?

@mxlutz mxlutz changed the title Special Tab Siemens Special Tab Jul 18, 2023
@fzimmermann89
Copy link
Member

Good point!

Can you provide an example of an xsl and an ismrmrd file? (Does not have to be public)

I believe it would be good to consider this already now when were are designing the header class

@fzimmermann89 fzimmermann89 added this to the 0.1 Data classes milestone Jul 18, 2023
@fzimmermann89 fzimmermann89 added the requirement Used in the beginning to flash out the requirements label Jul 18, 2023
@mxlutz
Copy link
Collaborator Author

mxlutz commented Jul 18, 2023

Yes sure! I did that for VB17, so probably for the new scanner we have to adapt it again (or maybe its already in the default one for XA or what file siemens_to_ismrmrd will use). I had to change the filendings to txt to attach it here

In the xsl the following lines are important:

                <xsl:for-each select="siemens/MEAS/sWipMemBlock/alFree">
                    <xsl:if test=". &gt; 0">
                      <userParameterDouble>
                            <name>alWipMemBlock</name>
                        <value>
                            <xsl:value-of select=". " />
                        </value>
                        </userParameterDouble>
                    </xsl:if>
                </xsl:for-each> 

                <xsl:for-each select="siemens/MEAS/sWipMemBlock/adFree">
                    <xsl:if test=". &gt; 0">
                        <userParameterDouble>
                            <name>adWipMemBlock</name>
                            <value>
                                <xsl:value-of select=". " />
                            </value>
                        </userParameterDouble>    
                    </xsl:if>
                </xsl:for-each> 

The filoper.py shows how to pass the custom files to siemens_to_ismrmrd

I think the xml was actually not important, I also added some lines to read out the RF Amplifer reference amplitude that is important for me but usually not read, I dont know whether we want to add that?

fileoper.py.txt
IsmrmrdParameterMap_Siemens_custom_Max.xsl.txt
IsmrmrdParameterMap_Siemens_VB17_custom_Max.xml.txt

@mxlutz
Copy link
Collaborator Author

mxlutz commented Jul 18, 2023

I just checked it and in the current version its already included (so I guess that should work with XA61?), so we wouldnt need any specific files for siemens_to_ismrmrd

https://github.com/ismrmrd/siemens_to_ismrmrd/blob/master/parameter_maps/IsmrmrdParameterMap_Siemens.xsl

@fzimmermann89
Copy link
Member

Not sure if I understood everything. The current scope of MRPro start with ismrmrd files.
So the "interesting" XML would be the final one after the conversion which is saved inside the ismrmrd h5.

We just have to take care that all user parameters are copied to from the ismrmrd header to our header.

So maybe you could point me to a converted file somewhere on echo that contains these parameters in the header?

@mxlutz
Copy link
Collaborator Author

mxlutz commented Jul 21, 2023

Ah sorry I think that was unclear from me.

As I understood the XML file is not included in the ismrmrd header, but tells the siemens_to_ismrmrd converter what attributes from the Siemens RAW file(.dat) to write where into the header of the ismrmrd (.h5) file.
So thats actually even one step before and probably not part of this repo but something we should think of how to handle that?

@fzimmermann89
Copy link
Member

There is still some confusion.
The data flow is:

Siemens XML->XSL Transformation --> ISMRMRD XML embedded in the h5-> ismrmrd python uses xsd file and xsdata to transform this into a dataclass -> our code reads the ismrmrd dataclass

The XSL is helpful as this defines the names to be used within ismrmrd and therefore later on in the python code.

But it would also be helpful to either get the XML which is emedded in the ismrmrd .h5 (under dataset/XML as a as string.
Or just an ISMRMRD h5- on echo.

How do you in the end access these values in ptbpyrecon?

Afaik we currently only read in a fixed list of attributes. So this might get lost in the ismrmrd to MRPro Kdata code.

@mxlutz
Copy link
Collaborator Author

mxlutz commented Jul 24, 2023

Ah okay sorry, I got confused with XSL and XML.

So to be sure:
XSL: Translates one sort of XML to another XML
XML: is actually embedded in the h5

I put an example file on echo under Y:\_allgemein\projects\Max\ForFelix

I played around a little, might be helpful:

import h5py
import numpy as np
import xml.etree.ElementTree as ET
import ismrmrd

file = '/echo3/allgemein/projects/Max/ForFelix/meas_MID68_ml_MRF_v026_br128_tr4_4_te2_2_bw590_60deg_CP_FID24628.h5'
#%% xml hdr
f = h5py.File(file, 'r')
xml = np.array(f['dataset']['xml'][0])
f.close()

root = ET.fromstring(xml)

print('\n\nThis is the userParameters section from xml: \n')
for child in root[-1]:
    print(child[0].text, child[1].text)


#%% ismrmrd hdr
dset = ismrmrd.Dataset(file)
acq = dset.read_acquisition(0)
dset.close()

print('\n\nThis is the Head from ismrmrd Object: \n')
print(acq.getHead())

So in the XML the Special card is under userParameters and then adWipMemBlock or alWipMemBlock (one is double, the other int).
They dont translate into the user_int and user_float in ismrmrd, which could be a place to store that or what is that reserved for?

In my PTBRecon branch I added something to read in the WipMemBlock:
https://github.com/ckolbPTB/PtbPyRecon/commit/096632c1803a98f8c6e7b15c7ac1912217dfb243

@fzimmermann89
Copy link
Member

So to summarize: All that you ask for is that
ismrmrdHeader/userParameters/* is accessible from our header, correct?

This is currently accessible via KData.header.misc['userParameters'] (i.e. a bit hidden and not considered part of our stable and tested API)

But we could also promote it to one of our "important" Parameters that we put directly under the KData.header
This sounds somewhat reasonable - if somebody makes an effort to put something there when converting the file, they most likely need it.

For now, we will wait with adding it the KHeader directly, as this is not that crucial for now.

But please voice your opinions regarding the promotion, @schuenke @ckolbPTB

@mxlutz
Copy link
Collaborator Author

mxlutz commented Aug 10, 2023

Yes, so if it is accessible from KData.header.misc['userParameters'] that should be fine. There could also be other parameters that people want to access (for me it's e.g. the RF Reference Voltage, which can be saved in the ismrmrd file with a custom XML/XSL file), so if the whole header from the ismrmrd file is accessible in KData that seems like a good solution to me.

Should we close this issue for now? We could reopen it if necessary

@fzimmermann89
Copy link
Member

Let's keep it open, till the KHeader fields are a bit more settled ;)

@ckolbPTB ckolbPTB removed this from the 0.1 Data classes milestone Aug 22, 2023
@fzimmermann89
Copy link
Member

@ckolbPTB
In #425, we make misc more private.
Maybe it would be good to discuss parsing userParameters into our header?

@fzimmermann89 fzimmermann89 reopened this Oct 26, 2024
@ckolbPTB
Copy link
Collaborator

The parameters in the special card are very specific to different uses cases and I don't think image reconstruction algorithms provided via MRpro should depend on them. Also for different sequences the same parameter means something differenet. Therefore I think _misc is the right place for them. If we parse them into our header, it would suggest that they can be used like any other header parameter.

@fzimmermann89
Copy link
Member

fzimmermann89 commented Nov 10, 2024

Maybe you missunderstood me, I was wondering if we should provide
userParameters as userParameters in the header, similar to userids, userint, and userfloat for each acquisition -- just as a value. What it means etc is up to the caller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
requirement Used in the beginning to flash out the requirements
Projects
None yet
Development

No branches or pull requests

3 participants