API Reference

Entry Point

MRITwixTools.read_twix — Function
read_twix(filename; kwargs...) -> TwixObj or Vector{TwixObj}

Read a Siemens twix (.dat) file. Returns a TwixObj for single-raid files or a Vector{TwixObj} for multi-raid (VD+) files.

Keyword Arguments

  • verbose::Bool=true: show progress bars during reading and data retrieval
  • bReadHeader::Bool=true: whether to read the header
  • bReadMDH::Bool=true: whether to read MDH data

The following flags are forwarded to each RawData object and control how data is processed when read via getdata / unsorted:

  • removeOS::Bool=false: remove 2× readout oversampling via FFT crop
  • regrid::Bool=false: regrid non-Cartesian (ramp-sampled) readouts
  • doAverage::Bool=false: average across the Ave dimension
  • averageReps::Bool=false: average across the Rep dimension
  • averageSets::Bool=false: average across the Set dimension
  • ignoreSeg::Bool=false: collapse the Seg dimension
  • squeeze::Bool=false: drop singleton dimensions from returned arrays
  • disableReflect::Bool=false: skip readout reflection correction
  • ignoreROoffcenter::Bool=false: ignore readout off-center shifts during regridding

Data Access

MRITwixTools.getdata — Function
getdata(s::RawData; key=nothing)

Retrieve data from the RawData. Pass key=nothing for all data, or a tuple of ranges for slicing.

MRITwixTools.unsorted — Function
unsorted(s::RawData, ival=nothing)

