sarpy.BRUKERIO package¶
Submodules¶
sarpy.BRUKERIO.AData_classes module¶
Class definitions for the analysed data structures
- class sarpy.BRUKERIO.AData_classes.AData(**kwargs)[source]¶
Bases:
object
- export2nii(filename)[source]¶
Export AData content to a named Nifti1 file using the visu_pars-defined geometry of the associated parent processed data (PData)
- Parameters
filename (string) – where to write the file, what did you think?
- Example:
>>> import sarpy >>> scn = sarpy.Scan('PhantomOrientation.iY1/2') >>> scn.store_adata(key='times2',data=scn.pdata[0].data*2, force=True) >>> scn.adata['times2'].export2nii('/tmp/PhantomOrientation-times2.nii.gz')
- classmethod fromdata(parent=None, data=None, **kwargs)[source]¶
This creates an AData object from an array (maybe somehing else later) It does not store it on disk. This would typically be done by the ADataDict on assignment to a key.
- Parameters
parent (BRUKER_classes.PDATA_file) – A parent has to be an object that provides a UID and has a visu_pars attribute. Typically a PDATA_file
data (array) – sourcedata
meta (dict(optional)) – meta information in the form of a dictionary. The following keys will be added to it: parent_uid, created_datetime, parent_filename, compressed.
- classmethod fromfile(filename, parent=None, lazy=True)[source]¶
classmethod that can be used to initiatlize the AData object by reading the content from file. To use, issue:
>>> import glob, os >>> adata_dir = glob.glob(adataroot+'/*/*')[0] # take the first dir >>> adata_dir_short = re.sub(adataroot+os.path.sep, '', adata_dir) >>> AData.fromfile(adata_dir_short) Analysed data ('...') based on PDATA (uid=...) created on ... parent: ...
Admittedly this will rarely be required and most likely be done from some other constructor.
- Parameters
filename (string) – points to the adataroot/uid/uid.*/ directory
- class sarpy.BRUKERIO.AData_classes.ADataDict(*args, **kwargs)[source]¶
Bases:
collections.abc.MutableMapping
A dictionary which perfoms some magic on value-by-key assignment
Pre-existing keys are bein checked against the new key. This is inspired by an answer on stackoverflow to the question of how to perfectly override a dict.
sarpy.BRUKERIO.BRUKER_classes module¶
Class Definitions for BRUKER data
- class sarpy.BRUKERIO.BRUKER_classes.AttrDict(**kwargs)[source]¶
Bases:
object
a class that behaves like a dict but gives you access to its attributes directly
- class sarpy.BRUKERIO.BRUKER_classes.Experiment(root=None, absolute_root=False)[source]¶
Bases:
sarpy.BRUKERIO.BRUKER_classes.StudyCollection
An Experiment is not BRUKER terminology. It is a grouping of several studies (that have scans themselves) by various criteria. Typically, the patient name contains a root pointing to a common goal of the performed scans. It is a bit like a patient with the relaxation of the requirement of having identical SUBJECT_ids.
- class sarpy.BRUKERIO.BRUKER_classes.JCAMP_file(filename)[source]¶
Bases:
sarpy.BRUKERIO.BRUKER_classes.AttrDict
Represents a JCAMP encoded parameter file.
Parameters become attributes in this class
- class sarpy.BRUKERIO.BRUKER_classes.PDATA_file(filename)[source]¶
Bases:
object
Initialize a processed data set that usually sits in */pdata/[1-9].
constructor expects a directory name (filename). It will look for the 2dseq file, the d3proc and th reco file.
- export2nii(filename, rescale=None, std_mod=None)[source]¶
Export the data originating from a 2dseq (BRUKER) reconstruction to a Nifti file format.
- Parameters
filename (string) – where to write the file
A lot of the magic happens in visu_pars_2_Nift1Header in order to figure out geometry.
- Examples:
>>> import tempfile >>> scn = Scan(os.path.join('readfidTest.ix1','3')) >>> fname = os.path.join(tempfile.gettempdir(),'readfid.nii') >>> print('writing tempfile %s' % fname) writing tempfile ...readfid.nii >>> scn.pdata[0].export2nii(fname)
- class sarpy.BRUKERIO.BRUKER_classes.Patient(patient_name)[source]¶
Bases:
sarpy.BRUKERIO.BRUKER_classes.StudyCollection
A Patient is a special Collection of studies in that the subject_id has to agree from one study to the next
- class sarpy.BRUKERIO.BRUKER_classes.Scan(root, absolute_root=False)[source]¶
Bases:
object
Object to represent a BRUKER scan consisting, typically, of FID_file and PDATA_file(s).
The __init__() method expects the filename to be a directory. It will try around a bit (filenames inside the directory) before throwing an exception. It will also give up if it can’t find any of the acqp, method, fid or one 2dseq file.
Simple Example:
>>> import os >>> exp3 = Scan('readfidTest.ix1/3') >>> dir(exp3) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'acqp', 'adata', 'dirname', 'fid', 'method', 'pdata', 'pdata_uids', 'shortdirname', 'store_adata']
>>> exp3.acqp.ACQ_protocol_name 'FLASH_bas(modified)' >>> exp3.acqp.ORIGIN 'Bruker BioSpin MRI GmbH' >>> exp3.acqp.DATE 'Thu Feb 21 19:01:26 2013 PST (UT-8h)'
Also, Scan has a pretty way of falling over when no fid file is detected:
>>> Scan('readfidTest.ix1/9') Traceback (most recent call last): ... IOError:...
Scan should be able to read spectro scans:
>>> Scan('VFAT1phant1.mo1/8').fid.shape (2048, 30)
>>> Scan('VFAT1phant1.mo1/9').fid.shape (2048, 30)
- masterlist_attr(attr, level=None)[source]¶
look up attr in the hierarchy of dictionaries of the masterlist config file. As a rule, the attribute stored at the more specific (deeper) level takes precedence.
level = ‘Experiment’, ‘Patient’, ‘Study’, ‘Scan’, None
- store_adata(pdata_idx=0, force=False, **kwargs)[source]¶
Store an AData set for one of the processed children of this scan. Typically the first one (pdata_idx=0)
- Parameters
force (boolean) – overwrite pre-existing AData sets, (default False)
compressed (boolean) – compress adata files on write to disk, (default True)
- class sarpy.BRUKERIO.BRUKER_classes.Study(root, absolute_root=False)[source]¶
Bases:
object
A study in BRUKER parlance is a collection of scans performed on on subject (typically within a day, without interruption). A study directory is expected to contain a JCAMP file ‘subject’ and have one or more subdirectories which are scans.
- class sarpy.BRUKERIO.BRUKER_classes.StudyCollection[source]¶
Bases:
object
A StudyCollection can have multiple studies (in BRUKER speak) which can in turn have multiple scans. It can be initialised by pointing it to a scan or study. This should be a superclass too (?), e.g. the Patient and the Experiment class.
- add_study(study=None, by_name=None, by_uid=None)[source]¶
search through database to find anything that matches root
- Parameters
study (Study) – add the indicated study
by_name (string) – search through database with the indicated string
by_uid (string) – search through database by UID. This is potentially very slow
- sarpy.BRUKERIO.BRUKER_classes.last_path_components(absdirname, depth=1)[source]¶
Return the last two parts of a path. Should be platform independent and fairly immune to trailing ‘/’ and other irregularities. Used to determine the shortdirname in Scan and Study.
>>> last_path_components('~/bdata/stefan/nmr/readfidTest.ix1/9') '9' >>> last_path_components('~/bdata/stefan/nmr/readfidTest.ix1/9/') '9' >>> last_path_components('~/bdata/stefan/nmr/readfidTest.ix1/9/', depth=2) 'readfidTest.ix1/9'
sarpy.BRUKERIO.JCAMP_comparison module¶
Copyright: SARlab members, UBC, Vancouver, 2013
- sarpy.BRUKERIO.JCAMP_comparison.list_param_by_type(type_=<class 'str'>, exp_names=['NecS3'], fname=None)[source]¶
create part of the soure code in this module: sort JCAMP parameter names into types (str, array and other) and create a dictionary that associate frozensets of these parameters with the corresponding compare function
sarpy.BRUKERIO.JCAMP_dict module¶
sarpy.BRUKERIO.bulk_analyze module¶
sarpy.BRUKERIO.check_fid_acqp_method module¶
Quick check for the presence of all sorts of BRUKER files in the entire dataroot. A fully stocked scan should have acqp, method, fid, 2dseq. This results in a score of 1 + 2 + 4 + 8 = 15. If one is missing, the score is less.
sarpy.BRUKERIO.check_nii_vs_visu_pars module¶
sarpy.BRUKERIO.compare_JCAMP_readers module¶
sarpy.BRUKERIO.congrid module¶
Rebinning example from he SciPy.org Cookbook
- sarpy.BRUKERIO.congrid.congrid(a, newdims, method='linear', centre=False, minusone=False)[source]¶
Arbitrary resampling of source array to new dimension sizes. Currently only supports maintaining the same number of dimensions. To use 1-D arrays, first promote them to shape (x,1).
- Parameters
a (numpy.ndarray) – input array
newdims (list) – new dimensions
method (string) – neighbour - closest value from original data nearest and linear - uses n x 1-D interpolations using scipy.interpolate.interp1d (see Numerical Recipes for validity of use of n 1-D interpolations) spline - uses ndimage.map_coordinates
centre (boolean) – True - interpolation points are at the centres of the bins False - points are at the front edge of the bin
minusone (boolean) – For example- inarray.shape = (i,j) & new dimensions = (x,y) False - inarray is resampled by factors of (i/x) * (j/y) True - inarray is resampled by(i-1)/(x-1) * (j-1)/(y-1) This prevents extrapolation one element beyond bounds of input array.
Uses the same parameters and creates the same co-ordinate lookup points as IDL’’s congrid routine, which apparently originally came from a VAX/VMS routine of the same name.
sarpy.BRUKERIO.descriptortest module¶
Created on Thu Feb 28 13:19:35 2013
@author: stefan
sarpy.BRUKERIO.dict_walk_minimal_example module¶
sarpy.BRUKERIO.lazy_property module¶
Created on Thu Mar 21 16:06:35 2013
@author: stefan
- class sarpy.BRUKERIO.lazy_property.lazy_property(fget)[source]¶
Bases:
object
Meant to be used for lazy evaluation of an object attribute. property should represent non-mutable data, as it replaces itself.
An example illustrates the use. First define a class that contains a lazy_property. That call it and observe how the calculation is only performed once.
>>> class Test(object): ... @lazy_property ... def results(self): ... calcs = 42 # do a lot of calculation here ... print('phew, this took a lot of effort - glad I do this so rarely...') ... return calcs >>> A=Test() >>> A.__dict__ {} >>> A.results phew, this took a lot of effort - glad I do this so rarely... 42 >>> A.results # on a second call the calculation is not needed ! 42 >>> A.__dict__ # see how results is no a proper attribute {'results': 42}
sarpy.BRUKERIO.lowlevel module¶
Collection of BRUKER input routines
Handy functions to read BRUKER data and header files.
The logging is set up so that if the library user does nothing, all will be silent. Details in :py:mod: SARlogger
- sarpy.BRUKERIO.lowlevel.dict2string(d)[source]¶
convert dictionary to nicely looking multi-line string
- Parameters
d (dict) – input dictionary
- Returns
list of strings
- Return type
list
This might be useful when turning the JCAMP-style dictionaries into something that goes into a text display. Example use would be:
>>> d={'TE':2.3} >>> print(dict2string(d)) TE : 2.3
- sarpy.BRUKERIO.lowlevel.fftbruker(array, encoding=None, DCoffset=False)[source]¶
wrapper to fft bruker FIDs
returns the fft of a multi-dimensional BRUKER FID. It uses the parameter ‘encoding’ to decide over which dimensions to Fourier transform. Typically, a 2D only needs FFT over 1st and 2nd dimension (encoding = [1, 1, 0, 0]) whereas 3D files get a FT over three dimensions (encoding = [1, 1, 1, 0]). The 4th dimension (repetitions) doesn’t usually get FTed.
- sarpy.BRUKERIO.lowlevel.fftfid(fptr=None, readfidresult=None, AxisFlip=True, PEshift=True, **kwargs)[source]¶
Take filename, retrieve fid and FT as best as you can
This relies on the FT-able axis to be in he 1st three positions.
- Parameters
fptr – input fid file (handed through to readfid)
AxisFlip – Flip axis to achieve display in agreement with radiological convention (default: True)
PEshift – find out shifts of slice packs and apply in the PE directions (default: True)
squeezed – squeeze FT array before returning (default: true)
kwargs – handed through to readfid (only squeezed is handled internally)
- Returns
complex-valued array from FT of fid
- Return type
ndarray
Remarks: It does not account for the possibility of several slice packs with different orientations etc. As a result, tripilot scans are not treated properly.
- sarpy.BRUKERIO.lowlevel.inner_value(somelist)[source]¶
Return somelist[0] a one-element list or the whole list otherwise
- Parameters
somelist (list) – list that might contain only one element
- Returns
element of somelist or somelist
>>> inner_value([42]) 42 >>> inner_value([42,43]) [42, 43] >>> inner_value([[42]]) 42 >>> inner_value([[42,43]]) [42, 43] >>> inner_value('spam') 'spam' >>> inner_value(['spam']) 'spam' >>> inner_value(['s']) 's' >>> inner_value(['spam','eggs','bacon']) ['spam', 'eggs', 'bacon']
Warning
This method does not work for dictionaries (KeyError)
- sarpy.BRUKERIO.lowlevel.pairwise(iterable)[source]¶
This is a solution to the problem of looking ahead in a for loop mentioned in on stackoverflow:
“s -> (s0,s1), (s1,s2), (s2, s3), …”
- sarpy.BRUKERIO.lowlevel.read2dseq(scandirname, visu_pars=None)[source]¶
Returns BRUKER’s 2dseq file as a properly dimensioned array
- Parameters
scandirname (string) – filename of the scan directory
visu_pars (dict reco, d3proc,) – parameter files (as dict) that can be provided by caller default: None which means they will be loaded by this function
- Returns
dictionary with data, and header information. The data is an array of BRUKER-reconstructed image data in the respecive proc directory.
- Return type
dict with ‘data’:numpy array ‘header’:dict{‘recpo’:…, ‘d3proc’:…}
- Raises
IOERROR if directory non-existent
This relies on numpy’s array functionality
- sarpy.BRUKERIO.lowlevel.readJCAMP(filename)[source]¶
Parse text file in JCAMP format
- Parameters
filename (string) – filename of fid file
- Returns
Dictionary of labelled data records (LDR) with LDR-names as keys and their content as values.
- Return type
dict
- Raises
IOERROR if opening file fails or passes on any other error
The JCAMP format is a self-documenting, ASCII text file format that is maintained by IUPAC (see a report here). It consists of labelled data records (LDR) that start with a ## and end when the next record begins. They can span several lines. The data label is enclosed between ‘##’ and ‘=’. If it starts with a $, we are dealing with a private LDR.
The issue of reading these is complicated due to the various types of data (integers, floats, strings, arrays and nested structures) that can be present.
~/bdata/readfidTest.ix1/subject:
##$SUBJECT_name_string=( 64 ) <Moosvi, readfidTest> ##$SUBJECT_name=(<Moosvi>, <readfidTest>) >>> import os >>> datapath = os.path.join(os.path.expanduser(dataroot),'stefan','nmr','readfidTest.ix1') >>> a=readJCAMP(os.path.join(datapath,'subject')) >>> a['SUBJECT_name'] ['<Moosvi>', '<readfidTest>'] >>> a['SUBJECT_name_string'] 'Moosvi, readfidTest'
~/bdata/readfidTest.ix1/1/acqp:
##$ACQ_user_filter=No ##$ACQ_dim_desc=( 2 ) Spatial Spatial ##$NR=1 ##$D=( 64 ) 0.00502257333333333 0 0.00066296 0.000114 0.000114 0 0.001886 0 2.5e-05 0 0.000886 0.000886 0.000368 0 0 0 0 0 0 0 1e-05 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ##$TPQQ=( 16 ) (<hermite.exc>, 17.9862515696541, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) (<>, 30, 0) ##$ACQ_grad_matrix=( 15, 3, 3 ) 1 0 -0 0 1 0 0 -0 1 1 0 -0 0 1 0 0 -0 1 1 0 -0 0 1 0 0 -0 1 -0 0 1 -0 1 -0 1 0 0 -0 0 1 -0 1 -0 1 0 0 0 0 1 1 -0 0 0 1 -0 0 0 1 1 -0 0 0 1 -0 0 0 1 1 -0 0 0 1 -0 1 0 -0 0 1 0 0 -0 1 1 0 -0 0 1 0 0 -0 1 -0 0 1 -0 1 -0 1 0 0 -0 0 1 -0 1 -0 1 0 0 -0 0 1 -0 1 -0 1 0 0 0 0 1 1 -0 0 0 1 -0 0 0 1 1 -0 0 0 1 -0 >>> import os >>> a=readJCAMP(os.path.join(datapath,'1','acqp')) >>> a['ACQ_user_filter'] 'No' >>> a['ACQ_dim_desc'] ['Spatial', 'Spatial'] >>> a['NR'] 1 >>> a['D'][0:4] [0.00502257333333333, 0, 0.00066296, 0.000114] >>> a['TPQQ'][0:4] [['<hermite.exc>', 17.9862515696541, 0], ['<>', 30, 0], ['<>', 30, 0], ['<>', 30, 0]] >>> a['TPQQ'][0] ['<hermite.exc>', 17.9862515696541, 0] >>> a['TPQQ'][0][1] 17.9862515696541 >>> a['ACQ_grad_matrix'][0] array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
- sarpy.BRUKERIO.lowlevel.readRFshape(filename)[source]¶
reads BRUKERS RF shape files spnam0 etc that are stored with experiments
returns a dictionary with ready-to-use attributes for amplitude, phase, bandwidth etc.
- sarpy.BRUKERIO.lowlevel.readfid(fptr=None, acqp=None, method=None, untouched=False, squeezed=True, resetNR=False)[source]¶
Returns BRUKER’s fid file as a properly dimensioned & rearranged array.
- Parameters
fptr (FileType,str) – filename of fid file or filehandle to open fid file
acqp (dict) – dictionary of acqp parameters (default None: parameter file will be loaded)
method (dict) – dictionary of method parameters (default None: parameter file will be loaded)
untouched (boolean) – do not rearrange/reshape data (default: False)
squeezed (boolean) – squeeze dimension of length 1 (default: True)
resetNR (boolean) – for incomplete scans, reset NR if needed (default: False)
- Returns
Flat (untouched = True) or Rearranged and assembled array of the acquire k-space
- Return type
numpy array
- Raises
IOERROR if filesize and matrix description appear to be inconsistent
BRUKER manual D.14 File Formats (Raw data files)
The reconstruction assumes that the raw data to be reconstructed will be located in a file named either fid or ser in the EXPNO directory. Any averaging of the raw data must be done before the data is written to the file, no post-acquisition averag- ing is done by the reconstruction.
- K-format
The raw data file must be written in K-format to be processed by the TOPSPIN processing software. This means that every profile must be written to the file at a posi- tion which is a multiple of 1K-bytes (1024 bytes). Datasets which are imported may need to be reformatted. Both little-endian and big-endian word formats are sup- ported, the BYTORDA parameter in the acqp parameter file is assumed to correctly specify the format of the raw data file. Finally, the raw data file is assumed to contain data only, without any headers.
- Packed format
Data to be processed with ParaVision can also be stored in packed format. For this purpose the parameter GO_block_size must be set to continuous.
- Integer formats
By default, raw data is stored in 32-bit signed integer format, real and imaginary points of the complex signal interleaved. For applications where the data range may not exceed 16-bit, e.g. when accumulation and oversampling are disabled in analog mode, data can be stored as 16-bit short integers, setting the parameter GO_raw_data_format to GO_16BIT_SGN_INT. A warning message is displayed if an overflow occurs during data acquisition.
- Floating point format
Alternatively, data can be stored in floating point format: GO_raw_data_format = GO_32BIT_FLOAT. Note, that data not acquired in the default 32-bit signed integer format cannot be processed with TOPSPIN but only by the ParaVision reconstruction.
- Order of data storage
The raw data file usually contains the data in the order of acquisition. There is only one exception: in case a pipeline filter (AU) is used to process the raw data, the order of data storage is defined by the output order of the filter.
For raw datasets acquired by ParaVision methods, ordering and size of the data are described by the ACQP parameters contained in the file acqp:
ACQ_dim - Spatial/spectroscopic dimension of the experiment.
ACQ_size[ ] - Array of length ACQ_dim with length of the given dimensions. ACQ_size[0] counts real valued data and for this it must be an even number. Real and imaginary data is stored shuffled. For experiments acquired with multiple receivers (ACQ_experiment_mode == ParallelExperiment) the scans from different receivers are appended. The number of active receivers is derived from the number of selected receivers in the parameter array GO_ReceiverSelect.
NI - Number of objects. e.g. slices, but not purely!, could be slices*echoes
ACQ_obj_order - Permutation of the order of the acquired objects.
ACQ_phase_factor - Number of subsequent scans in the raw dataset belonging to the same Object. Typically, this parameter is set to 1 which will keep the cod- ing constant within a Multiplex step. If ACQ_phase_factor > 1, this parameter will give the number of consecutively acquired phase encoding steps that belong to a single Object. Concerning phase increment: see ACQ_rare_factor.
ACQ_phase_enc_mode[ ] - Ordering scheme for scans within the k-space.
Note
parameter seems to be renamed to ACQ_phase_encoding_mode
ACQ_phase_enc_start[ ] - For positioning of first scan in phase encoding scheme.
ACQ_rare_factor - For positioning of the ACQ_phase_factor scans within the k-space. In the case of ACQ_phase_factor > 1 the phase encoding increment is determined by ACQ_size[1] / ACQ_rare_factor. ACQ_rare_factor = ACQ_phase_factor is used for RARE experiments.
NR - Number of repeated experiments within the dataset.
These salient parameters are printed using the following code: [‘%s: %s’ % (k,acqp[k]) for k in [‘ACQ_dim’,’ACQ_size’,’GO_block_size’,’NI’,’ACQ_obj_order’,’ACQ_phase_factor’,’ACQ_phase_encoding_mode’,’ACQ_phase_enc_start’,’ACQ_rare_factor’,’NR’,’NSLICES’,’ACQ_spatial_phase_1’,’ACQ_spatial_size_1’]]
Examples:
>>> import os >>> datapath = os.path.join(os.path.expanduser(dataroot),'stefan','nmr','readfidTest.ix1') >>> fid = readfid(os.path.join(datapath,'1','fid')) >>> fid['data'].shape # TriPilot multi (128, 128, 15) >>> fid = readfid(os.path.join(datapath,'2','fid')) >>> fid['data'].shape # FLASH 2D (133, 105, 5) >>> fid = readfid(os.path.join(datapath,'3','fid')) >>> fid['data'].shape # FLASH 3D (133, 105, 25) >>> fid = readfid(os.path.join(datapath,'4','fid')) >>> fid['data'].shape # MSME 2D (133, 105, 5) >>> fid = readfid(os.path.join(datapath,'5','fid')) >>> fid['data'].shape # MSME 3D (133, 105, 25) >>> fid = readfid(os.path.join(datapath,'6','fid')) >>> fid['data'].shape # MSME 2D-TURBO (256, 256, 5, 3) >>> fid = readfid(os.path.join(datapath,'7','fid')) >>> fid['data'].shape # FLASH 2D (NR=25, NI=5, NSLICES=5) (133, 105, 5, 25) >>> fid = readfid(os.path.join(datapath,'8','fid')) >>> fid['data'].shape # FLASH 2D, partial acq. NR auto reset to 5 (133, 105, 5, 5) >>> fid = readfid(os.path.join(datapath,'9','fid')) Traceback (most recent call last): ... FileNotFoundError: ... >>> # fid file 9 was missing due to incomplete scans >>> fid = readfid(os.path.join(datapath,'10','fid')) >>> fid['data'].shape # FLASH 2D (MATRIX 32 X 32) (32, 32, 5) >>> fid = readfid(os.path.join(datapath,'11','fid')) >>> fid['data'].shape # FLASH 3D (MATRIX 32 X 32) (32, 32, 5) >>> fid = readfid(os.path.join(datapath,'12','fid')) ... ... # 1-segment EPI - FIXME, this should be easy but somehow ACQ_size=(8192,1) ... # and ACQ_scan_size=ACQ_phase_factor_scans (instead of One_Scan) ... # this should be an easy 64x64x5slice single shot EPI... Traceback (most recent call last): ... IndexError: ... >>> fid = readfid(os.path.join(datapath,'13','fid')) ... ... # 16 segment EPI - FIXME Traceback (most recent call last): ... IndexError: ... >>> fid = readfid(os.path.join(datapath,'14','fid')) >>> fid['data'].shape # DTI Standard (133, 105, 5, 2) >>> fid = readfid(os.path.join(datapath,'15','fid')) ... ... # DTI SPIRAL - FIXME Traceback (most recent call last): ... TypeError: ... >>> fid = readfid(os.path.join(datapath,'16','fid')) >>> fid['data'].shape # UTE 2D (64, 402, 5) >>> fid = readfid(os.path.join(datapath,'17','fid')) # UTE 3D ... ... # FIXME: once we know how to read this data it should be added to ... # the testdata submodule Traceback (most recent call last): ... FileNotFoundError: ... >>> fid = readfid(os.path.join(datapath,'18','fid')) # ZTE 3D ... ... #FIXME: once we know how to read this data it should be added to ... # the testdata submodule Traceback (most recent call last): ... FileNotFoundError: ... >>> fid = readfid(os.path.join(datapath,'99','fid')) ... ... # interrupted FLASH DCE, mismatch in filesize causes IOError ... # this is desired (and expected) behaviour Traceback (most recent call last): ... ValueError: ... >>> fid = readfid(os.path.join(datapath,'99','fid'), resetNR=True) >>> fid['data'].shape # interrupted FLASH DCE (NR=7 from formerly 25) (133, 105, 5, 7)
- sarpy.BRUKERIO.lowlevel.readfidspectro(fptr=None, acqp=None, method=None, untouched=False)[source]¶
Returns BRUKER’s fid file as a properly dimensioned & rearranged array
- Parameters
fptr (string or FileType) – filename of fid file or filehandle to open fid file
untouched (boolean) – Do not rearrange lines into slices and echos and such in the fid in its form as found on disk
- Returns
array of kspace data
- Return type
numpy.array
- Raises
AssertError for various inconsistencies in data size or simply misunderstandings of how the data is to be interpreted.
sarpy.BRUKERIO.masterlist module¶
sarpy.BRUKERIO.obj2dict module¶
Created on Sat Mar 16 22:28:37 2013
@author: stefan
sarpy.BRUKERIO.oldtest_BRUKER_classes module¶
sarpy.BRUKERIO.oldtest_SARlogger module¶
sarpy.BRUKERIO.oldtest_lowlevel module¶
Test Routines for lowlevel
sarpy.BRUKERIO.oldtest_write2nii module¶
sarpy.BRUKERIO.parseJCAMP module¶
sarpy.BRUKERIO.test_lowlevel module¶
sarpy.BRUKERIO.visu_pars_2_Nifti1Header module¶
Created on Mon Apr 1 00:36:03 2013
@author: stefan
- sarpy.BRUKERIO.visu_pars_2_Nifti1Header.visu_pars_2_Nifti1Header(visu_pars)[source]¶
Take visu_pars header and extract all useful information for Nifti1Header. This attempts to get all the geometry information out without requiring any special flip etc in the data beyond the initial column-major-to-row- major flip when reading in the 2dseq file.
- param dict visu_pars
visu_pars structure as previded by readJCAMP
Note: this results in a headr that’s different from the one obtained by exporting BRUKER data to dicom. Not clear why that is…
`Original Header information <http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/`_ But this site is by far the best resource for info on the Nifti header: <http://brainder.org/2012/09/23/the-nifti-file-format/>
There are 3 different methods by which continuous coordinates can be attached to voxels. We are using method 2: METHOD 2 (used when qform_code > 0, which should be the “normal” case): Ref: ——————————————————————— The (x,y,z) coordinates are given by the pixdim[] scales, a rotation matrix, and a shift. This method is intended to represent “scanner-anatomical” coordinates, which are often embedded in the image header (e.g., DICOM fields (0020,0032), (0020,0037), (0028,0030), and (0018,0050)), and represent the nominal orientation and location of the data. This method can also be used to represent “aligned” coordinates, which would typically result from some post-acquisition alignment of the volume to a standard orientation (e.g., the same subject on another day, or a rigid rotation to true anatomical orientation from the tilted position of the subject in the scanner). The formula for (x,y,z) in terms of header parameters and (i,j,k) is:
[ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ] [ y ] = [ R21 R22 R23 ] [ pixdim[2] j ] + [ qoffset_y ] [ z ] [ R31 R32 R33 ] [ qfac pixdim[3] * k ] [ qoffset_z ]
In methods 2 and 3, the (x,y,z) axes refer to a subject-based coordinate system,
with +x = Right +y = Anterior +z = Superior. This is a right-handed coordinate system. However, the exact direction these axes point with respect to the subject depends on qform_code
- Examples:
>>> import tempfile >>> scn = Scan(os.path.join('readfidTest.ix1','3')) >>> fname = os.path.join(tempfile.gettempdir(),'readfid.nii') >>> print('writing tempfile %s' % fname) writing tempfile ...readfid.nii >>> scn.pdata[0].write2nii(fname)
- sarpy.BRUKERIO.visu_pars_2_Nifti1Header.visu_pars_2_matrix_size(visu_pars, reco=None)[source]¶
Returns the matrix size as calculated from visu_pars
- Parameters
visu_pars (dict) – parameter files (as dict) that can be provided by caller
- Returns
array of size
- Return type
array
This relies on numpy’s array functionality. The whole routine is quite the contortion since we are swapping the x y dimensional size (because of the row-major, column major confusion). As a result the outut here corresponds to the shape produced by read2dseq and also results in images which when shown with imshow will have x-axis along the horizontal…
sarpy.BRUKERIO.watch_sdata module¶
sarpy.BRUKERIO.write_parameter_stack module¶
- sarpy.BRUKERIO.write_parameter_stack.write_parameter_stack(pat_name, params, masterlist, slice=None, rootdir='/tmp', loglevel=10)[source]¶
For one patient, collects all images and adatas that are listed in paramdict. The format of paramdict uses scan labels and adata labels as a(n ordered) dictionary. Typically, parameter stacks are written to /tmp separately for all slices unless the keyword parameter slice is set to a slice number
# identify adata (referred to by its label) for a given scan (referred to by its scanlabel) params = [(‘roi-0h’, [‘’,’roi’]),
(‘dce-0ha_HPG’, [‘auc60’, ‘auc300’, ‘auc600’]), (‘dce-0ha_Gd’, [‘auc60’]), (‘LL-0h+2’, [‘deltaR1_HPG2’]), (‘LL-0h+3’, [‘deltaR1_Gd’])
]
expname = ‘HerS11’ masterlist = json.load(open(os.path.expanduser(os.path.join(
‘~’, ‘sdata’, expname, expname+’.json’)),’r’))
write_parameter_stack(‘HerS11Bs05’, params, masterlist, slice=4)
or, to get all slices for all patients: for patname in masterlist:
for sl in arange(6): write_parameter_stack(patname, params, masterlist, slice=sl)