diff --git a/nibabel/nicom/ascconv.py b/nibabel/nicom/ascconv.py new file mode 100644 index 0000000000..811ea270f5 --- /dev/null +++ b/nibabel/nicom/ascconv.py @@ -0,0 +1,207 @@ +# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- +# vi: set ft=python sts=4 ts=4 sw=4 et: +""" +Parse the "ASCCONV" meta data format found in a variety of Siemens MR files. +""" +import re +import ast +from ..externals import OrderedDict + + +ASCCONV_RE = re.compile( + r'### ASCCONV BEGIN((?:\s*[^=\s]+=[^=\s]+)*) ###\n(.*?)\n### ASCCONV END ###', + flags=re.M | re.S) + + +class AscconvParseError(Exception): + """ Error parsing ascconv file """ + + +class Atom: + """ Object to hold operation, object type and object identifier + + An atom represents an element in an expression. For example:: + + a.b[0].c + + has four elements. We call these elements "atoms". + + We represent objects (like ``a``) as dicts for convenience. + + The last element (``.c``) is an ``op = ast.Attribute`` operation where the + object type (`obj_type`) of ``c`` is not constrained (we can't tell from + the operation what type it is). The `obj_id` is the name of the object -- + "c". + + The second to last element ``[0]``, is ``op = ast.Subscript``, with object type + dict (we know from the subsequent operation ``.c`` that this must be an + object, we represent the object by a dict). The `obj_id` is the index 0. + + Parameters + ---------- + op : {'name', 'attr', 'list'} + Assignment type. Assignment to name (root namespace), attribute or + list element. + obj_type : {list, dict, other} + Object type being assigned to. + obj_id : str or int + Key (``obj_type is dict``) or index (``obj_type is list``) + """ + + def __init__(self, op, obj_type, obj_id): + self.op = op + self.obj_type = obj_type + self.obj_id = obj_id + + +class NoValue: + """ Signals no value present """ + + +def assign2atoms(assign_ast, default_class=int): + """ Parse single assignment ast from ascconv line into atoms + + Parameters + ---------- + assign_ast : assignment statement ast + ast derived from single line of ascconv file. + default_class : class, optional + Class that will create an object where we cannot yet know the object + type in the assignment. + + Returns + ------- + atoms : list + List of :class:`atoms`. See docstring for :class:`atoms`. Defines + left to right sequence of assignment in `line_ast`. + """ + if not len(assign_ast.targets) == 1: + raise AscconvParseError('Too many targets in assign') + target = assign_ast.targets[0] + atoms = [] + prev_target_type = default_class # Placeholder for any scalar value + while True: + if isinstance(target, ast.Name): + atoms.append(Atom(target, prev_target_type, target.id)) + break + if isinstance(target, ast.Attribute): + atoms.append(Atom(target, prev_target_type, target.attr)) + target = target.value + prev_target_type = OrderedDict + elif isinstance(target, ast.Subscript): + index = target.slice.value.n + atoms.append(Atom(target, prev_target_type, index)) + target = target.value + prev_target_type = list + else: + raise AscconvParseError( + 'Unexpected LHS element {0}'.format(target)) + return reversed(atoms) + + +def _create_obj_in(atom, root): + """ Create object defined in `atom` in dict-like given by `root` + + Return defined object. + """ + name = atom.obj_id + obj = root.get(name, NoValue) + if obj is not NoValue: + return obj + obj = atom.obj_type() + root[name] = obj + return obj + + +def _create_subscript_in(atom, root): + """ Create object defined in `atom` at index ``atom.obj_id`` in list `root` + + Return defined object. + """ + curr_n = len(root) + index = atom.obj_id + if curr_n > index: + return root[index] + obj = atom.obj_type() + root += [None] * (index - curr_n) + [obj] + return obj + + +def obj_from_atoms(atoms, namespace): + """ Return object defined by list `atoms` in dict-like `namespace` + + Parameters + ---------- + atoms : list + List of :class:`atoms` + namespace : dict-like + Namespace in which object will be defined. + + Returns + ------- + obj_root : object + Namespace such that we can set a desired value to the object defined in + `atoms` with ``obj_root[obj_key] = value``. + obj_key : str or int + Index into list or key into dictionary for `obj_root`. + """ + root_obj = namespace + for el in atoms: + prev_root = root_obj + if isinstance(el.op, (ast.Attribute, ast.Name)): + root_obj = _create_obj_in(el, root_obj) + else: + root_obj = _create_subscript_in(el, root_obj) + if not isinstance(root_obj, el.obj_type): + raise AscconvParseError( + 'Unexpected type for {0} in {1}'.format(el.obj_id, prev_root)) + return prev_root, el.obj_id + + +def _get_value(assign): + value = assign.value + if isinstance(value, ast.Num): + return value.n + if isinstance(value, ast.Str): + return value.s + if isinstance(value, ast.UnaryOp) and isinstance(value.op, ast.USub): + return -value.operand.n + raise AscconvParseError('Unexpected RHS of assignment: {0}'.format(value)) + + +def parse_ascconv(ascconv_str, str_delim='"'): + '''Parse the 'ASCCONV' format from `input_str`. + + Parameters + ---------- + ascconv_str : str + The string we are parsing + str_delim : str, optional + String delimiter. Typically '"' or '""' + + Returns + ------- + prot_dict : OrderedDict + Meta data pulled from the ASCCONV section. + attrs : OrderedDict + Any attributes stored in the 'ASCCONV BEGIN' line + + Raises + ------ + AsconvParseError + A line of the ASCCONV section could not be parsed. + ''' + attrs, content = ASCCONV_RE.match(ascconv_str).groups() + attrs = OrderedDict((tuple(x.split('=')) for x in attrs.split())) + # Normalize string start / end markers to something Python understands + content = content.replace(str_delim, '"""') + # Use Python's own parser to parse modified ASCCONV assignments + tree = ast.parse(content) + + prot_dict = OrderedDict() + for assign in tree.body: + atoms = assign2atoms(assign) + obj_to_index, key = obj_from_atoms(atoms, prot_dict) + obj_to_index[key] = _get_value(assign) + + return prot_dict, attrs diff --git a/nibabel/nicom/tests/data/ascconv_sample.txt b/nibabel/nicom/tests/data/ascconv_sample.txt new file mode 100644 index 0000000000..1fd78f788f --- /dev/null +++ b/nibabel/nicom/tests/data/ascconv_sample.txt @@ -0,0 +1,919 @@ +### ASCCONV BEGIN ### +ulVersion = 0x14b44b6 +tSequenceFileName = ""%SiemensSeq%\ep2d_diff"" +tProtocolName = ""CBU+AF8-DTI+AF8-64D+AF8-1A"" +tReferenceImage0 = ""1.3.12.2.1107.5.2.32.35119.2010011420070434054586384"" +tReferenceImage1 = ""1.3.12.2.1107.5.2.32.35119.2010011420070721803086388"" +tReferenceImage2 = ""1.3.12.2.1107.5.2.32.35119.201001142007109937386392"" +ucScanRegionPosValid = 0x1 +ucTablePositioningMode = 0x1 +sProtConsistencyInfo.tBaselineString = ""N4_VB17A_LATEST_20090307"" +sProtConsistencyInfo.tSystemType = ""092"" +sProtConsistencyInfo.flNominalB0 = 2.89362 +sProtConsistencyInfo.flGMax = 26 +sProtConsistencyInfo.flRiseTime = 5.88 +sProtConsistencyInfo.lMaximumNofRxReceiverChannels = 18 +sGRADSPEC.sEddyCompensationX.aflAmplitude[0] = 0.00141208 +sGRADSPEC.sEddyCompensationX.aflAmplitude[1] = 0.000569241 +sGRADSPEC.sEddyCompensationX.aflAmplitude[2] = -0.000514958 +sGRADSPEC.sEddyCompensationX.aflAmplitude[3] = 0.000499075 +sGRADSPEC.sEddyCompensationX.aflAmplitude[4] = 0.000821246 +sGRADSPEC.sEddyCompensationX.aflTimeConstant[0] = 1.81531 +sGRADSPEC.sEddyCompensationX.aflTimeConstant[1] = 0.995025 +sGRADSPEC.sEddyCompensationX.aflTimeConstant[2] = 0.0492598 +sGRADSPEC.sEddyCompensationX.aflTimeConstant[3] = 0.0194645 +sGRADSPEC.sEddyCompensationX.aflTimeConstant[4] = 0.000499659 +sGRADSPEC.sEddyCompensationY.aflAmplitude[0] = 0.00112797 +sGRADSPEC.sEddyCompensationY.aflAmplitude[1] = -0.000565372 +sGRADSPEC.sEddyCompensationY.aflAmplitude[2] = -0.00182913 +sGRADSPEC.sEddyCompensationY.aflAmplitude[3] = -2.65859e-005 +sGRADSPEC.sEddyCompensationY.aflAmplitude[4] = 0.000601077 +sGRADSPEC.sEddyCompensationY.aflTimeConstant[0] = 1.09142 +sGRADSPEC.sEddyCompensationY.aflTimeConstant[1] = 0.661632 +sGRADSPEC.sEddyCompensationY.aflTimeConstant[2] = 0.446457 +sGRADSPEC.sEddyCompensationY.aflTimeConstant[3] = 0.0118729 +sGRADSPEC.sEddyCompensationY.aflTimeConstant[4] = 0.00134346 +sGRADSPEC.sEddyCompensationZ.aflAmplitude[0] = 0.00221038 +sGRADSPEC.sEddyCompensationZ.aflAmplitude[1] = 0.00592667 +sGRADSPEC.sEddyCompensationZ.aflAmplitude[2] = 0.000254437 +sGRADSPEC.sEddyCompensationZ.aflAmplitude[3] = -8.35135e-005 +sGRADSPEC.sEddyCompensationZ.aflAmplitude[4] = -4.25678e-005 +sGRADSPEC.sEddyCompensationZ.aflTimeConstant[0] = 4.32108 +sGRADSPEC.sEddyCompensationZ.aflTimeConstant[1] = 0.923398 +sGRADSPEC.sEddyCompensationZ.aflTimeConstant[2] = 0.0379209 +sGRADSPEC.sEddyCompensationZ.aflTimeConstant[3] = 0.0104227 +sGRADSPEC.sEddyCompensationZ.aflTimeConstant[4] = 0.00199944 +sGRADSPEC.bEddyCompensationValid = 1 +sGRADSPEC.sB0CompensationX.aflAmplitude[0] = -0.0494045 +sGRADSPEC.sB0CompensationX.aflAmplitude[1] = 0.0730311 +sGRADSPEC.sB0CompensationX.aflAmplitude[2] = -0.00670347 +sGRADSPEC.sB0CompensationX.aflTimeConstant[0] = 0.618983 +sGRADSPEC.sB0CompensationX.aflTimeConstant[1] = 0.341914 +sGRADSPEC.sB0CompensationX.aflTimeConstant[2] = 0.002 +sGRADSPEC.sB0CompensationY.aflAmplitude[0] = 0.136281 +sGRADSPEC.sB0CompensationY.aflAmplitude[1] = 0.0376382 +sGRADSPEC.sB0CompensationY.aflAmplitude[2] = -0.0500779 +sGRADSPEC.sB0CompensationY.aflTimeConstant[0] = 0.71999 +sGRADSPEC.sB0CompensationY.aflTimeConstant[1] = 0.00341892 +sGRADSPEC.sB0CompensationY.aflTimeConstant[2] = 0.002 +sGRADSPEC.sB0CompensationZ.aflAmplitude[0] = 0.0776537 +sGRADSPEC.sB0CompensationZ.aflAmplitude[1] = 0.0168151 +sGRADSPEC.sB0CompensationZ.aflAmplitude[2] = -0.0550622 +sGRADSPEC.sB0CompensationZ.aflTimeConstant[0] = 0.669998 +sGRADSPEC.sB0CompensationZ.aflTimeConstant[1] = 0.0213343 +sGRADSPEC.sB0CompensationZ.aflTimeConstant[2] = 0.00186002 +sGRADSPEC.bB0CompensationValid = 1 +sGRADSPEC.sCrossTermCompensationXY.aflAmplitude[0] = -0.00049613 +sGRADSPEC.sCrossTermCompensationXY.aflTimeConstant[0] = 0.562233 +sGRADSPEC.sCrossTermCompensationXZ.aflAmplitude[0] = -0.000499641 +sGRADSPEC.sCrossTermCompensationXZ.aflTimeConstant[0] = 0.693605 +sGRADSPEC.sCrossTermCompensationYX.aflAmplitude[0] = 5.35458e-005 +sGRADSPEC.sCrossTermCompensationYX.aflTimeConstant[0] = 0.598216 +sGRADSPEC.sCrossTermCompensationYZ.aflAmplitude[0] = 0.0004678 +sGRADSPEC.sCrossTermCompensationYZ.aflTimeConstant[0] = 0.705977 +sGRADSPEC.sCrossTermCompensationZX.aflAmplitude[0] = -0.000529382 +sGRADSPEC.sCrossTermCompensationZX.aflTimeConstant[0] = 0.551175 +sGRADSPEC.sCrossTermCompensationZY.aflAmplitude[0] = 8.74925e-005 +sGRADSPEC.sCrossTermCompensationZY.aflTimeConstant[0] = 0.890761 +sGRADSPEC.bCrossTermCompensationValid = 1 +sGRADSPEC.lOffsetX = -7806 +sGRADSPEC.lOffsetY = -8833 +sGRADSPEC.lOffsetZ = -2097 +sGRADSPEC.bOffsetValid = 1 +sGRADSPEC.lDelayX = 14 +sGRADSPEC.lDelayY = 14 +sGRADSPEC.lDelayZ = 10 +sGRADSPEC.bDelayValid = 1 +sGRADSPEC.flSensitivityX = 7.95149e-005 +sGRADSPEC.flSensitivityY = 7.82833e-005 +sGRADSPEC.flSensitivityZ = 9.09015e-005 +sGRADSPEC.bSensitivityValid = 1 +sGRADSPEC.flGSWDMinRiseTime = 9.88 +sGRADSPEC.alShimCurrent[0] = 867 +sGRADSPEC.alShimCurrent[1] = 80 +sGRADSPEC.alShimCurrent[2] = -61 +sGRADSPEC.alShimCurrent[3] = -4 +sGRADSPEC.alShimCurrent[4] = -16 +sGRADSPEC.bShimCurrentValid = 1 +sGRADSPEC.ucMode = 0x11 +sTXSPEC.asNucleusInfo[0].tNucleus = ""1H"" +sTXSPEC.asNucleusInfo[0].lFrequency = 123251815 +sTXSPEC.asNucleusInfo[0].bFrequencyValid = 1 +sTXSPEC.asNucleusInfo[0].flReferenceAmplitude = 384.855 +sTXSPEC.asNucleusInfo[0].bReferenceAmplitudeValid = 1 +sTXSPEC.asNucleusInfo[0].flAmplitudeCorrection = 1 +sTXSPEC.asNucleusInfo[0].bAmplitudeCorrectionValid = 1 +sTXSPEC.asNucleusInfo[0].bRFPAIndexValid = 1 +sTXSPEC.asNucleusInfo[1].bFrequencyValid = 1 +sTXSPEC.asNucleusInfo[1].bReferenceAmplitudeValid = 1 +sTXSPEC.asNucleusInfo[1].flAmplitudeCorrection = 1 +sTXSPEC.asNucleusInfo[1].bAmplitudeCorrectionValid = 1 +sTXSPEC.asNucleusInfo[1].lRFPAIndex = -1 +sTXSPEC.asNucleusInfo[1].bRFPAIndexValid = 1 +sTXSPEC.aRFPULSE[0].tName = ""ExtExciteRF"" +sTXSPEC.aRFPULSE[0].bAmplitudeValid = 0x1 +sTXSPEC.aRFPULSE[0].flAmplitude = 357.891 +sTXSPEC.aRFPULSE[1].tName = ""CSatCSatNS"" +sTXSPEC.aRFPULSE[1].bAmplitudeValid = 0x1 +sTXSPEC.aRFPULSE[1].flAmplitude = 94.871 +sTXSPEC.aRFPULSE[2].tName = ""SLoopFCSatNS"" +sTXSPEC.aRFPULSE[2].bAmplitudeValid = 0x1 +sTXSPEC.aRFPULSE[2].flAmplitude = 94.871 +sTXSPEC.lNoOfTraPulses = 3 +sTXSPEC.lBCExcitationMode = 1 +sTXSPEC.lBCSeqExcitationMode = 4 +sTXSPEC.flKDynMagnitudeMin = 0.5 +sTXSPEC.flKDynMagnitudeMax = 1.5 +sTXSPEC.flKDynMagnitudeClipLow = 1 +sTXSPEC.flKDynMagnitudeClipHigh = 1 +sTXSPEC.flKDynPhaseMax = 0.698132 +sTXSPEC.flKDynPhaseClip = 0.174533 +sTXSPEC.bKDynValid = 1 +sTXSPEC.ucRFPulseType = 0x2 +sTXSPEC.ucExcitMode = 0x1 +sTXSPEC.ucSimultaneousExcitation = 0x1 +sTXSPEC.ucBCExcitationModeValid = 0x1 +sRXSPEC.lGain = 1 +sRXSPEC.bGainValid = 1 +sRXSPEC.alDwellTime[0] = 2800 +sAdjData.uiAdjFreMode = 0x1 +sAdjData.uiAdjShimMode = 0x2 +sAdjData.uiAdjWatSupMode = 0x1 +sAdjData.uiAdjRFMapMode = 0x1 +sAdjData.uiAdjMDSMode = 0x1 +sAdjData.uiAdjTableTolerance = 0x1 +sAdjData.uiAdjProtID = 0x56 +sAdjData.uiAdjFreProtRelated = 0x1 +sAdjData.sAdjVolume.sPosition.dCor = -19.66101724 +sAdjData.sAdjVolume.sPosition.dTra = -8.81356001 +sAdjData.sAdjVolume.sNormal.dCor = 0.005235963828 +sAdjData.sAdjVolume.sNormal.dTra = 0.9999862922 +sAdjData.sAdjVolume.dThickness = 144 +sAdjData.sAdjVolume.dPhaseFOV = 230 +sAdjData.sAdjVolume.dReadoutFOV = 230 +ucEnableNoiseAdjust = 0x1 +alTR[0] = 6600000 +alTI[0] = 2500000 +lContrasts = 1 +alTE[0] = 93000 +acFlowComp[0] = 1 +lCombinedEchoes = 1 +sSliceArray.asSlice[0].sPosition.dCor = -20.03015269 +sSliceArray.asSlice[0].sPosition.dTra = -79.31259361 +sSliceArray.asSlice[0].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[0].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[0].dThickness = 2.5 +sSliceArray.asSlice[0].dPhaseFOV = 230 +sSliceArray.asSlice[0].dReadoutFOV = 230 +sSliceArray.asSlice[1].sPosition.dCor = -20.0144448 +sSliceArray.asSlice[1].sPosition.dTra = -76.31263473 +sSliceArray.asSlice[1].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[1].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[1].dThickness = 2.5 +sSliceArray.asSlice[1].dPhaseFOV = 230 +sSliceArray.asSlice[1].dReadoutFOV = 230 +sSliceArray.asSlice[2].sPosition.dCor = -19.99873691 +sSliceArray.asSlice[2].sPosition.dTra = -73.31267586 +sSliceArray.asSlice[2].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[2].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[2].dThickness = 2.5 +sSliceArray.asSlice[2].dPhaseFOV = 230 +sSliceArray.asSlice[2].dReadoutFOV = 230 +sSliceArray.asSlice[3].sPosition.dCor = -19.98302902 +sSliceArray.asSlice[3].sPosition.dTra = -70.31271698 +sSliceArray.asSlice[3].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[3].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[3].dThickness = 2.5 +sSliceArray.asSlice[3].dPhaseFOV = 230 +sSliceArray.asSlice[3].dReadoutFOV = 230 +sSliceArray.asSlice[4].sPosition.dCor = -19.96732113 +sSliceArray.asSlice[4].sPosition.dTra = -67.3127581 +sSliceArray.asSlice[4].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[4].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[4].dThickness = 2.5 +sSliceArray.asSlice[4].dPhaseFOV = 230 +sSliceArray.asSlice[4].dReadoutFOV = 230 +sSliceArray.asSlice[5].sPosition.dCor = -19.95161324 +sSliceArray.asSlice[5].sPosition.dTra = -64.31279923 +sSliceArray.asSlice[5].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[5].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[5].dThickness = 2.5 +sSliceArray.asSlice[5].dPhaseFOV = 230 +sSliceArray.asSlice[5].dReadoutFOV = 230 +sSliceArray.asSlice[6].sPosition.dCor = -19.93590535 +sSliceArray.asSlice[6].sPosition.dTra = -61.31284035 +sSliceArray.asSlice[6].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[6].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[6].dThickness = 2.5 +sSliceArray.asSlice[6].dPhaseFOV = 230 +sSliceArray.asSlice[6].dReadoutFOV = 230 +sSliceArray.asSlice[7].sPosition.dCor = -19.92019745 +sSliceArray.asSlice[7].sPosition.dTra = -58.31288147 +sSliceArray.asSlice[7].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[7].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[7].dThickness = 2.5 +sSliceArray.asSlice[7].dPhaseFOV = 230 +sSliceArray.asSlice[7].dReadoutFOV = 230 +sSliceArray.asSlice[8].sPosition.dCor = -19.90448956 +sSliceArray.asSlice[8].sPosition.dTra = -55.3129226 +sSliceArray.asSlice[8].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[8].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[8].dThickness = 2.5 +sSliceArray.asSlice[8].dPhaseFOV = 230 +sSliceArray.asSlice[8].dReadoutFOV = 230 +sSliceArray.asSlice[9].sPosition.dCor = -19.88878167 +sSliceArray.asSlice[9].sPosition.dTra = -52.31296372 +sSliceArray.asSlice[9].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[9].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[9].dThickness = 2.5 +sSliceArray.asSlice[9].dPhaseFOV = 230 +sSliceArray.asSlice[9].dReadoutFOV = 230 +sSliceArray.asSlice[10].sPosition.dCor = -19.87307378 +sSliceArray.asSlice[10].sPosition.dTra = -49.31300484 +sSliceArray.asSlice[10].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[10].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[10].dThickness = 2.5 +sSliceArray.asSlice[10].dPhaseFOV = 230 +sSliceArray.asSlice[10].dReadoutFOV = 230 +sSliceArray.asSlice[11].sPosition.dCor = -19.85736589 +sSliceArray.asSlice[11].sPosition.dTra = -46.31304597 +sSliceArray.asSlice[11].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[11].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[11].dThickness = 2.5 +sSliceArray.asSlice[11].dPhaseFOV = 230 +sSliceArray.asSlice[11].dReadoutFOV = 230 +sSliceArray.asSlice[12].sPosition.dCor = -19.841658 +sSliceArray.asSlice[12].sPosition.dTra = -43.31308709 +sSliceArray.asSlice[12].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[12].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[12].dThickness = 2.5 +sSliceArray.asSlice[12].dPhaseFOV = 230 +sSliceArray.asSlice[12].dReadoutFOV = 230 +sSliceArray.asSlice[13].sPosition.dCor = -19.8259501 +sSliceArray.asSlice[13].sPosition.dTra = -40.31312821 +sSliceArray.asSlice[13].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[13].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[13].dThickness = 2.5 +sSliceArray.asSlice[13].dPhaseFOV = 230 +sSliceArray.asSlice[13].dReadoutFOV = 230 +sSliceArray.asSlice[14].sPosition.dCor = -19.81024221 +sSliceArray.asSlice[14].sPosition.dTra = -37.31316934 +sSliceArray.asSlice[14].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[14].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[14].dThickness = 2.5 +sSliceArray.asSlice[14].dPhaseFOV = 230 +sSliceArray.asSlice[14].dReadoutFOV = 230 +sSliceArray.asSlice[15].sPosition.dCor = -19.79453432 +sSliceArray.asSlice[15].sPosition.dTra = -34.31321046 +sSliceArray.asSlice[15].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[15].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[15].dThickness = 2.5 +sSliceArray.asSlice[15].dPhaseFOV = 230 +sSliceArray.asSlice[15].dReadoutFOV = 230 +sSliceArray.asSlice[16].sPosition.dCor = -19.77882643 +sSliceArray.asSlice[16].sPosition.dTra = -31.31325158 +sSliceArray.asSlice[16].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[16].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[16].dThickness = 2.5 +sSliceArray.asSlice[16].dPhaseFOV = 230 +sSliceArray.asSlice[16].dReadoutFOV = 230 +sSliceArray.asSlice[17].sPosition.dCor = -19.76311854 +sSliceArray.asSlice[17].sPosition.dTra = -28.31329271 +sSliceArray.asSlice[17].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[17].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[17].dThickness = 2.5 +sSliceArray.asSlice[17].dPhaseFOV = 230 +sSliceArray.asSlice[17].dReadoutFOV = 230 +sSliceArray.asSlice[18].sPosition.dCor = -19.74741065 +sSliceArray.asSlice[18].sPosition.dTra = -25.31333383 +sSliceArray.asSlice[18].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[18].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[18].dThickness = 2.5 +sSliceArray.asSlice[18].dPhaseFOV = 230 +sSliceArray.asSlice[18].dReadoutFOV = 230 +sSliceArray.asSlice[19].sPosition.dCor = -19.73170276 +sSliceArray.asSlice[19].sPosition.dTra = -22.31337495 +sSliceArray.asSlice[19].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[19].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[19].dThickness = 2.5 +sSliceArray.asSlice[19].dPhaseFOV = 230 +sSliceArray.asSlice[19].dReadoutFOV = 230 +sSliceArray.asSlice[20].sPosition.dCor = -19.71599486 +sSliceArray.asSlice[20].sPosition.dTra = -19.31341608 +sSliceArray.asSlice[20].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[20].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[20].dThickness = 2.5 +sSliceArray.asSlice[20].dPhaseFOV = 230 +sSliceArray.asSlice[20].dReadoutFOV = 230 +sSliceArray.asSlice[21].sPosition.dCor = -19.70028697 +sSliceArray.asSlice[21].sPosition.dTra = -16.3134572 +sSliceArray.asSlice[21].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[21].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[21].dThickness = 2.5 +sSliceArray.asSlice[21].dPhaseFOV = 230 +sSliceArray.asSlice[21].dReadoutFOV = 230 +sSliceArray.asSlice[22].sPosition.dCor = -19.68457908 +sSliceArray.asSlice[22].sPosition.dTra = -13.31349832 +sSliceArray.asSlice[22].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[22].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[22].dThickness = 2.5 +sSliceArray.asSlice[22].dPhaseFOV = 230 +sSliceArray.asSlice[22].dReadoutFOV = 230 +sSliceArray.asSlice[23].sPosition.dCor = -19.66887119 +sSliceArray.asSlice[23].sPosition.dTra = -10.31353945 +sSliceArray.asSlice[23].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[23].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[23].dThickness = 2.5 +sSliceArray.asSlice[23].dPhaseFOV = 230 +sSliceArray.asSlice[23].dReadoutFOV = 230 +sSliceArray.asSlice[24].sPosition.dCor = -19.6531633 +sSliceArray.asSlice[24].sPosition.dTra = -7.313580571 +sSliceArray.asSlice[24].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[24].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[24].dThickness = 2.5 +sSliceArray.asSlice[24].dPhaseFOV = 230 +sSliceArray.asSlice[24].dReadoutFOV = 230 +sSliceArray.asSlice[25].sPosition.dCor = -19.63745541 +sSliceArray.asSlice[25].sPosition.dTra = -4.313621695 +sSliceArray.asSlice[25].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[25].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[25].dThickness = 2.5 +sSliceArray.asSlice[25].dPhaseFOV = 230 +sSliceArray.asSlice[25].dReadoutFOV = 230 +sSliceArray.asSlice[26].sPosition.dCor = -19.62174752 +sSliceArray.asSlice[26].sPosition.dTra = -1.313662818 +sSliceArray.asSlice[26].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[26].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[26].dThickness = 2.5 +sSliceArray.asSlice[26].dPhaseFOV = 230 +sSliceArray.asSlice[26].dReadoutFOV = 230 +sSliceArray.asSlice[27].sPosition.dCor = -19.60603962 +sSliceArray.asSlice[27].sPosition.dTra = 1.686296059 +sSliceArray.asSlice[27].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[27].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[27].dThickness = 2.5 +sSliceArray.asSlice[27].dPhaseFOV = 230 +sSliceArray.asSlice[27].dReadoutFOV = 230 +sSliceArray.asSlice[28].sPosition.dCor = -19.59033173 +sSliceArray.asSlice[28].sPosition.dTra = 4.686254935 +sSliceArray.asSlice[28].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[28].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[28].dThickness = 2.5 +sSliceArray.asSlice[28].dPhaseFOV = 230 +sSliceArray.asSlice[28].dReadoutFOV = 230 +sSliceArray.asSlice[29].sPosition.dCor = -19.57462384 +sSliceArray.asSlice[29].sPosition.dTra = 7.686213812 +sSliceArray.asSlice[29].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[29].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[29].dThickness = 2.5 +sSliceArray.asSlice[29].dPhaseFOV = 230 +sSliceArray.asSlice[29].dReadoutFOV = 230 +sSliceArray.asSlice[30].sPosition.dCor = -19.55891595 +sSliceArray.asSlice[30].sPosition.dTra = 10.68617269 +sSliceArray.asSlice[30].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[30].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[30].dThickness = 2.5 +sSliceArray.asSlice[30].dPhaseFOV = 230 +sSliceArray.asSlice[30].dReadoutFOV = 230 +sSliceArray.asSlice[31].sPosition.dCor = -19.54320806 +sSliceArray.asSlice[31].sPosition.dTra = 13.68613156 +sSliceArray.asSlice[31].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[31].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[31].dThickness = 2.5 +sSliceArray.asSlice[31].dPhaseFOV = 230 +sSliceArray.asSlice[31].dReadoutFOV = 230 +sSliceArray.asSlice[32].sPosition.dCor = -19.52750017 +sSliceArray.asSlice[32].sPosition.dTra = 16.68609044 +sSliceArray.asSlice[32].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[32].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[32].dThickness = 2.5 +sSliceArray.asSlice[32].dPhaseFOV = 230 +sSliceArray.asSlice[32].dReadoutFOV = 230 +sSliceArray.asSlice[33].sPosition.dCor = -19.51179228 +sSliceArray.asSlice[33].sPosition.dTra = 19.68604932 +sSliceArray.asSlice[33].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[33].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[33].dThickness = 2.5 +sSliceArray.asSlice[33].dPhaseFOV = 230 +sSliceArray.asSlice[33].dReadoutFOV = 230 +sSliceArray.asSlice[34].sPosition.dCor = -19.49608438 +sSliceArray.asSlice[34].sPosition.dTra = 22.68600819 +sSliceArray.asSlice[34].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[34].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[34].dThickness = 2.5 +sSliceArray.asSlice[34].dPhaseFOV = 230 +sSliceArray.asSlice[34].dReadoutFOV = 230 +sSliceArray.asSlice[35].sPosition.dCor = -19.48037649 +sSliceArray.asSlice[35].sPosition.dTra = 25.68596707 +sSliceArray.asSlice[35].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[35].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[35].dThickness = 2.5 +sSliceArray.asSlice[35].dPhaseFOV = 230 +sSliceArray.asSlice[35].dReadoutFOV = 230 +sSliceArray.asSlice[36].sPosition.dCor = -19.4646686 +sSliceArray.asSlice[36].sPosition.dTra = 28.68592595 +sSliceArray.asSlice[36].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[36].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[36].dThickness = 2.5 +sSliceArray.asSlice[36].dPhaseFOV = 230 +sSliceArray.asSlice[36].dReadoutFOV = 230 +sSliceArray.asSlice[37].sPosition.dCor = -19.44896071 +sSliceArray.asSlice[37].sPosition.dTra = 31.68588482 +sSliceArray.asSlice[37].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[37].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[37].dThickness = 2.5 +sSliceArray.asSlice[37].dPhaseFOV = 230 +sSliceArray.asSlice[37].dReadoutFOV = 230 +sSliceArray.asSlice[38].sPosition.dCor = -19.43325282 +sSliceArray.asSlice[38].sPosition.dTra = 34.6858437 +sSliceArray.asSlice[38].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[38].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[38].dThickness = 2.5 +sSliceArray.asSlice[38].dPhaseFOV = 230 +sSliceArray.asSlice[38].dReadoutFOV = 230 +sSliceArray.asSlice[39].sPosition.dCor = -19.41754493 +sSliceArray.asSlice[39].sPosition.dTra = 37.68580258 +sSliceArray.asSlice[39].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[39].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[39].dThickness = 2.5 +sSliceArray.asSlice[39].dPhaseFOV = 230 +sSliceArray.asSlice[39].dReadoutFOV = 230 +sSliceArray.asSlice[40].sPosition.dCor = -19.40183703 +sSliceArray.asSlice[40].sPosition.dTra = 40.68576145 +sSliceArray.asSlice[40].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[40].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[40].dThickness = 2.5 +sSliceArray.asSlice[40].dPhaseFOV = 230 +sSliceArray.asSlice[40].dReadoutFOV = 230 +sSliceArray.asSlice[41].sPosition.dCor = -19.38612914 +sSliceArray.asSlice[41].sPosition.dTra = 43.68572033 +sSliceArray.asSlice[41].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[41].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[41].dThickness = 2.5 +sSliceArray.asSlice[41].dPhaseFOV = 230 +sSliceArray.asSlice[41].dReadoutFOV = 230 +sSliceArray.asSlice[42].sPosition.dCor = -19.37042125 +sSliceArray.asSlice[42].sPosition.dTra = 46.68567921 +sSliceArray.asSlice[42].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[42].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[42].dThickness = 2.5 +sSliceArray.asSlice[42].dPhaseFOV = 230 +sSliceArray.asSlice[42].dReadoutFOV = 230 +sSliceArray.asSlice[43].sPosition.dCor = -19.35471336 +sSliceArray.asSlice[43].sPosition.dTra = 49.68563808 +sSliceArray.asSlice[43].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[43].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[43].dThickness = 2.5 +sSliceArray.asSlice[43].dPhaseFOV = 230 +sSliceArray.asSlice[43].dReadoutFOV = 230 +sSliceArray.asSlice[44].sPosition.dCor = -19.33900547 +sSliceArray.asSlice[44].sPosition.dTra = 52.68559696 +sSliceArray.asSlice[44].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[44].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[44].dThickness = 2.5 +sSliceArray.asSlice[44].dPhaseFOV = 230 +sSliceArray.asSlice[44].dReadoutFOV = 230 +sSliceArray.asSlice[45].sPosition.dCor = -19.32329758 +sSliceArray.asSlice[45].sPosition.dTra = 55.68555584 +sSliceArray.asSlice[45].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[45].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[45].dThickness = 2.5 +sSliceArray.asSlice[45].dPhaseFOV = 230 +sSliceArray.asSlice[45].dReadoutFOV = 230 +sSliceArray.asSlice[46].sPosition.dCor = -19.30758969 +sSliceArray.asSlice[46].sPosition.dTra = 58.68551471 +sSliceArray.asSlice[46].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[46].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[46].dThickness = 2.5 +sSliceArray.asSlice[46].dPhaseFOV = 230 +sSliceArray.asSlice[46].dReadoutFOV = 230 +sSliceArray.asSlice[47].sPosition.dCor = -19.29188179 +sSliceArray.asSlice[47].sPosition.dTra = 61.68547359 +sSliceArray.asSlice[47].sNormal.dCor = 0.005235963828 +sSliceArray.asSlice[47].sNormal.dTra = 0.9999862922 +sSliceArray.asSlice[47].dThickness = 2.5 +sSliceArray.asSlice[47].dPhaseFOV = 230 +sSliceArray.asSlice[47].dReadoutFOV = 230 +sSliceArray.anAsc[1] = 1 +sSliceArray.anAsc[2] = 2 +sSliceArray.anAsc[3] = 3 +sSliceArray.anAsc[4] = 4 +sSliceArray.anAsc[5] = 5 +sSliceArray.anAsc[6] = 6 +sSliceArray.anAsc[7] = 7 +sSliceArray.anAsc[8] = 8 +sSliceArray.anAsc[9] = 9 +sSliceArray.anAsc[10] = 10 +sSliceArray.anAsc[11] = 11 +sSliceArray.anAsc[12] = 12 +sSliceArray.anAsc[13] = 13 +sSliceArray.anAsc[14] = 14 +sSliceArray.anAsc[15] = 15 +sSliceArray.anAsc[16] = 16 +sSliceArray.anAsc[17] = 17 +sSliceArray.anAsc[18] = 18 +sSliceArray.anAsc[19] = 19 +sSliceArray.anAsc[20] = 20 +sSliceArray.anAsc[21] = 21 +sSliceArray.anAsc[22] = 22 +sSliceArray.anAsc[23] = 23 +sSliceArray.anAsc[24] = 24 +sSliceArray.anAsc[25] = 25 +sSliceArray.anAsc[26] = 26 +sSliceArray.anAsc[27] = 27 +sSliceArray.anAsc[28] = 28 +sSliceArray.anAsc[29] = 29 +sSliceArray.anAsc[30] = 30 +sSliceArray.anAsc[31] = 31 +sSliceArray.anAsc[32] = 32 +sSliceArray.anAsc[33] = 33 +sSliceArray.anAsc[34] = 34 +sSliceArray.anAsc[35] = 35 +sSliceArray.anAsc[36] = 36 +sSliceArray.anAsc[37] = 37 +sSliceArray.anAsc[38] = 38 +sSliceArray.anAsc[39] = 39 +sSliceArray.anAsc[40] = 40 +sSliceArray.anAsc[41] = 41 +sSliceArray.anAsc[42] = 42 +sSliceArray.anAsc[43] = 43 +sSliceArray.anAsc[44] = 44 +sSliceArray.anAsc[45] = 45 +sSliceArray.anAsc[46] = 46 +sSliceArray.anAsc[47] = 47 +sSliceArray.anPos[1] = 1 +sSliceArray.anPos[2] = 2 +sSliceArray.anPos[3] = 3 +sSliceArray.anPos[4] = 4 +sSliceArray.anPos[5] = 5 +sSliceArray.anPos[6] = 6 +sSliceArray.anPos[7] = 7 +sSliceArray.anPos[8] = 8 +sSliceArray.anPos[9] = 9 +sSliceArray.anPos[10] = 10 +sSliceArray.anPos[11] = 11 +sSliceArray.anPos[12] = 12 +sSliceArray.anPos[13] = 13 +sSliceArray.anPos[14] = 14 +sSliceArray.anPos[15] = 15 +sSliceArray.anPos[16] = 16 +sSliceArray.anPos[17] = 17 +sSliceArray.anPos[18] = 18 +sSliceArray.anPos[19] = 19 +sSliceArray.anPos[20] = 20 +sSliceArray.anPos[21] = 21 +sSliceArray.anPos[22] = 22 +sSliceArray.anPos[23] = 23 +sSliceArray.anPos[24] = 24 +sSliceArray.anPos[25] = 25 +sSliceArray.anPos[26] = 26 +sSliceArray.anPos[27] = 27 +sSliceArray.anPos[28] = 28 +sSliceArray.anPos[29] = 29 +sSliceArray.anPos[30] = 30 +sSliceArray.anPos[31] = 31 +sSliceArray.anPos[32] = 32 +sSliceArray.anPos[33] = 33 +sSliceArray.anPos[34] = 34 +sSliceArray.anPos[35] = 35 +sSliceArray.anPos[36] = 36 +sSliceArray.anPos[37] = 37 +sSliceArray.anPos[38] = 38 +sSliceArray.anPos[39] = 39 +sSliceArray.anPos[40] = 40 +sSliceArray.anPos[41] = 41 +sSliceArray.anPos[42] = 42 +sSliceArray.anPos[43] = 43 +sSliceArray.anPos[44] = 44 +sSliceArray.anPos[45] = 45 +sSliceArray.anPos[46] = 46 +sSliceArray.anPos[47] = 47 +sSliceArray.lSize = 48 +sSliceArray.lConc = 1 +sSliceArray.ucMode = 0x2 +sSliceArray.sTSat.dThickness = 50 +sGroupArray.asGroup[0].nSize = 48 +sGroupArray.asGroup[0].dDistFact = 0.2 +sGroupArray.anMember[1] = 1 +sGroupArray.anMember[2] = 2 +sGroupArray.anMember[3] = 3 +sGroupArray.anMember[4] = 4 +sGroupArray.anMember[5] = 5 +sGroupArray.anMember[6] = 6 +sGroupArray.anMember[7] = 7 +sGroupArray.anMember[8] = 8 +sGroupArray.anMember[9] = 9 +sGroupArray.anMember[10] = 10 +sGroupArray.anMember[11] = 11 +sGroupArray.anMember[12] = 12 +sGroupArray.anMember[13] = 13 +sGroupArray.anMember[14] = 14 +sGroupArray.anMember[15] = 15 +sGroupArray.anMember[16] = 16 +sGroupArray.anMember[17] = 17 +sGroupArray.anMember[18] = 18 +sGroupArray.anMember[19] = 19 +sGroupArray.anMember[20] = 20 +sGroupArray.anMember[21] = 21 +sGroupArray.anMember[22] = 22 +sGroupArray.anMember[23] = 23 +sGroupArray.anMember[24] = 24 +sGroupArray.anMember[25] = 25 +sGroupArray.anMember[26] = 26 +sGroupArray.anMember[27] = 27 +sGroupArray.anMember[28] = 28 +sGroupArray.anMember[29] = 29 +sGroupArray.anMember[30] = 30 +sGroupArray.anMember[31] = 31 +sGroupArray.anMember[32] = 32 +sGroupArray.anMember[33] = 33 +sGroupArray.anMember[34] = 34 +sGroupArray.anMember[35] = 35 +sGroupArray.anMember[36] = 36 +sGroupArray.anMember[37] = 37 +sGroupArray.anMember[38] = 38 +sGroupArray.anMember[39] = 39 +sGroupArray.anMember[40] = 40 +sGroupArray.anMember[41] = 41 +sGroupArray.anMember[42] = 42 +sGroupArray.anMember[43] = 43 +sGroupArray.anMember[44] = 44 +sGroupArray.anMember[45] = 45 +sGroupArray.anMember[46] = 46 +sGroupArray.anMember[47] = 47 +sGroupArray.anMember[48] = -1 +sGroupArray.lSize = 1 +sGroupArray.sPSat.dThickness = 50 +sGroupArray.sPSat.dGap = 10 +sAutoAlign.dAAMatrix[0] = 1 +sAutoAlign.dAAMatrix[5] = 1 +sAutoAlign.dAAMatrix[10] = 1 +sAutoAlign.dAAMatrix[15] = 1 +sNavigatorPara.lBreathHoldMeas = 1 +sNavigatorPara.lRespComp = 4 +sNavigatorPara.alFree[22] = 2 +sNavigatorPara.adFree[13] = 150000 +sBladePara.dBladeCoverage = 100 +sBladePara.ucMotionCorr = 0x2 +sPrepPulses.ucFatSat = 0x1 +sPrepPulses.ucWaterSat = 0x4 +sPrepPulses.ucInversion = 0x4 +sPrepPulses.ucSatRecovery = 0x1 +sPrepPulses.ucT2Prep = 0x1 +sPrepPulses.ucTIScout = 0x1 +sPrepPulses.ucFatSatMode = 0x2 +sPrepPulses.dDarkBloodThickness = 200 +sPrepPulses.dDarkBloodFlipAngle = 200 +sPrepPulses.dT2PrepDuration = 40 +sPrepPulses.dIRPulseThicknessFactor = 0.77 +sKSpace.dPhaseResolution = 1 +sKSpace.dSliceResolution = 1 +sKSpace.dAngioDynCentralRegionA = 20 +sKSpace.dAngioDynSamplingDensityB = 25 +sKSpace.lBaseResolution = 128 +sKSpace.lPhaseEncodingLines = 128 +sKSpace.lPartitions = 64 +sKSpace.lImagesPerSlab = 64 +sKSpace.lRadialViews = 64 +sKSpace.lRadialInterleavesPerImage = 2 +sKSpace.lLinesPerShot = 1 +sKSpace.unReordering = 0x1 +sKSpace.dSeqPhasePartialFourierForSNR = 1 +sKSpace.ucPhasePartialFourier = 0x4 +sKSpace.ucSlicePartialFourier = 0x10 +sKSpace.ucAveragingMode = 0x2 +sKSpace.ucMultiSliceMode = 0x2 +sKSpace.ucDimension = 0x2 +sKSpace.ucTrajectory = 0x1 +sKSpace.ucViewSharing = 0x1 +sKSpace.ucAsymmetricEchoMode = 0x1 +sKSpace.ucPOCS = 0x1 +sFastImaging.lEPIFactor = 128 +sFastImaging.lTurboFactor = 1 +sFastImaging.lSliceTurboFactor = 1 +sFastImaging.lSegments = 1 +sFastImaging.ulEnableRFSpoiling = 0x1 +sFastImaging.ucSegmentationMode = 0x1 +sFastImaging.lShots = 1 +sFastImaging.lEchoTrainDuration = 700 +sPhysioImaging.lSignal1 = 1 +sPhysioImaging.lMethod1 = 1 +sPhysioImaging.lSignal2 = 1 +sPhysioImaging.lMethod2 = 1 +sPhysioImaging.lPhases = 1 +sPhysioImaging.lRetroGatedImages = 16 +sPhysioImaging.sPhysioECG.lTriggerPulses = 1 +sPhysioImaging.sPhysioECG.lTriggerWindow = 5 +sPhysioImaging.sPhysioECG.lArrhythmiaDetection = 1 +sPhysioImaging.sPhysioECG.lCardiacGateOnThreshold = 100000 +sPhysioImaging.sPhysioECG.lCardiacGateOffThreshold = 700000 +sPhysioImaging.sPhysioECG.lTriggerIntervals = 1 +sPhysioImaging.sPhysioPulse.lTriggerPulses = 1 +sPhysioImaging.sPhysioPulse.lTriggerWindow = 5 +sPhysioImaging.sPhysioPulse.lArrhythmiaDetection = 1 +sPhysioImaging.sPhysioPulse.lCardiacGateOnThreshold = 100000 +sPhysioImaging.sPhysioPulse.lCardiacGateOffThreshold = 700000 +sPhysioImaging.sPhysioPulse.lTriggerIntervals = 1 +sPhysioImaging.sPhysioExt.lTriggerPulses = 1 +sPhysioImaging.sPhysioExt.lTriggerWindow = 5 +sPhysioImaging.sPhysioExt.lArrhythmiaDetection = 1 +sPhysioImaging.sPhysioExt.lCardiacGateOnThreshold = 100000 +sPhysioImaging.sPhysioExt.lCardiacGateOffThreshold = 700000 +sPhysioImaging.sPhysioExt.lTriggerIntervals = 1 +sPhysioImaging.sPhysioResp.lRespGateThreshold = 20 +sPhysioImaging.sPhysioResp.lRespGatePhase = 2 +sPhysioImaging.sPhysioResp.dGatingRatio = 0.3 +sPhysioImaging.sPhysioNative.ucMode = 0x1 +sPhysioImaging.sPhysioNative.ucFlowSenMode = 0x1 +sSpecPara.lPhaseCyclingType = 1 +sSpecPara.lPhaseEncodingType = 1 +sSpecPara.lRFExcitationBandwidth = 1 +sSpecPara.ucRemoveOversampling = 0x1 +sSpecPara.lAutoRefScanNo = 1 +sSpecPara.lDecouplingType = 1 +sSpecPara.lNOEType = 1 +sSpecPara.lExcitationType = 1 +sSpecPara.lSpecAppl = 1 +sSpecPara.lSpectralSuppression = 1 +sDiffusion.lDiffWeightings = 2 +sDiffusion.alBValue[1] = 1000 +sDiffusion.lNoiseLevel = 40 +sDiffusion.lDiffDirections = 64 +sDiffusion.ulMode = 0x100 +sAngio.ucPCFlowMode = 0x2 +sAngio.ucTOFInflow = 0x4 +sAngio.lDynamicReconMode = 1 +sAngio.lTemporalInterpolation = 1 +sRawFilter.lSlope_256 = 25 +sRawFilter.ucOn = 0x1 +sRawFilter.ucMode = 0x1 +sDistortionCorrFilter.ucMode = 0x1 +sPat.lAccelFactPE = 2 +sPat.lAccelFact3D = 1 +sPat.lRefLinesPE = 38 +sPat.ucPATMode = 0x2 +sPat.ucRefScanMode = 0x4 +sPat.ucTPatAverageAllFrames = 0x1 +sMDS.ulMdsModeMask = 0x1 +sMDS.ulMdsVariableResolution = 0x1 +sMDS.lTableSpeedNumerator = 1 +sMDS.lmdsLinesPerSegment = 15 +sMDS.sMdsEndPosSBCS_mm.dTra = 600 +sMDS.ulMdsReconMode = 0x1 +sMDS.dMdsRangeExtension = 600 +ucEnableIntro = 0x1 +ucDisableChangeStoreImages = 0x1 +ucAAMode = 0x1 +ucAARegionMode = 1 +ucAARefMode = 1 +ucReconstructionMode = 0x1 +ucOneSeriesForAllMeas = 0x1 +ucPHAPSMode = 0x1 +ucDixon = 0x1 +ucDixonSaveOriginal = 0x1 +ucWaitForPrepareCompletion = 0x1 +lAverages = 1 +dAveragesDouble = 1 +adFlipAngleDegree[0] = 90 +lScanTimeSec = 449 +lTotalScanTimeSec = 450 +dRefSNR = 33479.60771 +dRefSNR_VOI = 33479.60771 +tdefaultEVAProt = ""%SiemensEvaDefProt%\DTI\DTI.evp"" +asCoilSelectMeas[0].tNucleus = ""1H"" +asCoilSelectMeas[0].iUsedRFactor = 3 +asCoilSelectMeas[0].asList[0].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[0].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[0].sCoilElementID.tElement = ""H3P"" +asCoilSelectMeas[0].asList[0].lElementSelected = 1 +asCoilSelectMeas[0].asList[0].lRxChannelConnected = 1 +asCoilSelectMeas[0].asList[1].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[1].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[1].sCoilElementID.tElement = ""H4P"" +asCoilSelectMeas[0].asList[1].lElementSelected = 1 +asCoilSelectMeas[0].asList[1].lRxChannelConnected = 2 +asCoilSelectMeas[0].asList[2].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[2].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[2].sCoilElementID.tElement = ""H4S"" +asCoilSelectMeas[0].asList[2].lElementSelected = 1 +asCoilSelectMeas[0].asList[2].lRxChannelConnected = 3 +asCoilSelectMeas[0].asList[3].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[3].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[3].sCoilElementID.tElement = ""H4T"" +asCoilSelectMeas[0].asList[3].lElementSelected = 1 +asCoilSelectMeas[0].asList[3].lRxChannelConnected = 4 +asCoilSelectMeas[0].asList[4].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[4].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[4].sCoilElementID.tElement = ""H3S"" +asCoilSelectMeas[0].asList[4].lElementSelected = 1 +asCoilSelectMeas[0].asList[4].lRxChannelConnected = 5 +asCoilSelectMeas[0].asList[5].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[5].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[5].sCoilElementID.tElement = ""H3T"" +asCoilSelectMeas[0].asList[5].lElementSelected = 1 +asCoilSelectMeas[0].asList[5].lRxChannelConnected = 6 +asCoilSelectMeas[0].asList[6].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[6].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[6].sCoilElementID.tElement = ""H1P"" +asCoilSelectMeas[0].asList[6].lElementSelected = 1 +asCoilSelectMeas[0].asList[6].lRxChannelConnected = 7 +asCoilSelectMeas[0].asList[7].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[7].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[7].sCoilElementID.tElement = ""H2P"" +asCoilSelectMeas[0].asList[7].lElementSelected = 1 +asCoilSelectMeas[0].asList[7].lRxChannelConnected = 8 +asCoilSelectMeas[0].asList[8].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[8].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[8].sCoilElementID.tElement = ""H2S"" +asCoilSelectMeas[0].asList[8].lElementSelected = 1 +asCoilSelectMeas[0].asList[8].lRxChannelConnected = 9 +asCoilSelectMeas[0].asList[9].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[9].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[9].sCoilElementID.tElement = ""H2T"" +asCoilSelectMeas[0].asList[9].lElementSelected = 1 +asCoilSelectMeas[0].asList[9].lRxChannelConnected = 10 +asCoilSelectMeas[0].asList[10].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[10].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[10].sCoilElementID.tElement = ""H1S"" +asCoilSelectMeas[0].asList[10].lElementSelected = 1 +asCoilSelectMeas[0].asList[10].lRxChannelConnected = 11 +asCoilSelectMeas[0].asList[11].sCoilElementID.tCoilID = ""HeadMatrix"" +asCoilSelectMeas[0].asList[11].sCoilElementID.lCoilCopy = 1 +asCoilSelectMeas[0].asList[11].sCoilElementID.tElement = ""H1T"" +asCoilSelectMeas[0].asList[11].lElementSelected = 1 +asCoilSelectMeas[0].asList[11].lRxChannelConnected = 12 +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[0] = 0xff +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[1] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[2] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[3] = 0xad +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[4] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[5] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[6] = 0x5d +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[7] = 0xb1 +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[8] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[9] = 0xb2 +asCoilSelectMeas[0].sCOILPLUGS.aulPlugId[10] = 0xee +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[0] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[1] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[2] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[3] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[4] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[5] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[6] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[7] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[8] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[9] = 0x2 +asCoilSelectMeas[0].sCOILPLUGS.auiNmbrOfNibbles[10] = 0x2 +asCoilSelectMeas[0].aFFT_SCALE[0].flFactor = 3.77259 +asCoilSelectMeas[0].aFFT_SCALE[0].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[0].lRxChannel = 1 +asCoilSelectMeas[0].aFFT_SCALE[1].flFactor = 3.83164 +asCoilSelectMeas[0].aFFT_SCALE[1].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[1].lRxChannel = 2 +asCoilSelectMeas[0].aFFT_SCALE[2].flFactor = 3.7338 +asCoilSelectMeas[0].aFFT_SCALE[2].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[2].lRxChannel = 3 +asCoilSelectMeas[0].aFFT_SCALE[3].flFactor = 4.08449 +asCoilSelectMeas[0].aFFT_SCALE[3].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[3].lRxChannel = 4 +asCoilSelectMeas[0].aFFT_SCALE[4].flFactor = 3.82172 +asCoilSelectMeas[0].aFFT_SCALE[4].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[4].lRxChannel = 5 +asCoilSelectMeas[0].aFFT_SCALE[5].flFactor = 3.86816 +asCoilSelectMeas[0].aFFT_SCALE[5].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[5].lRxChannel = 6 +asCoilSelectMeas[0].aFFT_SCALE[6].flFactor = 4.48252 +asCoilSelectMeas[0].aFFT_SCALE[6].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[6].lRxChannel = 7 +asCoilSelectMeas[0].aFFT_SCALE[7].flFactor = 4.39406 +asCoilSelectMeas[0].aFFT_SCALE[7].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[7].lRxChannel = 8 +asCoilSelectMeas[0].aFFT_SCALE[8].flFactor = 4.50498 +asCoilSelectMeas[0].aFFT_SCALE[8].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[8].lRxChannel = 9 +asCoilSelectMeas[0].aFFT_SCALE[9].flFactor = 4.57011 +asCoilSelectMeas[0].aFFT_SCALE[9].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[9].lRxChannel = 10 +asCoilSelectMeas[0].aFFT_SCALE[10].flFactor = 4.6211 +asCoilSelectMeas[0].aFFT_SCALE[10].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[10].lRxChannel = 11 +asCoilSelectMeas[0].aFFT_SCALE[11].flFactor = 4.69845 +asCoilSelectMeas[0].aFFT_SCALE[11].bValid = 1 +asCoilSelectMeas[0].aFFT_SCALE[11].lRxChannel = 12 +sEFISPEC.bEFIDataValid = 1 +ucCineMode = 0x1 +ucSequenceType = 0x4 +ucCoilCombineMode = 0x2 +ucFlipAngleMode = 0x1 +lTOM = 1 +lProtID = -434 +ucReadOutMode = 0x1 +ucBold3dPace = 0x1 +ucForcePositioningOnNDIS = 0x1 +ucInternalTablePosValid = 0x1 +sParametricMapping.ucParametricMap = 0x1 +sIR.lScanNumber = 1 +sAsl.ulMode = 0x1 +WaitForUserStart = 0x1 +ucAutoAlignInit = 0x1 +### ASCCONV END ### \ No newline at end of file diff --git a/nibabel/nicom/tests/test_ascconv.py b/nibabel/nicom/tests/test_ascconv.py new file mode 100644 index 0000000000..974b917415 --- /dev/null +++ b/nibabel/nicom/tests/test_ascconv.py @@ -0,0 +1,63 @@ +""" Testing Siemens "ASCCONV" parser +""" + +from os.path import join as pjoin, dirname + +import numpy as np + +from .. import ascconv +from ...externals import OrderedDict + +from numpy.testing import assert_array_equal, assert_array_almost_equal + +DATA_PATH = pjoin(dirname(__file__), 'data') +ASCCONV_INPUT = pjoin(DATA_PATH, 'ascconv_sample.txt') + + +def test_ascconv_parse(): + with open(ASCCONV_INPUT, 'rt') as fobj: + contents = fobj.read() + ascconv_dict, attrs = ascconv.parse_ascconv(contents, str_delim='""') + assert attrs == OrderedDict() + assert len(ascconv_dict) == 72 + assert ascconv_dict['tProtocolName'] == 'CBU+AF8-DTI+AF8-64D+AF8-1A' + assert ascconv_dict['ucScanRegionPosValid'] == 1 + assert_array_almost_equal(ascconv_dict['sProtConsistencyInfo']['flNominalB0'], + 2.89362) + assert ascconv_dict['sProtConsistencyInfo']['flGMax'] == 26 + assert (list(ascconv_dict['sSliceArray'].keys()) == + ['asSlice', 'anAsc', 'anPos', 'lSize', 'lConc', 'ucMode', + 'sTSat']) + slice_arr = ascconv_dict['sSliceArray'] + as_slice = slice_arr['asSlice'] + assert_array_equal([e['dPhaseFOV'] for e in as_slice], 230) + assert_array_equal([e['dReadoutFOV'] for e in as_slice], 230) + assert_array_equal([e['dThickness'] for e in as_slice], 2.5) + # Some lists defined starting at 1, so have None as first element + assert slice_arr['anAsc'] == [None] + list(range(1, 48)) + assert slice_arr['anPos'] == [None] + list(range(1, 48)) + # A top level list + assert len(ascconv_dict['asCoilSelectMeas']) == 1 + as_list = ascconv_dict['asCoilSelectMeas'][0]['asList'] + # This lower-level list does start indexing at 0 + assert len(as_list) == 12 + for i, el in enumerate(as_list): + assert (list(el.keys()) == + ['sCoilElementID', 'lElementSelected', 'lRxChannelConnected']) + assert el['lElementSelected'] == 1 + assert el['lRxChannelConnected'] == i + 1 + # Test negative number + assert_array_almost_equal(as_slice[0]['sPosition']['dCor'], -20.03015269) + + +def test_ascconv_w_attrs(): + in_str = ("### ASCCONV BEGIN object=MrProtDataImpl@MrProtocolData " + "version=41340006 " + "converter=%MEASCONST%/ConverterList/Prot_Converter.txt ###\n" + "test = \"hello\"\n" + "### ASCCONV END ###") + ascconv_dict, attrs = ascconv.parse_ascconv(in_str, '""') + assert attrs['object'] == 'MrProtDataImpl@MrProtocolData' + assert attrs['version'] == '41340006' + assert attrs['converter'] == '%MEASCONST%/ConverterList/Prot_Converter.txt' + assert ascconv_dict['test'] == 'hello'