Source code for spike.v1.Generic

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

"""
 The library of NMR processing functions to be used with the NPK program.

This library implement the standard functions needed for NMR processing.
Most of theese functions require that the NPK mathematical kernel is loaded.

"""

from __future__ import print_function

__author__ = "Marc A. Delsuc <delsuc@igbmc.fr> and Vincent Catherinot <v.catherinot@nmrtec.com>"
__date__ = "Oct 2009"


# The following import are needed when running in jython,
# the NPK.so or NPK.dll should already be loaded in the JVM
# this is generally done by __init__.py

import math
import time
import re
import os
import sys
from . import Nucleus
from . import Param
from .Kore import *
import unittest
try:
    import ConfigParser
except:
    import configparser as ConfigParser

[docs]def get_npk_path(): #print os.getcwd() #return os.path.join(sys.prefix,"NPK") return os.path.join(os.getcwd(),"v1")
#---------------------------------------------------------------------------
[docs]def dict_load(fname): """ load a property list file as a dictionary one entry per line with the following syntax : entry=value keys are set to lowercase """ dico = {} print(fname) try: fin = open(fname) f=fin.read() ls= f.split("\n") for line in ls: if ( line == "" or line[0] == "#"): # skip comments and empty lines continue l = re.split(r'(?<!\\)=', line,1) #matches = but not \= dkey = re.sub(r'\\=', '=',l[0]) fval = re.sub(r'\\=', '=',l[1]) # replaces \= by = try: # check key existence val=dico[dkey] except: pass # else: # if val != fval: # print "WARNING, key -",dkey,"- defined twice in",fname # print " previous value :",val," new value",fval dico[dkey]=fval fin.close except: print("File "+fname+" not found.") print("Creating empty parameter list\n") return dico
#---------------------------------------------------------------------------
[docs]def dict_out(dict,title=""): """ dump the content of a dictionary as a property list file one entry per line with the following syntax : entry=value """ from sys import stdout sys.stdout.write("\n#Property listing (START)" + title + "\n") for i in dict.keys(): lk = re.sub('=', r'\\=', i) # replaces = by \= try: lv = re.sub('=', r'\\=', str(dict[i])) # replaces = by \= except: lv = "UNDEFINED" sys.stdout.write(lk+"="+lv+"\n") sys.stdout.write("#Property listing (END)" + title + "\n\n")
#---------------------------------------------------------------------------
[docs]def dict_dump(dict,fname): """ dump the content of a dictionary as a property list file one entry per line with the following syntax : entry=value """ fout = open(fname, 'w') fout.write("#Property list file, created :"+time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime())+"\n") for i in dict.keys(): lk = re.sub('=', r'\\=', i) # replaces = by \= lv = re.sub('=', r'\\=', str(dict[i])) # replaces = by \= fout.write(lk+"="+lv+"\n") fout.close()
#---------------------------------------------------------------------------
[docs]def build_dict(default_list,p_in_arg={}): """ build the default parameter dictionary used in standard actions, returns a dictionary built from the default parmaters (see do_default.py and Param/*) and the additional parameters defined in the optionnal p_in_arg overwrite the default values wrapper around the NPKParam class """ p = Param.NPKParam() # first load default values p.build_default(default_list) # then add parameters in arg for i in p_in_arg.keys(): try: p[i]=p_in_arg.raw(i) # if p_in_arg is a NPKParam, we DO NOT want to evaluate at this stage ! except: p[i]=p_in_arg[i] # otherwise return p
#---------------------------------------------------------------------------
[docs]def change_key_dict(patternOut, patternIn, p_in_arg): """ goes though the given dictionnay (which remains unchanged) and changes in keys the pattern "patternIn" to "patternOut" and returns the modified dictionnary typically used in 3D processing : change_key_dict('f2', 'f3', change_key_dict('f1', 'f2', p_in)) # in THAT order ! substitutes F2 (of the 3D) by F1 (of the 2D plane) substitutes F3 (of the 3D) by F2 (of the 2D plane) """ verbose = 0 if verbose: print("change_key_dict\n", patternIn,patternOut, p_in_arg) p = Param.NPKParam() if (len(p_in_arg)>0): for i in p_in_arg.keys(): j=re.sub(patternIn,patternOut,i) try: p[j]=p_in_arg.raw(i) # we want raw() values except: p[j]=p_in_arg[i] if verbose: print(p) raise Exception("stop") return(p)
#---------------------------------------------------------------------------
[docs]def key_is_true(dict,key): """ used to check keys in processing parameter files will return true if dict[key] exists and is true will return false otherwise (does not exist or is false) """ try: keytest = dict[key] except: keytest = (1==0) return (keytest)
#---------------------------------------------------------------------------
[docs]def key_is_not_false(dict,key): """ used to check keys in processing parameter files will return true if dict[key] exists and is true or doest not exist will return false if dict[key] is defined false """ try: keytest = dict[key] except: keytest = (1==1) return (keytest)
#---------------------------------------------------------------------------
[docs]def NPKtempfile(ext=".npktmp"): """ Standard tempfile module is VERY buggy in jython, the secure mkstemp is missing, and the basic system call needed to implement it are lacking. This is an attempt to make a "slightly" better tempfile than the jython built-in one. This seems to be enough to change it from really annoying to bearly noticiable... """ import tempfile # will use it nevertheless import random # we'll use random as a work around r=("%d"%int(1000000*random.random())) tpf = tempfile.mktemp(r+ext) F=open(tpf,'w') # equivalent to touch F.close() return tpf
#---------------------------------------------------------------------------
[docs]def save_state(dd): """ save current working data-buffer kind of wrapper over put("data") save on temp file if necessary *** NOT FINISHED yet, do no use *** """ global saved_state,tempdata mem_max = 16*1024*1024 tempdata="empty" where="mem" d = get_dim() if (dd==1): if (get_si1_1d() > mem_max): where="disk" if (dd==2): if (get_si1_2d()*get_si2_2d() > mem_max): where="disk" if (dd==3): if (get_si1_3d()*get_si2_3d()*get_si3_3d() > mem_max): where="disk" dim(dd) if (where=="mem"): put("data") else: tempdata = NPKtempfile('.npktemp') writec(tempdata) dim(d) saved_state=(dd,where) print(repr(saved_state),tempdata)
#---------------------------------------------------------------------------
[docs]def get_saved_state(dd): """ recover saved current working data-buffer """ global saved_state,tempdata (sdim,where)=saved_state d = get_dim() if (where=="mem"): dim(dd) get("data") else: read(tempdata) dim(d)
#---------------------------------------------------------------------------
[docs]def get_itype(dim=0): """ analyze the complex state of the data buffer dim is either 0 (current dim); 1 2 or 3 returns either (t) (t1,t2) (t1,t2,t3) where tx is 0 if real and 1 if complex """ if (dim==0): dim=get_dim() if dim == 1: return get_itype_1d() elif (dim == 2): t1 = get_itype_2d()/2 t2 = get_itype_2d()%2 return (t1,t2) elif (dim == 3): t1 = get_itype_3d()/4 t3 = get_itype_3d()%2 t2 = (get_itype_3d()-4*t1)/2 return (t1,t2,t3) else: raise Exception( "wrong value for dim")
#---------------------------------------------------------------------------
[docs]def set_itype(type): """ set the complex state of the data buffer dim is either 1 2 or 3 type is either (t) (t1,t2) (t1,t2,t3) where tx is 0 if real and 1 if complex """ dim=get_dim() if dim == 1: (t1)=type if (t1<0 or t1>1): raise Exception( "wrong value for type value") itype(t1) elif (dim == 2): (t1,t2)=type if (t1<0 or t1>1): raise Exception( "wrong value for F1 type value") if (t2<0 or t2>1): raise Exception( "wrong value for F2 type value") itype(2*t1+t2) elif (dim == 3): (t1,t2,t3)=type if (t1<0 or t1>1): raise Exception( "wrong value for F1 type value") if (t2<0 or t2>1): raise Exception( "wrong value for F2 type value") if (t3<0 or t3>1): raise Exception( "wrong value for F3 type value") itype(4*t1+2*t2+t3) else: raise Exception( "wrong value for dim")
#---------------------------------------------------------------------------
[docs]def apsl_cp( pki, sz): """computes the phase of the peak centered on i, using +/-sz points the phase of the peak is returned between -180 and 180 i has to be odd ! used by apsl to compute an automatic phase correction of a 1D spectrum see also : apsl() MAD-VC, july 2005""" a = b = 0 pi =4.0*math.atan(1.0) for j in range(2, 2*sz+2, 2): dr = val1d(pki+j) - val1d(pki-j) di = val1d(pki+j+1) - val1d(pki-j+1) a = a + dr*di b = b + di*di - dr*dr phi = 0.5*math.atan(2.0*a/b) px = 0 for j in range(0,4): pj = phi + float(j)*0.5*pi x = math.cos(pj)*val1d(pki) - math.sin(pj)*val1d(pki+1) if ( x > px ): phx = pj px = x while( phx <= -pi ): phx = phx + 2*pi while( phx > pi ): phx = phx - 2*pi return 180.0*phx / pi
#---------------------------------------------------------------------------
[docs]def apsl(): """ APSL method A.Heuer J.Magn.Reson. 91 p241 (1991) uses the data buffer you may want to adapt : s_wdth : ration of line width to spectral width used for computing phases p_wdth : ration of line width to spectral width used for broadening for peak picking npk : minimum number of peaks needed for phasing nfrst : the number of peaks used for first approx see also : apsl2d() apsl_cp() MAD-VC, july 2005 """ s_wdth = 400 p_wdth = 1000 npk = 8 nfrst = 4 dim = get_dim() if ( dim != 1 ): raise Exception( "On 1D only") if ( get_itype_1d() != 1 ): raise Exception( "On complex data only") if ( get_si1_1d() < 500 ): raise Exception( "size too small for operation") # find at least $npk peaks on a smoothed version of the spectrum - insure that size is unchanged ! com_put('data') ift() chsize( get_si1_1d()/2 ) sqsin(0.5) chsize( get_si1_1d()*4 ) ft() modulus() com_max() npeaks = 0 pk = {} amp = {} # do it twice, once on the left part of the spectrum, once on the right one for loop in range(1,3): if ( loop == 1 ): zoom( 1, 0.01*get_si1_1d(), 0.48*get_si1_1d()) else: zoom( 1, 0.52*get_si1_1d(), 0.99*get_si1_1d()) sc = 0.5 while(1): minimax( geta_max(1)*sc, geta_max(1) + 1) peak() if ( get_npk1d() < npk/2 ): sc = sc/1.3 continue if ( get_npk1d() > 2*npk ): sc = sc*1.09 continue break # counting backward here, makes that the first guess is done on the high field part of the spectrum - much better ! for i in range(get_npk1d(),0,-1): pp = geta_pk1d_f(i) npeaks = npeaks + 1 pk[npeaks] = 2*int((pp-1)/2)+1 amp[npeaks] = geta_pk1d_a(i) zoom(0) nfrst = min(nfrst,npeaks) com_get('data') pk[0] = 1 pk[npeaks+1] = get_si1_1d() phi = {} #; compute phase for first peaks for i in range(1,nfrst+1): phi[i] = apsl_cp(pk[i], get_si1_1d() / s_wdth) if ( get_debug() ): print((repr(i) + "th peak at index " + repr(pk[i]) + " phase : " + repr(phi[i]))) phase0 = 0 aaa = 0 #; recompute phase correction for i in range(1,nfrst+1): phase0 = phase0 + amp[i]*phi[i] aaa = aaa + amp[i] phase0 = phase0 / aaa slope = 0.0 if ( get_debug() ): print("1rst guess on " + repr(nfrst) + " peaks : " + repr(phase0) + " " + repr(slope)) phase( phase0, slope) for i in range(1,nfrst+1): phi[i] = phi[i]-phase0 #; then redo for all the others for i in range(nfrst+1,npeaks+1): phi[i] = apsl_cp(pk[i], get_si1_1d()/s_wdth) if ( get_debug() ): print(repr(i) + "th peak at index " + repr(pk[i]) + " phase : " + repr(phi[i])) # correct on all points # by making a weighted linear fit # # f = sum( wi*(axi+b-yi)^2) # wi are = sqrt((modulus of the summit points)*(distance to neighbors)) # #df/db = bW + aX - Y = 0 W=sum(wi) X=sum(xi wi) Y=sum(yi wi) #df/da = bX + aQ - Z = 0 Q=sum(xi^2 wi) Z=sum(xi yi wi) # # a = (YX-ZW)/(X^2-QW) b = (Y-aX)/W = (Z-aQ)/X x = 0 y = 0 z = 0 q = 0 w = 0 for i in range(1,npeaks+1): wi = amp[i] w = w + wi x = x + wi*(pk[i] - get_si1_1d()/2) y = y + wi*phi[i] q = q + wi*(pk[i] - get_si1_1d()/2)*(pk[i] - get_si1_1d()/2) z = z + wi*phi[i]*(pk[i] - get_si1_1d()/2) slope2 = (y*x-z*w)/(x*x-q*w) ph02 = (y-slope2*x)/w slope2 = slope2 * get_si1_1d() get("data") zoom(0) pkclear() phase(phase0+ph02, slope+slope2) if ( get_debug() ): print("final correction : " + repr(phase0 + ph02) + " " + repr(slope) + " " + repr(slope2))
#---------------------------------------------------------------------------
[docs]def apsl2d( axis = "F2"): """a 2D version of apsl() axis is : F1, F2 or F12 will peak pick the 2D, and apply apsl on sums of rows and columns see also : apsl() MAD-VC july 2005 """ return ap2d(apsl,axis)
#---------------------------------------------------------------------------
[docs]def apmin2d( axis = "F2"): """a 2D version of apmin() axis is : F1, F2 or F12 will peak pick the 2D, and apply apmin on sums of rows and columns see also : apsl() MAD-VC july 2005 """ return ap2d(apmin,axis)
#---------------------------------------------------------------------------
[docs]def ap2d(apfunc, axis = "F2"): """a 2D automatic phaser axis is : F1, F2 or F12 will peak pick the 2D, and apply the chose algo on sums of rows and columns MAD nov 2006 """ verbose=0 if verbose : print("ap2d started") npk = 8 ret = "" if ( get_dim() != 2 ): raise Exception( "On 2D only") if ( get_itype_2d() != 3 ): raise Exception( "On hypercomplex data only") if ( get_si1_2d() < 250 or get_si2_2d() < 500 ): raise Exception( "Size too small for operation") # evaluate noise evaln( get_si1_2d()*0.06, get_si2_2d()*0.01, get_si1_2d()*0.80, get_si2_2d()*0.2) #; find at least npk peaks on a smoothed version of the spectrum #; first smooth the spectrum - insure that size is unchanged ! save_state(2) s1 = get_si1_2d() s2 = get_si2_2d() chsize( 2*power2(get_si1_2d()-2), 2*power2(get_si2_2d()-2)) ift("F12") chsize( get_si1_2d()/2, get_si2_2d()/2 ) sqsin(0.35, "F1") sqsin(0.35, "F2") chsize( get_si1_2d()*2, get_si2_2d()*2 ) ft("F12") modulus() chsize( s1/2, s2/2) com_max() npeaks = 0 pk1 = {} pk2 = {} amp = {} if verbose : print("ap2d end prep") #; do it 4 times, on the 4 quadrants for loop in range(1,5): if ( loop == 1 ): zoom(1, get_si1_2d()*0.01, get_si2_2d()*0.01, get_si1_2d()*0.48, get_si2_2d()*0.48 ) #; remove central peaks (could be water) elif ( loop == 2 ): zoom(1, get_si1_2d()*0.01, get_si2_2d()*0.52, get_si1_2d()*0.48, get_si2_2d()*0.99 ) elif ( loop == 3 ): zoom(1, get_si1_2d()*0.52, get_si2_2d()*0.01, get_si1_2d()*0.99, get_si2_2d()*0.48 ) elif ( loop == 4 ): zoom(1, get_si1_2d()*0.52, get_si2_2d()*0.52, get_si1_2d()*0.99, get_si2_2d()*0.99 ) sc = 0.5 if verbose : print("ap2d end 2") for isc in range(1,100): # the purpose of this loop is to limitwhen oscilations happen # print "SC =",sc minimax( geta_max(1)*sc, geta_max(1)+1) if verbose : print("ap2d minimax",isc) peak(0) if verbose : print("ap2d") if verbose : print("ap2d",get_npk2d()) if ( get_npk2d() < npk/2 ): sc = sc / 1.31 continue if ( get_npk2d() > 2*npk ): sc = sc*1.09 continue if verbose : print("ap2d bf break") break #;reset peak coord : if verbose : print("ap2d end 3") for i in range(1, get_npk2d()+1): if ( geta_pk2d_a(i) > 3.0*get_noise()): pp1 = geta_pk2d_f1f(i) pp2 = geta_pk2d_f2f(i) npeaks = npeaks + 1 # pk1[npeaks] = 2.0 * int((pp1-1)/2) + 1 # pk2[npeaks] = 2.0 * int((pp2-1)/2) + 1 pk1[npeaks] = 2*pp1 + 1 #; double because preprocess divided size by 2 pk2[npeaks] = 2*pp2 + 1 amp[npeaks] = geta_pk2d_a(i) #; from these peaks, lets compute a typical F1 and/or F2 spectrum, and lets phase it get_saved_state(2) pf20 = pf21 = 0 pf10 = pf11 = 0 if ( axis == "F12" ): dim(2) row(1) dim(1) zero() put("data") for i in range(1,npeaks+1): dim(2) row(pk1[i]) dim(1) adddata() put("data") # writec("row1.gifa4") apfunc() dim(2) phase( get_ph0(), get_ph1(), "F2") pf20 = get_ph0() pf21 = get_ph1() dim(2) col(1) dim(1) zero() put("data") for i in range(1, npeaks+1): dim(2) col( pk2[i]) dim(1) adddata() put("data") # writec("col1.gifa4") apfunc() dim(2) phase(get_ph0(), get_ph1(), "F1") pf10 = get_ph0() pf11 = get_ph1() if ( axis == "F2" or axis == "F12" ): dim(2) row(1) dim(1) zero() put("data") for i in range(1,npeaks+1): dim(2) row(pk1[i]) dim(1) adddata() put("data") # writec("row2.gifa4") apfunc() dim(2) phase( get_ph0(), get_ph1(), "F2") pf20 = pf20 + get_ph0() pf21 = pf21 + get_ph1() # ret = " ".join(["F2", repr(pf20), repr(pf21), ret]) if ( axis == "F1" or axis == "F12" ): dim(2) col(1) dim(1) zero() put("data") for i in range(1,npeaks+1): dim(2) col(pk2[i]) dim(1) adddata() put("data") # writec("col2.gifa4") apfunc() dim(2) phase( get_ph0(), get_ph1(), "F1") pf10 = pf10 + get_ph0() pf11 = pf11 + get_ph1() # ret = " ".join(["F1", repr(pf10), repr(pf11), ret]) return (pf10, pf11, pf20, pf21)
#----------------------------------------------------------------
[docs]def phase_pivot(p0,p1,pivot=0.5): """ three parameter phasing routine pivot = 0 is on left side pivot = 1 is on right side all intermidoate values are possible returns actual (P0, P1) """ phase(p0+(0.5-pivot)*p1,p1) return(p0+(0.5-pivot)*p1,p1)
#----------------------------------------------------------------
[docs]def neg_wing(): """ measure negative wing power""" dim(1) real() bcorr(1, int(0.01*get_si1_1d()), (int(0.05*get_si1_1d()),int(0.95*get_si1_1d()))) minus() evaln(int(0.05*get_si1_1d()),int(0.95*get_si1_1d())) return(get_noise())
#----------------------------------------------------------------
[docs]def apmin_original(): """automatic 1D phase correction phase by minimizing the negative wing of the spectrum MAD, oct 2006 apmin moved to Kore """ dim = get_dim() if ( dim != 1 ): raise Exception( "On 1D only") if ( get_itype_1d() != 1 ): raise Exception( "On complex data only") # initialize put("data") min=neg_wing() P0min=0 P1min=0 P0minnext=0 P1minnext=0 neval=0 # find largest point get("data") modulus() com_max() npeaks = 0 pk = {} zoom( 1, 0.05*get_si1_1d(), 0.95*get_si1_1d()) minimax( geta_max(1)*0.1, geta_max(1) + 1) #set min and max values peak() pm = 0 im = 0 for i in range(get_npk1d()): if (geta_pk1d_a(i+1)>pm): pm = geta_pk1d_a(i+1) im = geta_pk1d_f(i+1) if (im == 0): raise Exception( "error in getting largest point") else: pivot = (im/get_si1_1d()) # print "Pivot:",pivot # first coarse P0step=10.0 P1step=20.0 while(P0step>=1.0 or P0step <=-1.0): # abs(x) is dead ! moved=1 while(moved): moved=0 # for (dP0,dP1) in ((P0step,P1step),(-P0step,P1step),(P0step,-P1step),(-P0step,-P1step)): for (dP0,dP1) in ((P0step,0),(-P0step,0),(0,P1step),(0,-P1step)): get("data") phase_pivot(P0min+dP0, P1min+dP1,pivot) neval = neval+1 pw=neg_wing() # print P0min+dP0, P1min+dP1, pw if (pw<min): moved=1 min=pw P0minnext = P0min+dP0 P1minnext = P1min+dP1 if (P0step*dP0 <0): # try to remember variation direction P0step = -P0step if (P1step*dP1 <0): P1step = -P1step break P0min = P0minnext P1min = P1minnext # print "*** P0 :",P0min,"P1 :",P1min P0step=P0step/4.0 P1step=P1step/4.0 get("data") (PP0,PP1)=phase_pivot(P0min,P1min,pivot)
# print "*** P0 :",P0min,"P1 :",P1min," (",PP0,PP1,")" # print neval,"evaluations" #---------------------------------------------------------------------------
[docs]def spec_noise(n=10): """estimate of noise in the data-set estimates the noise in the data set by choping into n parts, and keeping the smallest one in the same time evaluates the offset on the dataset on the same part used for noise determination sets the value in get_noise and get_shift""" if ( get_dim() == 1 ): if ( get_itype_1d() != 0 ): # compute on real part only put("data") real() getdata = 1 else: getdata = 0 if ( get_si1_1d() < 200 ): n = round( get_si1_1d()/10) elif ( n < 3 ): n = 10 elif ( get_si1_1d() / n < 20 ): n = round( get_si1_1d()/20) evaln(10, min(100, get_si1_1d())) so_far = get_noise() so_f_sh = 0 # 0 seems to be a better starting point than get_shift() - typically if this remains the best guess for i in range(1,int(n)+1): evaln( get_si1_1d()*(i-1)/n + 1, get_si1_1d()*i / n) if ( get_noise() < so_far ): so_far = get_noise() so_f_sh = get_shift() if ( getdata ): get("data") elif ( get_dim() == 2 ): if ( get_itype_2d() != 0 ): put("data") if ( get_itype_2d() == 3 ): real("F12") elif ( get_itype_2d() == 1): real("F2") elif ( get_itype_2d() == 2 ): real("F1") getdata = 1 else: getdata = 0 if ( get_si1_2d()*get_si2_2d() < 500 ): n = 10 elif ( n < 3 ): n = 10 evaln(1,1,min(100,get_si1_2d()), min(100, get_si2_2d())) so_far = get_noise() so_f_sh = get_shift() sn = round(math.sqrt(n)) for j in range(1,int(n)+1): for i in range(1,int(n)+1): evaln( get_si1_2d()*(i-1)/n + 1, get_si2_2d()*(j-1)/n + 1, get_si1_2d()* i /n , get_si2_2d()* j /n) if ( get_noise() < so_far ): so_far = get_noise() so_f_sh = get_shift() if ( getdata ): get("data") else: raise Exception( "reste a faire en 3D") if ( so_far != 0 ): noise( so_far ) shift( so_f_sh )
#---------------------------------------------------------------------------
[docs]def signal_noise(left=1,right=1,n=10): """estimate the signal to noise of a given 1D data-set It does this by find the most intense peak and dividing it by the noise level left , right define the zone in which the signal/noise is to be computed both value default to 1, right=1 means the right most point. n is the number of pieces on which the noise is computed. """ if right==1: right=get_si1_1d() if (left>=right): raise Exception( "wrong argument to signal_noise()") if (get_itype_1d() != 0): put("data") real() r = 1 else: r = 0 v = 0.0 for i in range(left,right+1): v=max(v,val1d(i)) if r == 1: get("data") return( v/get_noise() )
#---------------------------------------------------------------------------
[docs]def left_shift(shift_size,axis='F1'): """shifts the FID to the left by dropping data points MAD-VC January 2007""" if (get_dim() == 1): reverse() chsize( get_si1_1d() - shift_size) reverse() elif (get_dim() == 2): reverse(axis) if (axis.upper() == 'F1'): chsize( get_si1_2d() - shift_size, get_si2_2d()) elif (axis.upper() == 'F2'): chsize( get_si1_2d(), get_si2_2d()- shift_size) reverse(axis) elif (get_dim() == 3): raise Exception( 'not done yet')
#---------------------------------------------------------------------------
[docs]def right_shift(shift_size,axis='F1'): """shifts the FID to the right by adding null data points at the begining of the FID MAD-VC January 2007""" if (get_dim() == 1): reverse() chsize( get_si1_1d() + shift_size) reverse() elif (get_dim() == 2): reverse(axis) if (axis.upper() == 'F1'): chsize( get_si1_2d() + shift_size, get_si2_2d()) elif (axis.upper() == 'F2'): chsize( get_si1_2d(), get_si2_2d() + shift_size) reverse(axis) elif (get_dim() == 3): raise Exception( 'not done yet')
#---------------------------------------------------------------------------
[docs]def ft_sim(): """performs the fourier transform of a data-set acquired on a Bruker in simultaneous mode Processing is performed only along the F2 (F3) axis if in 2D (3D) (Bruker QSIM mode) see also : ft_seq() ft_sh() ft_tppi() ft_sh_tppi() ft_phase_modu() ft_n_p() MAD-VC July 2005""" if ( get_dim() == 1 ): itype(1) revf() ft() elif ( get_dim() == 2): if ( (get_itype_2d() == 2) or (get_itype_2d() == 0) ): print("Forcing Complex form in F2") itype( get_itype_2d() + 1) revf("f2") ft("f2") elif ( get_dim() == 3): if ( get_itype_3d() % 2 == 0 ): print("Forcing Complex form in F3") itype( get_itype_3d() + 1) revf("f3") ft("f3")
#---------------------------------------------------------------------------
[docs]def ft_seq(): """performs the fourier transform of a data-set acquired on a Bruker in simultaneous mode Processing is performed only along the F2 (F3) axis if in 2D (3D) (Bruker QSIM mode) see also : ft_seq() ft_sh() ft_tppi() ft_sh_tppi() ft_phase_modu() ft_n_p() MAD-VC July 2005""" if ( get_dim() == 1 ): itype(0) revf() rft() elif ( get_dim() == 2 ): if ( get_itype_2d() == 1 or get_itype_2d() == 3 ): print("Forcing Real form in F2") itype( get_itype_2d() - 1) revf("f2") rft("f2") elif ( get_dim() == 3): if ( get_itype_3d() % 2 == 1 ): print("Forcing Real form in F3") itype( get_itype_3d() - 1) revf("f3") rft("f3")
#---------------------------------------------------------------------------
[docs]def ft_tppi( axis = "F1" ): """TPPI F1 Fourier transform""" if ( get_dim() == 2 ): if ( get_itype_2d() == 2 or get_itype_2d() == 3): itype( get_itype_2d() - 2) print("Forcing Real form in F1") rft("f1") elif ( get_dim() == 3 ): axis = axis.upper() if ( axis == "F1" ): if ( get_itype_3d() > 3 ): itype( get_itype_3d()-4 ) print("Forcing Real form in F1") elif ( axis == "F2" ): if ( get_itype3d() % 4 > 1): itype( get_itype_3d() - 2) print("Forcing Real form in F2") else: raise Exception( "wrong axis") rft(axis) else: raise Exception( "Not implemented in 1D, use ft_seq instead")
#---------------------------------------------------------------------------
[docs]def ft_n_p( axis = "F1" ): """F1-Fourier transform for N+P (echo/antiecho) 2D""" if ( get_dim() == 2 ): conv_n_p() ft_sh() else: raise Exception( "in 2D only")
#---------------------------------------------------------------------------
[docs]def ft_sh( axis = "F1" ): """ States-Haberkorn F1 Fourier transform""" if ( get_dim() == 2 ): if (get_itype_2d() == 0 or get_itype_2d() == 1): itype (get_itype_2d()+2) print("Forcing Complex form in F1") revf("f1") ft("f1") elif ( get_dim() == 3 ): axis = axis.upper() if ( axis == "F1" ): if ( get_itype_3d() < 4 ): print("Forcing Complex form in F1") itype( get_itype_3d() + 4 ) elif ( axis == "F2" ): if ( get_itype_3d() % 4 < 2 ): itype( get_itype_3d() + 2 ) print("Forcing Complex form in F2") revf(axis) ft(axis) else: raise Exception( "not implemented in 1D, use ft_sim instead")
#---------------------------------------------------------------------------
[docs]def ft_sh_tppi( axis = "F1" ): """States-Haberkorn / TPPI F1 Fourier Transform """ if ( get_dim() == 2 ): if ( get_itype_2d() == 0 or get_itype_2d() == 1 ): itype( get_itype_2d() + 2 ) print("Forcing Complex form in F1") ft("F1") elif ( get_dim() == 3 ): axis = axis.upper(); if ( axis == "F1" ): if( get_itype_3d() < 4 ): itype( get_itype_3d() + 4 ) print("Forcing Complex form in F1") elif ( axis == "F2" ): if ( get_itype_3d() % 4 < 2 ): itype( get_itype_3d() + 2 ) print("Forcing Complex form in F2") else: raise Exception( "Wrong axis") ft( axis); else: raise Exception( "Not implemeted in 1D")
#---------------------------------------------------------------------------
[docs]def ft_phase_modu( axis = "F1" ): """F1-Fourier transform for phase-modulated 2D""" if ( get_dim() != 2 ): raise Exception( "implemented only in 2D") else: itype(1) flip() revf("F1") ft("F1") flop() reverse("F1")
#---------------------------------------------------------------------------
[docs]def expbroad( lb, axis = "F1" ): """apply a lb exponential broadening along given axis""" if ( get_dim() == 1 ): em(lb) else: axis = axis.upper() if ( get_dim() == 2 ): if ( axis == "F1" ): em( lb, 0) elif ( axis == "F2" ): em( 0, lb) elif ( axis == "F12" or axis == "F21" ): em( lb, lb) else: raise Exception( "Wrong axis") elif ( get_dim() == 3 ): if ( axis == "F1" ): em( lb, 0, 0) elif ( axis == "F2" ): em( 0, lb, 0) elif ( axis == "F3" ): em( 0, 0, lb) elif ( axis == "F12" or axis == "F21" ): em( lb, lb, 0) elif ( axis == "F23" or axis == "F32" ): em( 0, lb, lb) elif ( axis == "F31" or axis == "F13" ): em( lb, 0, lb) elif ( axis == "F123" ): em( lb, lb, lb) else: raise Exception( "Wrong dimension")
#---------------------------------------------------------------------------
[docs]def gaussbroad( lb, axis = "F1" ): """apply a lb gaussian broadening along given axis""" if ( get_dim() == 1 ): gm(lb) else: axis = axis.upper() if ( get_dim() == 2 ): if ( axis == "F1" ): gm( lb, 0) elif ( axis == "F2" ): gm( 0, lb) elif ( axis == "F12" or axis == "F21" ): gm( lb, lb) else: raise Exception( "Wrong axis") elif ( get_dim() == 3 ): if ( axis == "F1" ): gm( lb, 0, 0) elif ( axis == "F2" ): gm( 0, lb, 0) elif ( axis == "F3" ): gm( 0, 0, lb) elif ( axis == "F12" or axis == "F21" ): gm( lb, lb, 0) elif ( axis == "F23" or axis == "F32" ): gm( 0, lb, lb) elif ( axis == "F31" or axis == "F13" ): gm( lb, 0, lb) elif ( axis == "F123" ): gm( lb, lb, lb) else: raise Exception( "Wrong dimension")
#---------------------------------------------------------------------------
[docs]def gaussenh( gg, ll, axis = "F1"): """apply a lb gaussian enhancement along given axis""" if ( get_dim() == 1 ): gm(gg) em(-ll*gg) else: axis = axis.upper() if ( get_dim() == 2 ): if ( axis == "F1" ): gm(gg,0) em(-ll*gg,0) elif ( axis == "F2" ): gm(0,gg) em(0, -ll*gg) elif ( axis == "F12" or axis == "F21"): gm( gg, gg) em( -ll*gg, -ll*gg) else: raise Exception( "wrong axis") elif ( get_dim() == 3 ): if ( axis == "F1" ): gm(gg,0,0) em(-ll*gg,0,0) elif ( axis == "F2"): gm(0,gg,0) em(0,-ll*gg,0) elif ( axis == "F3" ): gm(0, 0, gg) em(0, 0, -ll*gg) elif ( axis == "F12" or axis == "F21" ): gm( gg, gg, 0) em( -ll*gg, -ll*gg, 0) elif ( axis == "F23" or axis == "F32" ): gm(0, gg, gg) em(0, -ll*gg, -ll*gg) elif ( axis == "F13" or axis == "F31" ): gm( gg, 0, gg) em( -ll*gg, 0, -ll*gg ) elif ( axis == "F123" ): gm( gg, gg, gg) em( -ll*gg, -ll*gg, -ll*gg) else: raise Exception( "wrong axis")
#---------------------------------------------------------------------------
[docs]def apodise( apod, axis = "F1" ): """ apod is the function to be applied, it is a python callable sequence which realise the apodisation e.g. "sin(0)" "expbroad(10)" "sqsin(0);expbroad(3)" etc... (note the ; to separate several simple apodisations) """ """ M-A Delsuc march 2006 """ # import traceback # print traceback.print_stack(limit=3) import types debug = 0 if type(apod) != str: print(apod) raise Exception( "argument should be an NPK executable string\n\n"+apodise.__doc__) if ( get_dim() == 1 ): if debug: print("apod 1D "+apod) exec(apod) elif ( get_dim() == 2 ): axis = axis.upper() if (axis == 'F2'): if debug: print("apod F2 "+apod) if debug: writec("TTT1.gs2") row(1) # this brings all the descriptors, and is needed for apod() to work dim(1) if (get_itype_1d() == 0): one() else: itype(0);one();itype(1) # one()is complex-sensitive ! try: exec(apod) except: print("error in apodise(), wrong function : " + apod) dim(2) mult1d('F2') elif (axis == 'F1'): if debug: print("apod F1 "+apod) col(1) # this brings all the descriptors, and is needed for apod() to work dim(1) if (get_itype_1d() == 0): one() else: itype(0);one();itype(1) # one()is complex-sensitive ! try: exec(apod) except: print("error in apodise(), wrong function : " + apod) dim(2) mult1d('F1') else: raise Exception( "wrong axis") elif ( get_dim() == 3 ): axis = axis.upper() if (axis == 'F3'): plane('f1',1) # this brings all the descriptors, and is needed for apod() to work dim(2);row(1) dim(1) if (get_itype_1d() == 0): one() else: itype(0);one();itype(1) # one()is complex-sensitive ! try: exec(apod) except: print("error in apodise(), wrong function : " + apod) dim(3) mult1d('F3') elif (axis == 'F2'): plane('f1',1) # this brings all the descriptors, and is needed for apod() to work dim(2);col(1) dim(1) if (get_itype_1d() == 0): one() else: itype(0);one();itype(1) # one()is complex-sensitive ! try: exec(apod) except: print("error in apodise(), wrong function : " + apod) dim(2) mult1d('F2') elif (axis == 'F1'): plane('f2',1) # this brings all the descriptors, and is needed for apod() to work dim(2);col(1) dim(1) if (get_itype_1d() == 0): one() else: itype(0);one();itype(1) # one()is complex-sensitive ! try: exec(apod) except: print("error in apodise(), wrong function : " + apod) dim(2) mult1d('F1') else: raise Exception( "wrong axis")
#---------------------------------------------------------------------------
[docs]def apodise_f( apod, axis = "F1" ): """ apod is the function to be applied, it is a python callable sequence which realise the apodisation e.g. "sin(0)" "expbroad(10)" "sqsin(0),expbroad(3)" etc... (note the , to separate several simple apodisations) M-A D. march 2006 """ if ( get_dim() == 1 ): eval(apod) elif ( get_dim() == 2 ): # the trick is to use apply("window") # however window has to be defined along F1 AND F2, the buffer is of the form : points for F2 : points for F1 : # so we have to put one() on the area of the axis which is not used # we do this by playing with data and adddata() # one day we should write a apply(apode,axis) in the kernel ! - it would simplyy this mess axis = axis.upper() if (axis == 'F2'): row(1) # this brings all the descriptors, and is needed for apod() to work dim(1) chsize(get_si2_2d()) one() # put 1.0 in 1D buffer try: exec(apod) except: print("error in apodise(), wrong function : " + apod) chsize(get_si1_2d()+get_si2_2d()) put("data") # now we have in data : apod() in F2 buffer : 0 in F1 buffer : chsize(get_si1_2d()) one() chsize(get_si1_2d()+get_si2_2d()) reverse() # now we have : 0 in F2 buffer : 1 in F1 buffer : adddata() # now we have : apod() in F2 buffer : 1 in F1 buffer : put("window") dim(2) apply("window") elif (axis == 'F1'): col(1) dim(1) chsize(get_si1_2d()) one() # put 1.0 in 1D buffer try: exec(apod) except: print("error in apodise(), wrong function : " + apod) reverse() chsize(get_si1_2d()+get_si2_2d()) reverse() put("data") # now we have in data : 0 in F2 buffer : apod() in F1 buffer : chsize(get_si2_2d()) one() chsize(get_si1_2d()+get_si2_2d()) # now we have : 1 in F2 buffer : 0 in F1 buffer : adddata() # now we have : 0 in F2 buffer : apod() in F1 buffer : put("window") dim(2) apply("window") else: raise Exception( "error with axis") else: raise Exception( "not implemented yet !")
#---------------------------------------------------------------------------
[docs]def apodise_p( apod, axis = "F1" ): if ( get_dim() == 1 ): lst = apod.split() leng = len(lst) i = 0 while( i < leng ): apod = lst[i] print("parsing " + apod) if ( apod == "sin" ): i= i+1 arg = float(lst[i]) sin(arg) elif ( apod == "sqsin" ): i = i+1 arg = float(lst[i]) sqsin(arg) elif ( apod == "expbroad" or apod == "em"): i = i+1 arg = float(lst[i]) expbroad(arg) elif ( apod == "gaussbroad" ): i = i+1 arg = float(lst[i]) gaussbroad(arg) elif ( apod == "gaussenh" ): i = i+1 arg = float(lst[i]) i = i+1 arg2 = float(lst[i]) gaussenh(arg, arg2) elif ( apod == "tm" ): i = i+1 arg = int(float(lst[i])) i = i+1 arg2 = int(float(lst[i])) tm( arg, arg2) elif ( apod == "DO_NOTHING"): pass else: raise Exception( ("Internal error in Apodisation -> " + apod)) i=i+1 elif ( get_dim() == 2 or get_dim()== 3 ): axis = axis.upper() lst = apod.split() leng = len(lst) i = 0 while( i < leng ): apod = lst[i] if ( apod == "sin" ): i= i+1 arg = float(lst[i]) sin(arg, axis) elif ( apod == "sqsin" ): i = i+1 arg = float(lst[i]) sqsin(arg, axis) elif ( apod == "em" ): i = i+1 arg = float(lst[i]) expbroad(arg, axis) elif ( apod == "expbroad" ): i = i+1 arg = float(lst[i]) expbroad(arg, axis) elif ( apod == "gaussbroad" ): i = i+1 arg = float(lst[i]) gaussbroad(arg, axis) elif ( apod == "gaussenh" ): i = i+1 arg = float(lst[i]) i = i+1 arg2 = float(lst[i]) gaussenh(arg, arg2, axis) elif ( apod == "tm" ): i = i+1 arg = int(lst[i]) i = i+1 arg2 = int(lst[i]) tm( arg, arg2, axis) elif ( apod == "DO_NOTHING"): pass else: raise Exception( ("Internal error in Apodisation -> " + apod)) i=i+1
#---------------------------------------------------------------------------
[docs]def hanning( axis = "F1"): """hanning apodisation""" if ( get_dim() == 1 ): sin( 0.5 ) else: axis = axis.upper() if ( get_dim() == 2 ): sin(0.5, axis) elif ( get_dim() == 3): sin(0.5, axis)
#---------------------------------------------------------------------------
[docs]def bucket(start=0.5, end=9.5, bsize=0.04, file='bucket.cvs'): """ This tool permits to realize a bucket integration from the current 1D data-set. You will have to determine (all spectral values are in ppm) - start, end : the starting and ending points of the integration zone in the spectrum - bsize : the size of the bucket - file :the filename to which the result is written the "set to current window" button defines the starting and ending points of the integration zone from the current zoom window the "record" button permits to memorize the current parameters, which will be reused for the bucket integration. the "details" button displays the number and the size of the buckets currently defined. a non-integer size means that the integration will be performed on a varying number of data points in order to insure a constant integration width in ppm. However, the integration intensity is not modified by the integration width. For a better bucket integration, you should be careful that : - the bucket size is not too small, size is better than number ! - the baseline correction has been carefully done - the spectral window is correctly determined to encompass the meaningfull spectral zone. %programer% see also : int1d integrate.g %author% MA Delsuc %version% 5.2005 """ # alert2 ('You will have';round(($end-$start+$bsz)/$bsz); 'buckets') ('with a mean size of';round(100*$si1_1d*$bsz*$freq_1d/$specw_1d)/100;'data points') if get_dim() != 1: raise Exception(('Available on 1D data only')) com_max() if (geta_max(1) == 0.0): raise Exception( "Empty data-set !") if (bsize < 0): raise Exception( "Negative bucket size not allowed") if (start-bsize/2 < itop(get_si1_1d(),1,1)): raise Exception( "Starting point outside spectrum") if (end+bsize/2 > itop(1,1,1)): raise Exception( "Ending point outside spectrum") if ((end-start)/bsize < 10): raise Exception( "Integration zone too small or Bucket too large") put('data') if (bsize < (get_specw_1d/get_freq_1d/get_si1_1d)): get('data') raise Exception( "Bucket size smaller than digital resolution !") mkreal() int1d() fout = open(file) s = "# %i buckets with a mean size of %.2f data points" % ( round((end-start+bsize)/bsize), get_si1_1d()*bsize*get_freq_1d()/get_specw_1d() ) print(s) fout.writelines(s) fout.writelines("center, bucket, bucket_size") here = min(start,end) here2 = (here-bsize/2) there = max(start,end) while (here2 < there): ih = round(ptoi(here2,1,1)) next = (here2+bsize) inext = (round(ptoi(next,1,1))) fout.writeline("%f, %f, %d"%(here, ((val1d(ih)-val1d(inext))/((ih-inext)*bsize)), (ih-inext) )) here2 = next here = (here+bsize) get('data') close(fout)
#---------------------------------------------------------------------------
[docs]def auditinitial( auditfilename="audit_trail.html",title="NPK Processing",append=1): """ initialize the audit trail file auditfilename is the name of the audit file if the file does not exist it is created and initialized, if append ==1 and if the file exists, content will be added to it, this is the default behaviour """ from ..v1 import NPK_version NPK_version = NPK_version if (auditfilename=="mute"): return "mute" if os.path.exists(auditfilename) and append==1: auditfile = open(auditfilename,"a") else: auditfile = open(auditfilename,"w") auditfile.writelines(""" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="description" content="audit trail of NPK processing"/> <meta name="generator" content="NPK, version %(NPK_version)s"/> <title>%(title)s</title> </head> <body> """%(vars())) auditfile.writelines("<h1>" + title + "</h1>\n") auditfile.writelines("<h2>Processing conditions</h2>\n <ul><li>date: <b>" + time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime())+"</b></li>\n") auditfile.writelines("<li>working directory :<b>%s</b></li>\n"%(os.path.abspath(os.curdir))) auditfile.writelines("<li>command line :<b>" + repr(sys.argv) + "</b></li>\n") # auditfile.writelines("<li>operator :<b>" + get_user() + "</b></li>\n") # auditfile.writelines("<li>NPK version :<b>" + __version__ + "</b></li>\n") auditfile.writelines('<li>NPK version: <b>'+NPK_version+'</b></li>\n') auditfile.writelines("<li>SPIKE kernel version: <b>" + get_version() + "</b></li>\n") auditfile.writelines("</ul>\n") return auditfile
#---------------------------------------------------------------------------
[docs]def audittrail( auditfile, phtx, *argl ): """ management of the audit trail. first argument determines action : open close phase text arguments depends on the action audittrail(open, "title in audit file") opens the audit trail - use the argument as title audittrail(close) closes the audit trail audittrail(phase, "title of phase") start a new phase, creates a new heading in the audit trail audittrail(text, "text to write in audit trail", parameter_name, parameter_value, ...) writes in the audit trail if text is available on several arguments, several lines are displayed, in this case, the first arguments is the text/title, and the following arguments are by pair, with parameter_name parameter_value if phase mode <P> lines are added if text mode a <li> list is built """ if (auditfile=="mute"): return writemode = 0 if ( phtx == "close" ): if ( auditfile is not None ): # auditfile.writelines("<P>End of Audit Trail</P>\n</body></html>\n") writemode = 0 elif ( phtx == "3D-phase" ): pre = '</blockquote><hr size="7" noshade="noshade"/><h1>' post = "</h1><blockquote>" preline = "<p>" postline = "</p>\n" writemode = 1 elif ( phtx == "phase" ): pre = '<hr width="80%" noshade="noshade"/><h2>' post = "</h2>\n" preline = "" postline = "" writemode = 1 elif ( phtx == "text" ): pre = "<ul>" post = "</ul>" preline = "<li>" postline = "</li>\n" writemode = 1 else: raise Exception( "wrong key error in audit trail") if ( writemode ): if ( auditfile is not None ): auditfile.writelines(pre) text = argl[0] auditfile.writelines( preline + text ) leng = len(argl) if ( leng > 1 ): if ( phtx == "text" ): auditfile.writelines("<ul>") for i in range(1,leng,2): auditfile.writelines( preline + str(argl[i]) ) try: text=re.sub("\n","<br/>",str(argl[i+1])) except: text=" missing value" auditfile.writelines( ": <b>" + text + "</b>" + postline) if ( phtx == "text" ): auditfile.writelines("</ul>\n") auditfile.writelines( postline ) auditfile.write( post ) auditfile.flush() else: for t in argl: print(( "--audit--" + repr(t)))
#--------------------------------------------------------------------------- # derivative -- compute derivative of a given dataset #---------------------------------------------------------------------------
[docs]def derivative( n, sm ): """@sig public void derivative( int n, int sm )""" if ( get_dim() != 1 ): raise Exception( "derivative is available in 1D only") shift = int(sm/2)+1 for i in range(1,sm+1): smooth(2) for i in range(1,n+1): dsa( shift, -1) mult(-1)
#---------------------------------------------------------------------------
[docs]def causal_corr( delay ): """ remove the effect of a time shift on the spectrum due to digital filtering (Bruker) """ com_phase(0.0, -360.0*delay )
#---------------------------------------------------------------------------
[docs]def causalize( delay ): """ remove the effect of a time shift on the FID due to digital filtering (Bruker) brings back the beginning of the FID at the first data point shorten the FID length respectively """ if ( get_dim() == 1 ): si = get_si1_1d() revf() # change Cpx representation chsize( 4*power2(si-1) ) # zerofill to next 2^n itype(1) ft() phase( 0, -360.0 * delay) n = max( 2*int(delay), 0.0) # compute points to remove real() iftbis() # recompute FID chsize(si-n) # truncate revf() print("CAUSALIZE 1D",delay,si,n,get_si1_1d(),get_ph0(),get_ph1()) elif ( get_dim() == 2 ): si = get_si2_2d() revf("f2") chsize( get_si1_2d(), 4*power2(si-1)) if ( get_itype_2d() == 0 or get_itype_2d() == 2 ): itype( get_itype_2d() + 1) ft("f2") phase(0, -360.0/delay, "f2") n = max(2*int(delay), 0.0) real("f2") iftbis("f2") chsize( get_si1_2d(), si-n ) revf("f2")
#--------------------------------------------------------------------------- # conv_n_p -- ?? #---------------------------------------------------------------------------
[docs]def conv_n_p(): """ realizes the preparation of 2D FID acquired in n+p mode (echo / anti echo """ for i in range(2, get_si1_2d()+2, 2): k = i-1 row(k) dim(1) put("data") dim(2) row(i) dim(1) adddata() dim(2) put("row", k) row(i) dim(1) mult(-1.0) adddata() phase(90.0,0.0) dim(2) put("row", i)
#--------------------------------------------------------------------------- # autocalib -- autocalibration of the spectrum #---------------------------------------------------------------------------
[docs]def autocalib_old(): """ on a 2D experiment, assuming the F2 axis is 1H try to detect spin nature from frequency, and apply the unified scale as proposed by IUPAC-2001 WARNING, proteins tend to use DSS reference, where IUPAC imposes TMS this makes +2.66 ppm shift in 13C. IDEM, for 15N proteins tend to use NH3 reference, where IUPAC imposes MeNO3 this makes a +385.50 ppm shift in 15N. """ n15 = Nucleus.freq("15N",1.0) # was (from NH3) 0.101329118 ; now is 0.10136767 (from MeNO3) - 385.50 ppm shift c13 = Nucleus.freq("13C",1.0) # was 0.251449530 (from DSS); now 0.2514502 (from TMS) - 2.66 ppm shift if ( get_dim() == 1 ): print("Nothing to do in F1") elif ( get_dim() == 2 ): r = get_freq_1_2d() / get_freq_2_2d() if ( (0.09 < r) and (r < 0.11)): print("set to 1H-15N") vish = n15 ret = "15N" elif ( (0.24 < r) and (r < 0.26)): print("set to 1H-13C") vish = c13 ret = "13C" elif ( (0.98 < r) and (r < 1.02)): print("set to homonuclear") vish = 1.0 ret = "1H" else: vish = r print("unknown Nucleus") ret = "Unknown" decalh = itoh( get_si2_2d()/2, 2, 2) zeroh = get_freq_2_2d()*1000000 - decalh zerox = zeroh * vish decalx = get_freq_1_2d()*1000000 - zerox offset( decalx - get_specw_1_2d()/2, get_offset_2_2d()) else: print("Not available yet") ret = "None" return ret
#---------------------------------------------------------------------------
[docs]def autocalib(mode="IUPAC"): """ on a 2D experiment, assuming the F2 axis is 1H try to detect spin nature from frequency, and apply the unified scale as proposed by IUPAC-2001 Harris et al. NMR Nomenclature: Nuclear Spin Properties and Conventions for Chemical Shifts—IUPAC Recommendations. Journal of Magnetic Resonance (2002) vol. 156 (2) pp. 323-326 WARNING, a different setting for biomolecules was proposed in a IUPAC/IUB recommendation in 1998 Markley et al. Recommendations for the presentation of NMR structures of proteins and nucleic acids. Journal of Molecular Biology (1998) vol. 280 (5) pp. 933-952 This previous recommendation was only mentionning 2D 13C, 15N and 31P, but was using different references Usage is to use 1998 recommendation for proteins and nucleic acids. these are enforced when mode = "IUB" or "biomolecule" this makes +2.6645 ppm shift in 13C. this makes a +380.4434 ppm shift in 15N. Returns the name of the defined nucleus in F1, "15N" "13C" "31P" or "None" if nothing was done """ ret = "None" if ( get_dim() == 1 ): print("Nothing to do in F1") elif ( get_dim() == 2 ): F1 = get_freq_1_2d() F2 = get_freq_2_2d() for nuc in ("1H","13C","15N","31P","2H"): fnuc = Nucleus.freq(nuc,F2,mode) # freq of nuc, assuming F2 is 1H if abs(fnuc-F1)/fnuc <1E-3: # close to 1000 ppm print("set to ",nuc) vish = Nucleus.freq(nuc,1.0,mode) # ratio freq_of_nuc / freq_of_1H ret = nuc break if ret != "None": decalh = itoh( F2/2, 2, 2) zeroh = F2*1000000 - decalh zerox = zeroh * vish decalx = F1*1000000 - zerox off1 = decalx - get_specw_1_2d()/2 offset( off1, get_offset_2_2d()) else: print("Not available yet") return ret
#---------------------------------------------------------------------------
[docs]def hilbert( axis = "F1"): """convert a real data set to a complex dataset by using the Hilbert transform the number of data point is doubled, thus hilbert();real() is (nearly) a null operation axis can be F1 F2 or F12 in dim(1) no axis is needed does not work in dim(3) yet minimal error checking, done mostly by the FT operations. Note that a small apodisation is done on the Fourier transform to reduce truncation artifacts you might want to remove this in certain cases, for instance if you plan to have several hilbert() applied to the same data in sequence. see also : tocomplex() invhilbert() """ if ( get_dim() == 1 ): if ( get_itype_1d() == 1 ): raise Exception( "Wrong data format in hilbert()") si = get_si1_1d(); chsize( 2*power2(get_si1_1d() - 2)); iftbis() tm(1,int(get_si1_1d()*0.6)) # small apodisation chsize( get_si1_1d() * 2) ft() if ( 2*si != get_si1_1d() ): chsize( 2*si ) elif ( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" or axis == "F12" ): if ( get_itype_2d() == 2 or get_itype_2d() == 3 ): raise Exception( "Wrong data format in hilbert()") si = get_si1_2d(); chsize( 2*power2(get_si1_2d()-2), get_si2_2d()) iftbis("F1") tm(1,int(get_si1_2d()*0.6),"F1") # small apodisation chsize( get_si1_2d()*2, get_si2_2d()) ft("F1") if( 2*si != get_si1_2d()): chsize(2*si, get_si2_2d()) if ( axis == "F2" or axis == "F12" ): if ( get_itype_2d() == 1 or get_itype_2d() == 3): raise Exception( "Wrong data mode in hilbert.g") si = get_si2_2d() chsize( get_si1_2d(), 2*power2(get_si2_2d()-2)) iftbis("F2") tm(1,int(get_si2_2d()*0.6),"F2") # small apodisation chsize( get_si1_2d(), get_si2_2d()*2 ) ft("F2") if ( 2*si != get_si2_2d()): chsize( get_si1_2d(), 2*si)
#---------------------------------------------------------------------------
[docs]def invhilbert( axis = "F1" ): """convert a complex data set to a real dataset by using the Hilbert transform the number of data point is unchanged, thus the final real dataset is zerofilled once compared to the initial invhilbert() is nearly equivalent to having zerofillied once before FT, but processing time is faster. despite the name, not quite the inverse of hilbert() ! axis can be F1 F2 or F12 in dim(1) no axis is needed does not work in dim(3) yet minimal error checking, done mostly by the FT operations. see also : tocomplex() hilbert() """ if ( get_dim() == 1 ): if ( get_itype_1d() == 0 ): raise Exception( "wrong data format in invhilbert()") si = get_si1_1d() chsize(2*power2(get_si1_1d()-2)) ift() ftbis() if ( si != get_si1_1d() ): chsize(si) elif ( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" or axis == "F12" ): if ( get_itype_2d() < 2 ): raise Exception( "wrong data format in invhilbert()") si = get_si1_2d() chsize( 2*power2(get_si1_2d()-2), get_si2_2d()) ift("F1") ftbis("F1") if ( si != get_si1_2d()): chsize( si, get_si2_2d()) if ( axis == "F2" or axis == "F12" ): if ( get_itype_2d() % 2 == 0 ): raise Exception( "wrong data format in invhilbert()") si = get_si2_2d() chsize( get_si1_1d(), 2*power2(get_si2_2d()-2)) ift("F2") ftbis("F2") if ( si != get_si2_2d()): chsize( get_si1_2d(), si )
#---------------------------------------------------------------------------
[docs]def plane_size(axis='F1'): """ returns (si1,si2) the size of the plane orthogonal to axis from the joined dataset """ if (get_c_dim() != 3): raise Exception( 'only on 3D data') ax=axis.upper() if (ax == 'F1'): return (get_c_sizef2(),get_c_sizef3()) elif (ax == 'F2'): return (get_c_sizef1(),get_c_sizef3()) elif (ax == 'F3'): return (get_c_sizef1(),get_c_sizef2()) else: raise Exception( 'wrong axis')
#---------------------------------------------------------------------------
[docs]def filec_status(): """dumps the detailled header of a joined cache file used mostly for debugging """ print(""" Dim : %i FREQ : %f F1 F2 F3 Size : %8i %8i %8i SW : %8f %8f %8f offsets : %8f %8f %8f Freq : %8f %8f %8f """%(get_c_dim(), get_c_freq(), get_c_sizef1(), get_c_sizef2(), get_c_sizef3(), get_c_specwf1(), get_c_specwf2(), get_c_specwf3(), get_c_offsf1(), get_c_offsf2(), get_c_offsf3(), get_c_freq1(), get_c_freq2(), get_c_freq3() ))
#---------------------------------------------------------------------------
[docs]def proc3d( sourcefile, destinationfile, plane_to_process, commands, context): """ this macro processes a 3D file using the cache system (join, getc, putc) it permits to handle very large files, which would not fit into memory. sourcefile : is the initial data-set destinationfile : is the result of the process plane_to_process : either F1, F2 or F3 (NOT F12 or F123) F1 means : planes perpendicular to F1, thus the planes containing the F2 and F3 axes. commands : a string holding the commands to be applied to each plane in 2D notation context : a dictionary containing the variables needed to execute commands, i.e. exec(commands,context) will actually be used usually built from globals() and locals() the commands are the regular commands you would used to process a 2D data-set. when called without parameters, 'commands' can be several line long, as typed when proc3d is called with parameters on the line, then 'commands' should be a single command line within quotes. e.g. proc3(ser_file, F1_proc, "F1", 'sin(0.2,"f12"); ft_sim(); phase(30,-40,f2); real("f12"); ft_tppi()') # process axes f3 and f2 as 2D proc3(F1_proc, full_proc, "F2", 'sin(0.2,"f1"); ft_tppi(); real("f1"); bcorr(3,"f1")') # process axis f1 would process a whole 3D in 2 steps. """ # from Process1D import * # from Process2D import * # from Process3D import * # import Process2D debug = 0 # set to 1 to debug infile = sourcefile join(infile) if (get_c_dim() != 3): raise Exception( 'available on 3D data only' ) outfile = destinationfile if (infile == outfile): raise Exception( 'input file and output file must be different') axis = plane_to_process.upper() if (not (axis in ('F1','F2','F3'))): raise Exception( 'error with axis') ancdim = get_dim() # check how the size and itype changes dim(2) join(infile) (si1,si2)=plane_size(axis) getc(axis,1,1,1,si1,si2) exec(commands, context) # exec commands in context (it1,it2) = get_itype(2) si1ap=get_si1_2d() si2ap=get_si2_2d() # find type along unprocessed axis # then compute final itype if (axis == 'F1'): itc = (int(get_c_type()/4)) it = (4*itc + 2*it1 + it2) elif (axis == 'F3'): itc = (get_c_type() % 2) it = (4*it1 + 2*it2 + itc) elif (axis == 'F2'): itc = (int(get_c_type() / 2)) itc = (itc % 2) it = (4*it1 + 2*itc + it2) # then create large out_file if (axis == 'F1'): newfilec(outfile, get_c_freq(), it, (get_c_sizef1(),get_si1_2d(),get_si2_2d()), (get_c_offsf1(), get_offset_1_2d(),get_offset_2_2d()), (get_c_specwf1(), get_specw_1_2d(), get_specw_2_2d()), (get_c_freq1(),get_freq_1_2d(),get_freq_2_2d()) ) iter = get_c_sizef1() elif (axis == 'F2'): newfilec(outfile, get_c_freq(), it, (get_si1_2d(),get_c_sizef2(),get_si2_2d()), (get_offset_1_2d(),get_c_offsf2(),get_offset_2_2d()), (get_specw_1_2d(), get_c_specwf2(), get_specw_2_2d()), (get_freq_1_2d(),get_c_freq2(),get_freq_2_2d()) ) iter = get_c_sizef2() elif (axis == 'F3'): newfilec(outfile, get_c_freq(), it, (get_si1_2d(),get_si2_2d(),get_c_sizef3()), (get_offset_1_2d(),get_offset_2_2d(),get_c_offsf3()), (get_specw_1_2d(), get_specw_2_2d(),get_c_specwf3()), (get_freq_1_2d(),get_freq_2_2d(),get_c_freq3()) ) iter = get_c_sizef3() disjoin() join(outfile) # process dim(2) if (debug ==1): print("PROC3D : number of plane to process :", iter) iter = min(iter,4) print("PROC3D : limited to ",iter,"for debuging purposes") print("PROC3D : planes : (%i,%i)->(%i,%i)"%(si1,si2,si1ap,si2ap)) for i in range(1,iter+1): print("### IN : %s, OUT %s, plane %d / %d"%(infile,outfile,i,iter)) join(infile) getc(axis,i,1,1,si1,si2) exec(commands, context) join(outfile) putc(axis,i,1,1,si1ap,si2ap) join(infile) disjoin() join(outfile) disjoin()
#---------------------------------------------------------------------------
[docs]def tocomplex( axis = "F1"): """ tocomplex -- make dataset complex """ if ( get_dim() == 1 ): if ( get_itype_1d() == 0 ): hilbert() itype(1) # a verifer elif ( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" ): if ( get_itype_2d() == 1 or get_itype_2d() == 0 ): hilbert("F1") elif ( axis == "F2" ): if ( get_itype_2d() == 2 or get_itype_2d() == 0 ): hilbert("F2") elif ( axis == "F12" or axis == "F21" ): if ( get_itype_2d() == 0 ): hilbert("F12") elif ( get_itype_2d() == 1 ): hilbert("F1") elif ( get_itype_2d() == 2 ): hilbert("F2") else: raise Exception( "Wrong argument in tocomplex()") else: raise Exception( "Wrong dimension in tocomplex()")
#---------------------------------------------------------------------------
[docs]def toreal( axis = "F1" ): """ toreal -- make dataset real """ if ( get_dim() == 1 ): if ( get_itype_1d() == 1 ): real() elif ( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" ): if( (get_itype_2d() == 2) or (get_itype_2d() == 3) ): real("F1") elif ( axis == "F2" ): if ( (get_itype_2d() == 1) or (get_itype_2d() == 3) ): real("F2") elif ( axis == "F12" or axis == "F21" ): if ( get_itype_2d() == 1 ): real("F2") elif ( get_itype_2d() == 2 ): real("F1") elif ( get_itype_2d() == 3 ): real("F12") else: raise Exception( "Wrong argument in toreal") else: raise Exception( "Wrong dimension in toreal")
#---------------------------------------------------------------------------
[docs]def flat_solvent( param, delay=0.0 ): """reduces the solvent signal supposed to be at the carrier frequency to be applied on the time domain, before Fourier transform actually performs a "baseline" fit type of processing on the FID, real and imaginary parts are handled independantly param is either polynomial moving_average polynomial+moving_average moving_average+polynomial and determines the fitting algo used. delays is the timezeo delay offset (not implemented yet) """ if ( param == "no" ): return if ( get_dim() == 1 ): i = get_si1_1d() elif ( get_dim() == 2 ): i = get_si2_2d() else: raise Exception( "Not implemented in 3D") if ( get_dim() == 1 ): svspecw = get_specw_1d() svfreq = get_freq_1d() svoff = get_offset_1d() dim(2) itype( get_itype_1d() ) chsize(1, get_si1_1d()) rem_1d = 1 com_put("row",1) elif ( get_dim() == 2 ): rem_1d = 0 row(1) if ( get_itype_1d() != 0 ): rem_uswa = 1 if ( power2(get_si1_1d()) != get_si1_1d()): chsize( get_si1_2d(), 2*power2( get_si1_1d())) uswa("F2") modifysize( 2*get_si1_2d(), get_si2_2d()/2) else: rem_uswa = 0 if ( param == "polynomial" ): bcorrp0() segm1(0) bcorr(3,"F2") bcorrp0() elif ( param == "moving_average" ): bcorrp1() segm1(0) bcorr(3,"F2") bcorrp0() elif( param == "polynomial+moving_average" ): bcorrp0() segm1(0) bcorr(3,"F2") bcorrp0() bcorrp1() segm1(0) bcorr(3,"F2") bcorrp0() elif( param == "moving_average+polynomial" ): bcorrp1() segm1(0) bcorr(3,"F2") bcorrp0() bcorrp0() segm1(0) bcorr(3,"F2") bcorrp0() if ( rem_uswa != 0 ): modifysize( get_si1_2d()/2, get_si2_2d()*2) swa("F2") if ( get_si1_1d() != get_si2_2d()): chsize( get_si1_2d(), get_si1_1d()) if ( rem_1d == 1 ): row(1) dim(1) specw( svspecw ) freq( get_freq(), svfreq ) offset( svoff )
#--------------------------------------------------------------------------- # burg_mirror -- ?? #---------------------------------------------------------------------------
[docs]def burg_mirror( n, bsz ): if ( n == -1 ): msz = get_si1_1d() else: msz = get_si1_1d() - 2*n - 2 mirror(n) burg(msz+bsz) reverse() chsize(bsz) reverse
#--------------------------------------------------------------------------- # burg_back -- ?? #---------------------------------------------------------------------------
[docs]def burg_back( nsz ): if ( get_dim() != 1 ): raise Exception( "Available in 1D only") if ( nsz <= get_si1_1d()): raise Exception( "Wrong size") if ( nsz != int(nsz/2)*2 ): raise Exception( "size should be even") itype(1) reverse() burg(int(nsz)) reverse()
#--------------------------------------------------------------------------- # burg2d -- ?? #---------------------------------------------------------------------------
[docs]def burg2d_back( axis, nsz): if ( get_dim() != 2 ): raise Exception( "Available in 2D only") else: axis = axis.upper() if ( nsz != int(nsz/2)*2): raise Exception( "size should be even") if ( axis == "F1" ): if ( nsz <= get_si1_2d()): raise Exception( "Wrong size") osz = get_si1_2d() chsize( nsz, get_si2_2d()) ext = "col" imax = get_si2_2d() elif ( axis == "F2" ): if ( nsz <= get_si2_2d()): raise Exception( "Wrong size") osz = get_si2_2d() chsize( get_si1_1d(), nsz ) ext = "row" imax = get_si1_1d() else: raise Exception( "Wrong axis for LP") if ( ext == "row" ): for i in range(1,imax+1): row(i) dim(1) chsize(osz) itype(1) reverse() burg(nsz) reverse() dim(2) put("row",i) else: for i in range(1,imax+1): col(i) dim(1) chsize(osz) itype(1) reverse() burg(nsz) reverse() dim(2) put("col",i)
#--------------------------------------------------------------------------- # burg2d_mirror -- ?? #---------------------------------------------------------------------------
[docs]def burg2d_mirror( axis, n, bsz): axis = axis.upper() if ( axis == "F1" ): if ( bsz <= get_si1_2d()): raise Exception( "Wrong size") if ( n == -1 ): msz = get_si1_2d() else: msz = get_si1_2d() - 2*n - 2 cmd = "col" count = get_si2_2d() osz = get_si1_2d() chsize( bsz, get_si2_2d()) elif ( axis == "F2" ): if ( bsz <= get_si2_2d() ): raise Exception( "Wrong size") if ( n == -1 ): msz = get_si2_2d() else: msz = get_si2_2d() - 2*n - 2 cmd = "col" count = get_si1_1d() osz = get_si2_2d() chsize( get_si1_1d(), bsz ) else: raise Exception( "wrong axis in burg2d_mirror.g") dim(2) if ( cmd == "row" ): for i in range(1,count+1): row(i) dim(1) chsize(osz) mirror(n) burg(msz+bsz) reverse() chsize(bsz) reverse() dim(2) put("row",i) else: for i in range(1,count+1): col(i) dim(1) chsize(osz) mirror(n) burg(msz+bsz) reverse() chsize(bsz) reverse() dim(2) put("col",i) dim(2)
#--------------------------------------------------------------------------- # burg2d -- ?? #---------------------------------------------------------------------------
[docs]def burg2d( axis = "F1", nsz = None ): """apply burg extension to all columns (or rows) of current 2D axis is either "F1" or "F2" nsz is extended size, default (None) implies doubling of the size """ writec("toto.gf2") if ( get_dim() != 2 ): raise Exception( "available in 2D only") axis = axis.upper() if ( nsz is None ): if ( axis == "F1"): nsz = 2*get_si1_2d() elif ( axis == "F2" ): nsz = 2*get_si2_2d() if ( axis == "F1" ): if ( nsz <= get_si1_2d() ): raise Exception( "Wrong size") osz = get_si1_2d() chsize( int(nsz), get_si2_2d()) ext = "col" imax = get_si2_2d() elif ( axis == "F2" ): if ( nsz <= get_si2_2d() ): raise Exception( "Wrong size") osz = get_si2_2d() chsize( get_si1_1d(), int(nsz) ) ext = "row" imax = get_si1_2d() else: raise Exception( "Wrong axis for LP") if ( ext == "col" ): print(get_order()) for i in range(1,imax+1): col(i) dim(1) chsize(osz) itype(1) burg(int(nsz)) dim(2) put("col",i) else: for i in range(1,imax+1): row(i) dim(1) chsize(osz) itype(1) burg(int(nsz)) dim(2) put("row", i)
#---------------------------------------------------------------------------
[docs]def dc_offset( zone): """corrects each FID of a dataset for constant offset, estimated on the last % of the fid zone has a value between 0 and 1; 1 means the whole data set, 0.1 means the last 10% """ if ( get_dim() == 1 ): if zone == 0: d=1 else: d = (1-zone)*get_si1_1d() evaln(d, get_si1_1d()) s = get_shift() addbase( s ) return s elif ( get_dim() == 2 ): if zone == 0: d=1 else: d = (1-zone)*get_si1_2d() s = 0 for i in range(1, get_si1_2d()+1): dim(2) row(i) dim(1) evaln(d, get_si1_2d()) s = s + get_shift() addbase( get_shift()) dim(2) put("row",i) return s/get_si1_2d() else: raise Exception( "dc-offset.g reste a faire")
#--------------------------------------------------------------------------- # bcorr_quest -- ?? #---------------------------------------------------------------------------
[docs]def bcorr_quest( p = 4, axis = "F1"): """ apply the QUEST baseline correction, based on the Linear Prediction reconstruction on the beginning of the FID. p is the number of point to reconstruct axis is the axis to process when in nD works on complex as well as real datasets. from MAGMA. 2004 May;16(6):284-96. 2004 Time-domain quantitation of 1H short echo-time signals: background accommodation. Ratiney H, Coenradie Y, Cavassila S, van Ormondt D, Graveron-Demilly D. """ if ( get_dim() == 1 ): if ( p < 0 or p > get_si1_1d()/2): raise Exception( "wrong value for QUEST order") si = get_si1_1d() sip2 = int(2*power2(si-2)) it = get_itype_1d() chsize(int(sip2)) if ( it == 0 ): iftbis() else: ift() reverse() chsize(sip2-int(p)) reverse() burg_back(sip2) if ( it == 0 ): ftbis() else: ft() chsize(si) elif( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" or axis == "F12" ): if ( p < 0 or p > get_si1_2d()/2 ): raise Exception( "wrong value for QUEST order") si = get_si1_2d() sip2 = 2*power2(si-2) it = int( get_itype_2d()/2 ) chsize( sip2, get_si2_2d()) if ( it == 0 ): iftbis("F1") else: ift("F1") reverse("F1") chsize(sip2-p, get_si2_2d()) reverse("F1") burg2d_back("F1", sip2) if ( it == 0 ): ftbis("F1") else: ft("F1") chsize( si, get_si2_2d()) if ( axis == "F2" or axis == "F12" ): if ( p < 0 or p > get_si2_2d()): raise Exception( "wrong value for QUEST mode") si = get_si2_2d() sip2 = 2*power2(si-2) it = get_itype_2d() % 2 chsize( get_si1_2d(), sip2 ) if ( it == 0 ): iftbis("F2") else: ift("F2") reverse("F2") chsize( get_si1_2d(), sip2-p) reverse("F2") burg2d_back("F2", sip2) if ( it == 0 ): ftbis("F2") else: ft("F2") chsize( get_si1_2d(), si) else: raise Exception( "reste a faire en 3D")
#---------------------------------------------------------------------------
[docs]def bcorr_offset( spec_n=30, axis = "F1"): """correct for an offset of the spectrum, computed from an empty region of the spectrum spec_n is the argument to spec_noise() axis is the axis to process when in nD """ print("bcorr_offset",spec_n,axis) if ( get_dim() == 1 ): spec_noise(spec_n) addbase( get_shift()) elif ( get_dim() == 2 ): axis = axis.upper() if ( axis == "F1" or axis == "F12" ): for i in range(1, get_si2_2d()+1): col(i) dim(1) spec_noise(spec_n) addbase( get_shift()) dim(2) put("col",i) if ( axis == "F2" or axis == "F12" ): for i in range(1, get_si1_2d()+1): row(i) dim(1) spec_noise(spec_n) addbase( get_shift()) dim(2) put("row",i) else: raise Exception( "reste a faire")
#---------------------------------------------------------------------------
[docs]def add_files( list_of_files, list_of_coefficients=[] ): """ add a list of files weighted by the given coefficients if coefficients are lacking, no weighting is made """ list_loc = list_of_files if list_of_coefficients==[]: coef_loc=[1.0]*len(list_loc) else: coef_loc=list_of_coefficients if len(list_loc) != len(coef_loc): raise Exception( "the two lists should be of the same length") # check first read(list_loc.pop()) dloc = get_dim() mult(coef_loc.pop()) put("data") # all the others for i in range(len(coef_loc)): read(list_loc.pop()) if (dloc != get_dim()): raise Exception( "datasets are not all of the same dimension") mult(coef_loc.pop()) adddata() put("data")
#---------------------------------------------------------------------------
[docs]def shear( slope, pivot ): """shearing of a given NMR 2D experiment realized by a frequency shift of all the F1 spectra pivot is the position of the invariant column (0 is left, 1 is right)""" if ( get_dim() != 2 ): raise Exception( "To be applied on 2D only") si = get_si1_2d() sisi = 2*power2(si-2) chsize( sisi, get_si2_2d()) if ( get_itype_2d() == 0 or get_itype_2d() == 1 ): thetype = "real" iftbis("f1") else: thetype = "complex" ift("f1") si2 = get_si2_2d() sw2 = get_specw_2_2d() sw1 = get_specw_1_2d() for i in range(1, si2+1 ): col(i) dim(1) f2 = (i-pivot*si2)*sw2/si2 decal = f2 * si / sw1 coef = -180.0 * decal * slope phase( 0.5*coef, coef ) dim(2) put("col", i) if ( thetype == "real" ): ftbis("f1") else: ft("f1") chsize( si, get_si2_2d())
#---------------------------------------------------------------------------
[docs]def SecsyToCosy(): """shearing operation that transform a "secsy" symmetry type experiment to a "cosy" one """ shear(1.0,0.5)
#---------------------------------------------------------------------------
[docs]def CosyToSecsy(): """shearing operation that transform a "cosy" symmetry type experiment to a "secsy" one """ shear(-1.0,0.5)
#---------------------------------------------------------------------------
[docs]def InadequateToCosy(): """shearing operation that transform a "Inadequate" symmetry type experiment to a "cosy" one """ shear(-1.0,0.5)
#---------------------------------------------------------------------------
[docs]def CosyToInadequate(): """shearing operation that transform a "cosy" symmetry type experiment to a "Inadequate" one """ shear(1.0,0.5)
#--------------------------------------------------------------------------- # Tilting 2D #---------------------------------------------------------------------------
[docs]def tilt( slope, pivot ): """tilt of a 2D experiment realized by a frequency shift of all the F2 spectra pivot is the position of the invariant row (0 is bottom, 1 is top)""" if ( get_dim() != 2 ): raise Exception( "To be applied on 2D only") si = get_si2_2d() sisi = 2*power2(si-2) chsize( get_si1_2d(), sisi ) if ( get_itype_2d() == 0 or get_itype_2d() == 2 ): thetype = "real" iftbis("F2") else: thetype = "complex" ift("F2") si1 = get_si1_2d() sw1 = get_specw_1_2d() sw2 = get_specw_2_2d() for i in range(1, si1+1): row(i) dim(1) f1 = (i - pivot*si1 ) * sw1 / si1 decal = f1 * si / sw2 coef = -180.0 * slope * decal phase( 0.5*coef, coef ) dim(2) put("row", i) if ( thetype == "real" ): ftbis("F2") else: ft("F2") chsize( get_si1_2d(), si )
#---------------------------------------------------------------------------
[docs]def JResTilt(): """tilt operation that transform a JRes experiment to a symmetric one """ tilt(1.0,0.5)
#---------------------------------------------------------------------------
[docs]def Symmetrize2D(type="Cosy",algorithm="mean"): """realize the symmetrization of the current 2D available types are : Inadequate,Cosy, JRes available algorithm are : mean (X+Y)/2 , smallest value min(X,Y), and continuous (XY^2+YX^2)/(X^2 + Y^2) (not for JRes) """ dim(2) toreal("F12") # ensure we have real values if (type.upper()=="COSY"): SymmetrizeCosy(algorithm) elif(type.upper()=="JRES"): SymmetrizeJRes(algorithm) elif (type.upper()=="INADEQUATE"): SymmetrizeInadequate(algorithm)
#---------------------------------------------------------------------------
[docs]def SymmetrizeCosy(algorithm="mean"): """realize the symmetrization of COSY 2D available algorithm are : mean (X+Y)/2 , smallest value min(X,Y), continuous (XY^2+YX^2)/(X^2 + Y^2) """ # temporary zerofill of the smaller axis si1=get_si1_2d() si2=get_si2_2d() if (get_si1_2d() < get_si2_2d()): axe="F1" iftbis("F1") chsize(get_si2_2d(),get_si2_2d()) ftbis("F1") elif (get_si1_2d() > get_si2_2d()): axe="F2" iftbis("F2") chsize(get_si1_2d(),get_si1_2d()) ftbis("F2") else: axe="none" # then apply symmetry in the kernel if (algorithm.upper()=="MEAN"): symetrize(1) elif (algorithm.upper()=="MIN"): symetrize(2) elif (algorithm.upper()=="CONTINUOUS"): symetrize(3) else: raise Exception( "algorithm not available") #then return if (axe != "none"): iftbis(axe) chsize(si1,si2) ftbis(axe)
#---------------------------------------------------------------------------
[docs]def SymmetrizeJRes(algorithm="mean"): """realize the symmetrization of JRes 2D available algorithm are : mean (X+Y)/2 , smallest value min(X,Y) """ put("data") reverse("F1") if (algorithm.upper()=="MEAN"): adddata() mult(0.5) elif (algorithm.upper()=="MIN"): mindata() else: raise Exception( "algorithm not available")
#---------------------------------------------------------------------------
[docs]def SymmetrizeInadequate(algorithm="mean"): """realize the symmetrization of INADEQUATE 2D available algorithm are : mean (X+Y)/2 , smallest value min(X,Y), continuous (XY^2+YX^2)/(X^2 + Y^2) """ InadequateToCosy() SymmetrizeCosy(algorithm) CosyToInadequate()
#---------------------------------------------------------------------------
[docs]def local_proj( axis="F1", algo="M", f1_left=0, f2_left=0, f1_right=0, f2_right=0): """ realize a local projection of the 2D data-set axis : "F1" - "F2" : the axis along which the projection is performed algo : "M" - "S" ; Mean or Skyline f1_left, f2_left, f1_right, f2_right : the coordinates of the local projection O (default) means that the complete data-set will be used, thus: f1_left=1 f2_left=1 f1_right=get_si1_2D(), f2_right=get_si2_2D() thus : local_proj("F1","M") is equivalent to proj("F1","M") WARNING - local_proj("F1") will create a F2 1D. """ if ( get_dim() != 2 ): raise Exception( "To be applied on 2D only") # handle defaut values if f1_left==0 : f1_left=1 if f2_left==0 : f2_left=1 if f1_right==0 : f1_right=get_si1_2d() if f2_right==0 : f2_right=get_si2_2d() if not algo in ("M","S"): raise Exception( "Wrong algorithme for local_proj()") if axis.upper() == "F1": dim(2) # sets 1D buffer row(1) dim(1) zero() put("data") for i in range(f1_left,f1_right+1): dim(2) row(i) dim(1) if (algo.upper()=='M'): adddata() else: maxdata() put("data") dim(1) get("data") extract(f2_left,f2_right) elif axis.upper() == "F2": dim(2) # sets 1D buffer col(1) dim(1) zero() put("data") for i in range(f2_left,f2_right+1): dim(2) col(i) dim(1) if (algo.upper()=='M'): adddata() else: maxdata() put("data") dim(1) get("data") extract(f1_left,f1_right) else: raise Exception( "Wrong axis in local_proj()")
#---------------------------------------------------------------------------
[docs]def local_proj_3d( axis="F1", algo="M", f1_left=0, f2_left=0, f3_left=0, f1_right=0, f2_right=0, f3_right=0): """ realize a local projection of the 3D data-set axis : "F1" - "F2" - "F3": the axis along which the projection is performed algo : "M" - "S" ; Mean or Skyline f1_left, f2_left, f3_lest, f1_right, f2_right, f3_left : the coordinates of the local projection O (default) means that the complete data-set will be used, thus: f1_left=1 f2_left=1 f3_left=1 f1_right=get_si1_3D(), f2_right=get_si2_3D() f3_right=get_si3_3D() """ """ ; proj3d(axis,algo,abs) ; ; axis is F1, F2 or F3 ; algo is M or S ; if abs is Y, absolute value is taken first ; ; equivalent to proj in 3D, but on joined file ; ; see also : proj3d_all PROJ proj_loc JOIN proc3d """ if (get_c_dim()!=3): raise Exception( 'Works only on a JOINed 3D') # handle defaut values if f1_left==0 : f1_left=1 if f2_left==0 : f2_left=1 if f3_left==0 : f3_left=1 if f1_right==0 : f1_right=get_c_sizef1() if f2_right==0 : f2_right=get_c_sizef2() if f3_right==0 : f3_right=get_c_sizef3() si1 = f1_right-f1_left+1 si2 = f2_right-f2_left+1 si3 = f3_right-f3_left+1 dim(2) if (axis == "F1"): (p01, s01, s02) = (f1_left, f2_left, f3_left) # starting points (pn1, sn1, sn2) = (f1_right, f2_right, f3_right) # end points elif (axis == "F2"): (s01, p01, s02) = (f1_left, f2_left, f3_left) # starting points (sn1, pn1, sn2) = (f1_right, f2_right, f3_right) # end points elif (axis == "F3"): (s01, s02, p01) = (f1_left, f2_left, f3_left) # starting points (sn1, sn2, pn1) = (f1_right, f2_right, f3_right) # end points else: raise Exception( "Wrong axis") siz = (pn1-p01+1) # nb of planes dim(2) chsize(sn1-s01+1, sn2-s02+1) if (algo[0] == 'S'): todo = "maxdata()" elif (algo[0] == 'M') : todo = "adddata()" else: raise Exception( "wrong algorithm") try: if (algo[1] == 'A'): tabs = 1 else: tabs = 0 except: tabs = 0 getc(axis, 1, s01, s02, sn1, sn2) if (tabs == 1): itype(0) com_abs() put ("data") for i in range(p01,pn1+1): getc(axis, i, s01, s02, sn1, sn2) if tabs == 1: itype(0) com_abs() eval(todo) put ("data") get ("data") if algo == 'M': mult(1/siz)
#---------------------------------------------------------------------------
[docs]def pkwrite_p(filepeak): """write the content of the peak table in the kernel to a peak file the file is formated as a property list coordinates are in index, widths are in Hz, phases in degrees. format is not fully compatible with the format used in Gifa 5, as the coordinates are ouput in index it will write the 1D, 2D or 3D peak table, depending on get_dim() """ fout = open(filepeak, 'w') pph2 = get_specw_2_2d() / get_si2_2d() ppp2 = pph2 / get_freq_2_2d() pph1 = get_specw_1_2d() / get_si1_2d() ppp1 = pph1 / get_freq_1_2d() if (get_dim() == 1): fout.write("# 1D Peak file, date :"+time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime())+"\n") fout.write("# ID=Freq Amp Amp_err F1_Freq_err F1_Width F1_Width_err F1_phase F1_phase_err F2_Freq_err F2_Width F2_Width_err F2_phase F2_phase_err Type Label\n") for i in range (1, get_npk1d() + 1): fout.write( repr(i) + "=" + repr(geta_pk1d_f(i)) + " " + repr(geta_pk1d_a(i)) + " " + repr(geta_pk1d_a_err(i)) + " " + repr(ppp1*geta_pk1d_f_err(i)) + " " + repr(pph1*geta_pk1d_w(i)) + " " + repr(pph1*geta_pk1d_w_err(i)) + " 0 0 " + repr(geta_pk1d_t(i)) + " " + repr(geta_pk1d_id(i))) fout.write("\n") elif (get_dim() == 2): fout.write("# 2D Peak file, date :"+time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime())+"\n") fout.write("# ID=F1_Freq F2_Freq Amp Amp_err F1_Freq_err F1_Width F1_Width_err F1_phase F1_phase_err F2_Freq_err F2_Width F2_Width_err F2_phase F2_phase_err Type Label\n") for i in range (1, get_npk2d() + 1): fout.write( repr(i) + "=" + repr(geta_pk2d_f1f(i)) + " " + repr(geta_pk2d_f2f(i)) + " " + repr(geta_pk2d_a(i)) + " " + repr(geta_pk2d_a_err(i)) + " " + repr(ppp1*geta_pk2d_f1f_err(i)) + " " + repr(pph1*geta_pk2d_f1w(i)) + " " + repr(pph1*geta_pk2d_f1w_err(i)) + " 0 0 " + repr(ppp2*geta_pk2d_f2f_err(i)) + " " + repr(pph2*geta_pk2d_f2w(i)) + " " + repr(pph2*geta_pk2d_f2w_err(i)) + " 0 0 " + repr(geta_pk2d_t(i)) + " " + repr(geta_pk2d_id(i))) fout.write("\n") elif (get_dim() == 3): fout.close() raise Exception( "reste a faire") fout.close()
#---------------------------------------------------------------------------
[docs]def pkfilter(mode="add",tol=10): """peak filtering first try... """ print(" nbr de pics:", get_npk2d())
#---------------------------------------------------------------------------
[docs]def pksym_p(mode="add",tol=10): """peak symmetrisation algorithm first try... """ if (get_dim() !=2): raise Exception( "works only on 2D data-sets") print(" nbr de pics:", get_npk2d()) t = time.clock() print("----------debut du timer") for i in range (1, get_npk2d() + 1): f1i=geta_pk2d_f1f(i) f2i=geta_pk2d_f2f(i) for j in range (i, get_npk2d() + 1): diff1=f1i-geta_pk2d_f1f(j) diff2=f2i-geta_pk2d_f2f(j) diff = math.sqrt(diff1*diff1/10+diff2*diff2/10) if (diff>10): a=i+j t=time.clock()-t print("----------fin du timer", str(t))
#---------------------------------------------------------------------------
[docs]def peak1d_integ(index,factor=0.1, thresh=0, slope=0.001): """ compute the integration zone around a given 1D peak returns (left,right) as the integration zones left and right are determined as the points were either value gets below thresh (default value 0) determines an absolute stop point value gets below top_of_peak*factor (default value 0.1 = 10%) determines a relative stop point value > lower_point_so_far and abs(value-previous)>top_of_peak*slope (default value 0.001 = 0.1%) allows going up as much as slope*top warning, definitions are different from the integ kernel command """ dim(1) if (index<0 or index>get_si1_1d()): raise Exception( "Wrong index value") toreal() top=val1d(index) level = max(thresh,top*factor) print(level) left=index-1 lval=val1d(left) prev=top while (left>1 and lval>level and (lval-prev)<(slope*top) ): prev=min(lval,prev) # keep lowest value so-far left=left-1 lval=val1d(left) right=index+1 lval=val1d(right) prev=top while (right<get_si1_1d() and lval>level and (lval-prev)<(slope*top) ): prev=min(lval,prev) # keep lowest value so-far right=right+1 lval=val1d(right) return(left,right)
#---------------------------------------------------------------------------
[docs]def spectral_zone(left, right, axis="F1", left_unit="ppm", right_unit="ppm"): """ extract one spectral zone of the spectrum left float the left border of the extract zone, in unit left_unit enum ppm hz index the unit in which spec_zone_left is given right float the right border of the extract zone, in unit right_unit enum ppm hz index the unit in which spec_zone_right is given axis enum F1 F2 F3 if in 2D or 3D, the axis along the extract is to be done, ignored if in 1D returns [left,right] the left and right coordinates of the extracted spectral zone in index """ print(left, right, axis, left_unit, right_unit) if ( get_dim() == 1 ): pass elif ( get_dim() == 2 ): if (axis=="F1"): iaxis=1 si = get_si1_2d() elif (axis=="F2"): iaxis=2 si = get_si2_2d() else: raise Exception( "Error with axis in spectral_zone") if (left_unit == 'ppm'): l = (ptoi(left,2,iaxis)) print("L :",left,"ppm ->",l) elif (left_unit == 'hz'): l = (htoi(left,2,iaxis)) elif (left_unit == 'index'): l = left else: raise Exception( "Error with left unit") if (right_unit == 'ppm'): r = (ptoi(right,2,iaxis)) print("R :",right,"ppm ->",r) elif (right_unit == 'hz'): r = (htoi(right,2,iaxis)) elif (right_unit == 'index'): r = right else: raise Exception( "Error with righ unit") l = int(max(1,round(l))) r = int(min(si,round(r))) if (l > r): raise Exception("Wrong spectral zone coordinates : "+ repr(l) + " " + repr(r)) if ((r-l) < 8): raise Exception( "spectral zone too small") if (l != 1 or r != si): if (axis == "F1"): extract(l, 1, r, get_si2_2d()) elif (axis == "F2"): extract(1, l, get_si1_2d(), r) return (l,r)
#------------------------------------------------------------
[docs]def aparm(): """ computes phase correction form a reconstruction of the beginning of the FID """ if (get_dim() != 1): raise Exception( "aparm works only in 1D") put("data") # keep a copy of the spectrum aside ift() # and compute the fid if (get_si1_1d() > 256): chsize(256) # truncate to the 1st points # zerofill 32 times ft() chsize (32*get_si1_1d()) ift() # extend backward the fid to 2 dwell points print(get_si1_1d()) reverse() burg(get_si1_1d()+64) reverse() # and take modulus modulus() #search for the highest points imax=1;vmax=val1d(1) for i in range(1,64+1): if val1d(i) > vmax: imax=i; vmax=val1d(i) get("data") print("max at",32-(imax-1)/32) ph1 = -360*(imax-1)/64 print("PH1",ph1) phase(0,ph1) ift() ph0 = -(180/math.pi)*math.atan(val1d(2)/val1d(1)) print("PH0",ph0) ft() phase(ph0,0)
#------------------------------------------------------------
[docs]def writet(filename): """ writes the 1D memory as a simple 1D series skip # and ; comments """ try: fout = open(filename,'w') except: raise Exception(filename," cannot be opened") dim(1) fout.write("#text data file, created by NPK :"+time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime())+"\n") fout.write("#dim=1\n") fout.write("#size=%i\n" % get_si1_1d()) fout.write("#itype=%i\n" % get_itype_1d()) fout.write("#frequency=%i\n" % get_freq_1d()) fout.write("#specw=%i\n" % get_specw_1d()) fout.write("#offset=%i\n" % get_offset_1d()) for i in range(get_si1_1d()): fout.write("%f\n" % val1d(i+1)) fout.close()
#------------------------------------------------------------
[docs]def load(filename): """ load in 1D memory a simple 1D series skip # and ; comments """ fin = open(filename) # read file list = [] f=fin.read() lines= f.split("\n") for v in lines: v = v.lstrip() if ( v and (v[0] != '#') and (v[0] != ';')): # skip empty lines and comments list.append(float(v)) fin.close() # copy to 1D buffer dim(1) chsize(len(list)) for i in range(len(list)): setval( i+1,list[i])
#------------------------------------------- # ConfigParser methods directly copied from processing.py (october 11 2011)
[docs]def config_get(config, section, option, default=None, raw=0, vars=None): """read a value from the configuration, with a default value""" if config.has_option(section, option): return config.get(section, option, raw=raw, vars=vars) else: return default
[docs]def config_getint(config, section, option, default=0, raw=0, vars=None): """read a int value from the configuration, with a default value""" return int(config_get(config, section, option, default=default, raw=raw, vars=vars))
[docs]def config_getfloat(config, section, option, default=0.0, raw=0, vars=None): """read a float value from the configuration, with a default value""" return float(config_get(config, section, option, default=default, raw=raw, vars=vars))
[docs]def config_getboolean(config, section, option, default="OFF", raw=0, vars=vars): """read a boolean value from the configuration, with a default value""" v = config_get(config, section, option, default=default, raw=raw, vars=vars) if v.lower() not in ConfigParser.SafeConfigParser._boolean_states: raise (ValueError, 'Not a boolean: %s' % v) return ConfigParser.SafeConfigParser._boolean_states[v.lower()]
#----------------------------------------------
[docs]class Generic_Tests(unittest.TestCase):
[docs] def setUp(self): rootfiles = os.getcwd() cp = ConfigParser.SafeConfigParser() cp.read(rootfiles+"/NPKv1.mscf") self.TestFolder = config_get(cp, "npkv1", "TestFolder") self.fid = os.path.join(self.TestFolder,"fid") self.verbose = 1 # verbose > 0 switches messages on
[docs] def announce(self): if self.verbose > 0: print("\n========", self.shortDescription(), '===============')
[docs] def test_load(self): load(self.fid)
if __name__ == '__main__': unittest.main()