Source code for spike.File.Spinit

#!/usr/bin/env python 
# encoding: utf-8

"""
    Utility to Handle NMR Spinit files

"""

from __future__ import print_function

__author__ = "Marc Andre' Delsuc"
__date__ = "August 2017"

import os
import os.path as op
import glob
import re
import struct
import time
import unittest
import shutil
import xml.etree.ElementTree as ET

import numpy as np

from ..NPKData import NPKData

debug = False
verbose = True   # change this for verbose importers

################################################################
[docs]def load_header(filename="header.xml"): """ loads a header.xml as an ET.tree, and keep it in memory returns headertree xml parameters are found in headertree.getroot() """ tree = ET.parse(filename) return tree
[docs]def read_param(filename="header.xml"): """ loads a header.xml as a dictionnary key:value """ debug = 0 headertree = load_header(filename) xroot = headertree.getroot() xparams = xroot[0] params = {} for entry in xparams: k = entry.find('key').text params[k] = "" for xv in entry.iter('value'): try: params[k] += xv.text.strip() except AttributeError: pass # debug code if debug: for i in dict.keys(): print(i+" = "+str(dict[i])) return params
[docs]def modify_val(headertree, key, value): """ modify an entry from a headertree loaded with load_header() key should be present in headertree key and val are both strings headertree can then written back to disk with headertree.write('header.xml') """ debug = 1 for entry in headertree.getroot()[0]: k = entry.find('key').text if k == key: # match vals = entry.find('value') bef = vals.find('value').text vals.find('value').text = value if debug: print (key, 'Before:', bef, 'After:', vals.find('value').text)
################################################################
[docs]def read_1D(size, filename="data.dat"): """ Reads in a Spinit 1D fid as a numpy float array size is the number of data-points in the fid uses struct does not check endianess """ print("size is ", size) fmt = ">%df" si = size rl = np.empty((si/2)) im = np.empty((si/2)) print("****** bits number is {0} ".format(8*si)) dt = np.dtype(">f") ibuf = np.fromfile(filename, dt) # with open(filename,"rb") as F: # buf = F.read(8*si) # ibuf = struct.unpack(fmt%(2*si), buf) # unpack the string as pairs of float print("passing in complex") print("rl.size ",rl.size) print("im.size ",im.size) print("ibuf.size ",ibuf.size) rl[:] = ibuf[::2] im[:] = ibuf[1::2] npkbuf = rl + 1j*im print("complex is OK") return npkbuf
################################################################
[docs]def read_2D(sizeF1, sizeF2, filename="data.dat"): return npkbuf
################################################################
[docs]def zerotime(acqu): """get digital filter parameters, if any """ try: zerotimeposition = float( acqu['DIGITAL_FILTER_SHIFT'] ) except: zerotimeposition = 0.0 return(zerotimeposition)
################################################################
[docs]def offset(acqu, proc): """ computes the offset from spinit to spike """ try: ppmPointUn = float(proc['$OFFSET']) ppmWidth = float(acqu['$SW_h']) / float(acqu['$SFO1']) calibrationOffset = float(ppmPointUn - ppmWidth)* float(acqu['$SFO1']) except: calibrationOffset=0.0 return (calibrationOffset)
################################################################
[docs]def Import_1D(filename="data.dat"): """ Imports a 1D spinit fid as a NPKData """ if (not op.exists(filename)): raise Exception(filename+" : file not found") dire=op.dirname(filename) acqu = read_param(op.join(dire,'header.xml')) size= int(acqu['ACQUISITION_MATRIX_DIMENSION_1D']) # get size if verbose: print("importing 1D FID, size =",size) data = read_1D(size, filename) print("After read_1D, size is : ", data.size) d = NPKData(buffer=data) # d.revf() # then set parameters d.axis1.specwidth = float(acqu['SPECTRAL_WIDTH']) # in Hz d.axis1.frequency = float(acqu['OBSERVED_FREQUENCY'])/1E6 # in MHz d.axis1.itype = 1 # always complex d.axis1.offset = float(acqu['SR']) - d.axis1.specwidth/2 d.axis1.zerotime = zerotime(acqu) pardic = {"header": acqu} # create ad-hoc parameters d.params = pardic # add the parameters to the data-set return d
################################################################
[docs]def Export_1D(d, filename="data.dat", template="header.xml", kind=None): """ export a 1D NPKData as a spinit kind: 1DFID, 1DSPEC """ if d.dim >1: raise Exception("not implemented yet for Dim>1") if d.itype == 1: # complex array = d.get_buffer() else: # real array = d.get_buffer() + 0.0j # add a zero imaginary part dirname = op.dirname(filename) if not op.isdir(dirname): os.makedirs(dirname) # array.astype(">f").tofile(filename) array.view(np.float_).astype('>f').tofile(filename) # then set parameters headertree = load_header(template) modify_val(headertree, 'MODALITY', "NMR" ) modify_val(headertree, 'ACCU_DIM', "1" ) modify_val(headertree, 'ACQUISITION_MATRIX_DIMENSION_1D', str(d.axis1.cpxsize) ) modify_val(headertree, 'SPECTRAL_WIDTH', str(d.axis1.specwidth) ) modify_val(headertree, 'OBSERVED_FREQUENCY', str(d.axis1.frequency*1E6) ) modify_val(headertree, 'SR', str(d.axis1.offset+d.axis1.specwidth/2) ) print (' **SR is wrong ! to-be-changed**') try: STATE = [str(d.axis1.state),"0", "0", "0"] except: STATE = d.params['header']['STATE'] modify_val(headertree, 'STATE', STATE) modify_val(headertree, 'DIGITAL_FILTER_SHIFT', str(d.axis1.zerotime) ) headerfile = op.join( dirname, "header.xml") headertree.write(headerfile)
if __name__ == '__main__': unittest.main()