Return unsorted data [NCol, NCha, #samples].

MRITwixTools.fullSize — Function
fullSize(s::RawData) -> Vector{Int}

Return the full 16-element dimension size vector.

MRITwixTools.dataSize — Function
dataSize(s::RawData) -> Vector{Int}

Return data size accounting for OS removal and averaging flags.

MRITwixTools.sqzSize — Function
sqzSize(s::RawData) -> Vector{Int}

Return data sizes with singleton dimensions removed.

MRITwixTools.sqzDims — Function
sqzDims(s::RawData) -> Vector{String}

Return dimension names for non-singleton dimensions.

MRITwixTools.MDH_flags — Function
MDH_flags(t::TwixObj)

Return list of populated scan type names. Only entries whose value is a RawData object are considered scan types; auxiliary entries such as "hdr" (a TwixHdr) or "syncdata" (raw MDH_SYNCDATA payloads, a Vector{Vector{UInt8}}) are excluded.

Processing Flag Setters

These are exported convenience functions that set processing flags on a MRITwixTools.RawData object. Direct field access (e.g., obj.removeOS = true) is preferred for new code.

FunctionEquivalent
set_flagRemoveOS!(obj, val)obj.removeOS = val
set_flagRampSampRegrid!(obj, val)obj.regrid = val (errors if no trajectory)
set_flagDoAverage!(obj, val)obj.doAverage = val
set_flagAverageReps!(obj, val)obj.averageReps = val
set_flagAverageSets!(obj, val)obj.averageSets = val
set_flagIgnoreSeg!(obj, val)obj.ignoreSeg = val
set_flagSkipToFirstLine!(obj, val)obj.skipToFirstLine = val
set_flagDisableReflect!(obj, val)obj.disableReflect = val

SYNCDATA Introspection

These utilities help discover the ASCII tags embedded in an MDH_SYNCDATA packet and locate the start of the binary payload that follows a tag. See the SYNCDATA Payloads guide for context.

MRITwixTools.syncdata_strings — Function
syncdata_strings(pkt::AbstractVector{UInt8}; min_length::Int = 4)
    -> Vector{@NamedTuple{offset::Int, length::Int, str::String}}

Return every run of ≥ min_length consecutive printable-ASCII bytes in pkt. Each entry is a NamedTuple with fields

  • offset — 0-based byte offset of the first character in pkt,
  • length — number of characters in the run,
  • str — the run itself as a String.

SYNCDATA packets typically contain a small number of short ASCII field names (Siemens SEQData framing, such as "SQ", "AdjCoilSensSeq", "PMUData") followed by one or more sequence-specific tags (e.g. "MyCustomTag_v1") that mark the beginning of a binary payload. A call like

syncdata_strings(pkt; min_length = 16)

typically hides the framing noise and shows only the meaningful tag(s).

False-positive runs

The byte-level is_printable_ascii predicate can produce short-but-not-meaningful runs in two situations:

  • Fragments of the ASCII XProtocol header may bleed into fixed-size SEQData framing packets. Because the string spans packet boundaries, only ~10–20 characters survive as a run inside any one packet.
  • Small-magnitude Float32 values pack their exponent bytes into 0x3E..0x3F (bytes > / ?), so vectors of small floats occasionally produce ASCII runs up to ~12 characters long.

A min_length of 16 or above hides both. If you don't know the tag length in advance, sweep min_length downwards — genuine tags appear in exactly one packet at a stable offset, while noise fluctuates.

MRITwixTools.payload_offset — Function
payload_offset(pkt::AbstractVector{UInt8}, tag::AbstractString;
               min_padding::Int = 0, max_padding::Int = 256)
    -> Union{Int, Nothing}

Locate the ASCII tag inside pkt and return the 1-based byte offset of the first non-printable byte after it (i.e. the first byte that is not ASCII 0x20..0x7E). This is a good proxy for "where the binary payload starts" when the tag is followed by some padding of NUL bytes / framing.

min_padding / max_padding bound how far to search past the tag; the search stops as soon as a non-printable byte is found. Returns nothing if tag is not present in pkt or the packet ends before a non-printable byte is encountered.

Because Siemens sometimes inserts a variable number of framing/padding bytes between an ASCII tag and the actual binary header, callers that know the exact binary layout usually still want to slide forward a few bytes past this offset until the parsed fields look plausible — see the SYNCDATA Payloads user guide for the recommended pattern.

MRITwixTools.summarize_syncdata — Function
summarize_syncdata(sync::AbstractVector{<:AbstractVector{UInt8}};
                    min_length::Int = 4,
                    max_start_frac::Float64 = 0.5,
                    show_empty::Bool = false,
                    io::IO = stdout)

Print a human-readable summary of the packets in sync (as returned by TwixObj.syncdata): the packet index, total size in bytes, and every ASCII run of length ≥ min_length together with its offset.

Many SYNCDATA streams are dominated by:

  1. Framing packets (PMU telemetry, timing frames, …) that carry no printable-ASCII content at all, and
  2. XProtocol-fragment packets — fixed-size Siemens SEQData frames whose trailing bytes contain a slice of the ASCII XProtocol header, producing short ASCII runs at offsets near the end of the packet.

Both kinds of noise are hidden by default:

  • Packets with no qualifying ASCII run are omitted (this handles case 1).
  • Packets whose runs all start past max_start_frac × length(pkt) are omitted as "late-only" runs (this handles case 2). Custom tags identifying a payload are almost always near the start of their packet, so max_start_frac = 0.5 (the default) keeps them visible while dropping trailing XProtocol fragments.

A single aggregate line at the end reports how many packets were hidden and for what reason. Set max_start_frac = 1.0 to disable the "late-only" filter, and show_empty = true to list every packet individually.

twx = read_twix("meas.dat")
MRITwixTools.summarize_syncdata(twx.syncdata; min_length = 16)

Header Navigation

MRITwixTools.NestedDict — Type
NestedDict

A recursively nested dictionary with property-style access for navigating Siemens MRI header data. Supports:

  • Dot access: hdr.MeasYaps.sKSpace.lBaseResolution
  • Path strings: hdr["MeasYaps.sKSpace.lBaseResolution"]
  • Tab completion: at every level via propertynames
  • Search: search(hdr, "sTXSPEC", "Nucleus") finds all matching paths
  • Iteration: standard keys, values, pairs, length

Implementation note

Subtrees (NestedDict children) are stored separately from leaf values in a typed dict, enabling Julia's REPL to infer the return type of getproperty for chained tab-completion.

MRITwixTools.search — Function
search(n::NestedDict, terms...; regex=true, leaves_only=true, search_values=false) -> Vector{Pair{String,Any}}

Search all paths in the tree for entries whose full dotted path matches all given terms. Returns a vector of "dotted.path" => value pairs.

Keyword Arguments

  • regex::Bool=true: treat each term as a case-insensitive regex (otherwise plain substring match)
  • leaves_only::Bool=true: only return leaf values, not intermediate subtree nodes
  • search_values::Bool=false: also match terms against the string representation of leaf values

Examples

search(hdr, "sTXSPEC", "Nucleus")         # match path components
search(hdr, "lBaseRes")                    # find all keys containing "lBaseRes"
search(hdr, "1H", search_values=true)      # find leaves whose value contains "1H"
search(hdr, "Nucleus", "1H", search_values=true)  # path contains "Nucleus" AND value contains "1H"
MRITwixTools.leaves — Function
leaves(n::NestedDict) -> Vector{Pair{String,Any}}

Return all leaf (non-NestedDict) values with their full dotted paths.

MRITwixTools.setpath! — Function
setpath!(n::NestedDict, path::Vector{String}, value)

Insert a value at a dotted path, creating intermediate NestedDict nodes as needed. E.g., setpath!(n, ["sKSpace", "lBaseResolution"], 256).

Types

MRITwixTools.TwixObj — Type
TwixObj

Result object from read_twix. Contains header and scan data objects accessible via attribute-style access (e.g., obj.image, obj.hdr).

MRITwixTools.TwixHdr — Type
TwixHdr

Header object for Siemens twix files. Wraps a NestedDict with top-level sections (e.g., "Meas", "MeasYaps", "Phoenix") each containing parsed ASCCONV and XProtocol data as nested trees.

Access patterns

hdr.MeasYaps.sKSpace.lBaseResolution  # dot-access with tab-completion
hdr["MeasYaps.sKSpace.lBaseResolution"]  # path string
search(hdr, "lBaseRes")                  # search all paths
MRITwixTools.RawData — Type
RawData

Main data object for one scan type (image, noise, refscan, etc.). Stores MDH metadata and provides lazy data loading from the twix file.

  • flags: mutable processing flags
  • meta: per-acquisition metadata (Nothing until MDH is read)
  • dims: computed dimension sizes (Nothing until compute_dims! is called)
MRITwixTools.ReadInfo — Type
ReadInfo

Binary layout parameters for reading channel data from a twix file. Determined by software version (VB vs VD).

MRITwixTools.AcquisitionMeta — Type
AcquisitionMeta

Per-acquisition metadata extracted from MDH headers. All loop counters are stored as Int32; positions as Float32. Populated by readMDH!.

MRITwixTools.DimSizes — Type
DimSizes

Computed dimension extents and skip offsets, all as concrete Int. Immutable — recomputed when flags change.