Source code for spike.Interactive.INTER

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

"""
A set of utilities to use spike in NMR or FTMS within jupyter


First version MAD june 2017
preliminary and not fully tested !

"""

from __future__ import print_function, division
import unittest
import sys
import os
import os.path as op
import glob

import matplotlib.pylab as plt
import matplotlib.gridspec as gridspec
from ipywidgets import interact, interactive, fixed, interact_manual, Layout, HBox, VBox, Label, Output, Button
import ipywidgets as widgets
from IPython.display import display, HTML, Javascript
import numpy as np

from ..File.BrukerNMR import Import_1D
from .. import NPKData
try:
    import spike.plugins.bcorr as bcorr
except:
    print('Baseline correction plugins not installed !')

# REACTIVE modify callback behaviour
# True is good for inline mode / False is better for notebook mode
REACTIVE = True
HEAVY = False

[docs]def hidecode(initial='show', message=True): """ this func adds a button to hide/show the code on a jupyter page initial is either 'show' or 'hide' see: https://stackoverflow.com/questions/27934885/how-to-hide-code-from-cells-in-ipython-notebook-visualized-with-nbviewer/28073228#28073228 """ from IPython.display import display, HTML, Markdown if initial == 'show': init = 'false' elif initial == 'hide': init = 'true' if message: msg = "<i>usefull to show/print a clean screen when processing is finished</i>" else: msg = "" display(HTML(''' <style>hr {height: 2px; border: 0;border-top: 1px solid #ccc;margin: 1em 0;padding: 0; }</style> <script> code_show=%s; function code_toggle() { if (code_show){ $('div.input').hide(); } else { $('div.input').show(); } code_show = !code_show } $( document ).ready(code_toggle); </script> <form action="javascript:code_toggle()"> <input type="submit" style="border:1px solid black; background-color:#DDD" value="hide/show the python code."> %s </form>'''%(init, msg)))
[docs]def jsalert(msg): "send a javascript alert" display(Javascript("alert('%s')"%msg))
[docs]class FileChooser: """a simple file chooser for Jupyter - obsolete - not used""" def __init__(self, base=None, filetype=['fid','ser'], mode='r', show=True): if base is None: self.curdir = "/" else: self.curdir = base self.filetype = filetype self.mode = mode self.wfile = widgets.Text(layout=Layout(width='70%'),description='File to load') self.ldir = widgets.Label(value="Chosen dir: "+self.curdir) self.wdir = widgets.Select( options=self.dirlist(), description='Choose Dir', layout=Layout(width='70%')) if mode=='r': self.wchooser = widgets.Select( options=self.filelist(), description='Choose File', layout=Layout(width='70%')) self.wchooser.observe(self.wob) self.wfile.disabled=True # not mofiable in read mode elif mode=="w": self.wfile.description = 'File to create' self.wfile.disabled=False self.wchooser = widgets.Select( options=self.filelist(), description='Files', layout=Layout(width='70%')) else: raise Exception('Only "r" and "w" modes supported') self.wsetdir = Button(description='❯',layout=Layout(width='20%'), button_style='success', # 'success', 'info', 'warning', 'danger' or '' tooltip='descend in directory') self.wup = Button(description='❮',layout=Layout(width='20%'), button_style='success', # 'success', 'info', 'warning', 'danger' or '' tooltip='up to previous directory') self.wsetdir.on_click(self.setdir) self.wup.on_click(self.updir) if show: self.show()
[docs] def filelist(self): fl = [] if self.mode == 'r': if type(self.filetype) is str: fl = glob.glob(op.join(self.curdir,self.filetype)) elif type(self.filetype) in (tuple, list): for f in self.filetype: fl += glob.glob(op.join(self.curdir,f)) else: raise Exception('TypeError, filetype should be either a string or a list') else: # 'w' fl = [f for f in glob.glob(op.join(self.curdir,'*')) if op.isfile(f)] self.wfile.value = op.join(self.curdir,self.filetype) if fl == []: fl = [" "] return fl
[docs] def dirlist(self): base = self.curdir return [d for d in glob.glob(op.join(base,'*')) if (op.isdir(d) and not d.endswith('__pycache__'))]
[docs] def wob(self, e): self.wfile.value = self.wchooser.value
[docs] def updir(self, e): self.curdir = op.dirname(self.curdir) self.ldir.value = "Chosen dir: "+self.curdir self.wdir.options = self.dirlist() self.wchooser.options = self.filelist()
[docs] def setdir(self, e): self.curdir = self.wdir.value self.ldir.value = "Chosen dir: "+self.curdir self.wdir.options = self.dirlist() self.wchooser.options = self.filelist()
[docs] def show(self): display(VBox( [ self.ldir, HBox( [self.wdir, VBox([self.wup,self.wsetdir])] ), self.wchooser, self.wfile ]) ) return self
@property def file(self): "the chosen complete filename" return self.wfile.value @property def dirname(self): "the final dirname containing the chosen file" if op.isdir(self.wfile.value): return op.basename(self.wfile.value) else: return op.basename(op.dirname(self.wfile.value)) @property def nmrname(self): "the final dirname containing the chosen file for TopSpin files" if op.isdir(self.wfile.value): return op.join( op.basename(op.dirname(self.wfile.value)), self.dirname) else: return op.join( op.basename(op.dirname(op.dirname(self.wfile.value))), self.dirname) @property def basename(self): "the basename of the chosen file" return op.basename(self.wfile.value)
[docs]class Show1D(object): """ An interactive display, 1D NMR Show1D(spectrum) to be developped for peaks and integrals """ def __init__(self, data, title=None, figsize=None): self.data = data self.title = title if figsize is None: figsize = (10,5) self.done = Button(description="Done", button_style='success',layout=Layout(width='10%')) self.scale = widgets.FloatSlider(description='scale:', value=1.0, min=1.0, max=100, step=0.1, layout=Layout(width='50%'), continuous_update=REACTIVE) for widg in (self.scale,): widg.observe(self.ob) fi,ax = plt.subplots(figsize=figsize) self.ax = ax self.data.display(figure=self.ax, title=self.title) self.xb = self.ax.get_xbound() self.done.on_click(self.on_done) self.Box = HBox([self.scale, self.done]) display( self.Box )
[docs] def on_done(self, b): self.close()
[docs] def close(self): for w in [ self.Box, self.done, self.scale]: w.close()
[docs] def ob(self, event): "observe events and display" if event['name']=='value': self.disp()
[docs] def disp(self): self.xb = self.ax.get_xbound() self.ax.clear() self.data.display(scale=self.scale.value, new_fig=False, figure=self.ax, title=self.title) self.ax.set_xbound(self.xb)
[docs]class baseline1D(Show1D): def __init__(self, data, figsize=None): super().__init__( data, figsize=figsize) self.data.real() ppos = self.data.axis1.itop(self.data.axis1.size/2) #self.ax.plot([ppos,ppos], self.ax.get_ybound()) self.select = widgets.FloatSlider(description='select:', min=0.0, max=1.0, step=0.002, layout=Layout(width='100%'), value=0.5, readout=False, continuous_update=REACTIVE) self.selfine = widgets.FloatSlider(description='fine:', min=0.0, max=1.0, step=0.01, layout=Layout(width='70%'), value=0.5, readout=False, continuous_update=REACTIVE) self.bsl_points = [] for w in [self.select, self.selfine]: w.observe(self.ob) bsize = '15%' # self.apply = widgets.Button(description="Apply", button_style='success', layout=Layout(width=2*bsize)) # self.apply.on_click(self.on_apply) self.done.description = 'Apply' self.cancel = widgets.Button(description="Abort", button_style='warning', layout=Layout(width=2*bsize)) self.cancel.on_click(self.on_cancel) self.Box.add_class("hidden") self.auto = widgets.Button(description="auto", button_style='success', layout=Layout(width=bsize)) self.auto.on_click(self.on_auto) self.set = widgets.Button(description="add", button_style='success', layout=Layout(width=bsize)) self.set.on_click(self.on_set) self.unset = widgets.Button(description="rem", button_style='warning', layout=Layout(width=bsize)) self.unset.on_click(self.on_unset) self.toshow = widgets.Dropdown( options=['baseline', 'corrected', 'points'], description='Display:') self.toshow.observe(self.ob) self.Box = HBox([self.scale, self.done,self.cancel]) display(self.Box) display( HBox( [ VBox([self.select, self.selfine], layout=Layout(width='50%')), VBox([ HBox([self.set, self.auto, self.toshow], layout=Layout(width='100%')), self.unset ], layout=Layout(width='50%')) ], layout=Layout(width='100%')) ) self.disp()
[docs] def close(self): for w in [ self.select, self.selfine, self.auto, self.set, self.unset, self.cancel, self.toshow]: w.close() super().close()
[docs] def on_done(self, e): print('Applied correction:\n',self.bsl_points) self.data.set_buffer( self.data.get_buffer() - self.correction() ) super().disp() self.close()
[docs] def on_auto(self, e): "automatically set baseline points" self.bsl_points = [self.data.axis1.itop(x) for x in bcorr.autopoints(self.data)] self.disp()
[docs] def on_cancel(self, e): self.close() self.ax.clear() self.data.display(new_fig=False, figure=self.ax)
[docs] def on_set(self, e): "add baseline points at selector" self.bsl_points.append( self.selpos() ) self.selfine.value = 0.5 self.disp()
[docs] def on_unset(self, e): "remove baseline points closest from selector" here = self.selpos() distclose = np.inf pclose = np.NaN for i,p in enumerate(self.bsl_points): if abs(p-here)< distclose: pclose = p distclose = abs(p-here) self.bsl_points.remove(pclose) self.disp()
[docs] def selpos(self): "returns selector pos in ppm" pos = self.select.value + self.selfine.value/100 return (1-pos)*(self.data.axis1.itop(0)-self.data.axis1.itop(self.data.size1))+self.data.axis1.itop(self.data.size1)
[docs] def correction(self): "returns the correction to apply as a numpy array" ibsl_points = [int(self.data.axis1.ptoi(x)) for x in self.bsl_points] x = np.arange(self.data.size1) if len(self.bsl_points) == 1 : value = self.data[ibsl_points[0]] * np.ones( self.data.size1 ) elif len(self.bsl_points) < 4 : corr = bcorr._linear_interpolate(self.data.get_buffer(), ibsl_points) value = corr(x) else: corr = bcorr._spline_interpolate(self.data.get_buffer(), ibsl_points) value = corr(x) return value
[docs] def corrected(self): value = self.data.copy() value.set_buffer( value.get_buffer() - self.correction() ) return value
[docs] def disp(self): self.xb = self.ax.get_xbound() super().disp() if len(self.bsl_points)>0: if self.toshow.value == 'baseline': ( self.data.copy()-self.corrected() ).display(new_fig=False, figure=self.ax, color='r') elif self.toshow.value == 'corrected': self.ax.clear() self.corrected().display(new_fig=False, figure=self.ax, color='r', scale=self.scale.value) ppos = self.selpos() self.ax.plot([ppos,ppos], self.ax.get_ybound())# [0,self.data.absmax/self.scale.value]) y = [] for point in self.bsl_points: if self.toshow.value == 'corrected': y.append(0) else: loc = int(self.data.axis1.ptoi(point)) y.append(self.data[loc]) if y: self.ax.scatter(self.bsl_points, y, c='r', marker='o') self.ax.set_xbound(self.xb)
[docs]class Show1Dplus(Show1D): def __init__(self, data, figsize=None, title=None): super().__init__( data, figsize=figsize, title=title) self.scaleint = widgets.FloatSlider(value=0.5, min=0.1, max=10, step=0.05, layout=Layout(width='20%'), continuous_update=REACTIVE) self.offset = widgets.FloatSlider(value=0.3, min=0.0, max=1.0, step=0.01, layout=Layout(width='20%'), continuous_update=REACTIVE) self.peaks = widgets.Checkbox(value=False, layout=Layout(width='15%')) self.integ = widgets.Checkbox(value=False, layout=Layout(width='15%')) for widg in (self.scaleint, self.offset, self.peaks, self.integ): widg.observe(self.ob) self.fullBox = VBox([ HBox([Label('Integral scale:'),self.scaleint,Label('offset:'),self.offset]), HBox([Label('Show Peaks'),self.peaks,Label('integrals'),self.integ]) ]) display(self.fullBox)
[docs] def on_done(self, e): self.fullBox.close() super().close()
[docs] def disp(self): self.xb = self.ax.get_xbound() self.ax.clear() self.data.display(scale=self.scale.value, new_fig=False, figure=self.ax, title=self.title) if self.integ.value: try: self.data.display_integral(label=True, integscale=self.scaleint.value, integoff=self.offset.value, figure=self.ax) except: print('no or wrong integrals') pass if self.peaks.value: try: self.data.display_peaks(peak_label=True, figure=self.ax, scale=self.scale.value) except: print('no or wrong peaklist') pass self.ax.set_xbound(self.xb)
[docs]class baseline2D_F2(baseline1D): def __init__(self, data, figsize=None): self.data2D = data super().__init__( self.data2D.projF2, figsize=figsize)
[docs] def on_done(self, e): super().on_done(e) ibsl_points = [int(self.data2D.axis2.ptoi(x)) for x in self.bsl_points] self.data2D.bcorr(method='spline', xpoints=ibsl_points)
[docs]class Show2D(object): """ A display for 2D NMR with a scale cursor Show2D(spectrum) where spectrum is a NPKData object - special display for DOSY. """ def __init__(self, data, title=None, figsize=None): self.data = data self.isDOSY = isinstance(data.axis1, NPKData.LaplaceAxis) try: self.proj2 = data.projF2 except: self.proj2 = data.proj(axis=2).real() try: self.proj1 = data.projF1 except: self.proj1 = data.proj(axis=1).real() self.title = title self.scale = widgets.FloatLogSlider(description='scale:', value=1.0, min=-1, max=3, base=10, step=0.01, layout=Layout(width='80%'), continuous_update=HEAVY) self.posview = widgets.Checkbox(value=True,description='Positive') self.negview = widgets.Checkbox(value=False,description='Negative') for w in (self.scale, self.posview, self.negview): w.observe(self.ob) grid = {'height_ratios':[1,4],'hspace':0,'wspace':0} if self.isDOSY: fsize = (10,5) grid['width_ratios']=[7,1] else: fsize = (8,8) grid['width_ratios']=[4,1] # fig, self.axarr = plt.subplots(2, 1, sharex=True, figsize=fsize, gridspec_kw=grid) fig = plt.figure(figsize=fsize, constrained_layout=False) spec2 = gridspec.GridSpec(ncols=2, nrows=2, figure=fig, **grid) axarr = np.empty((2,2), dtype=object) axarr[0,0] = fig.add_subplot(spec2[0, 0]) axarr[1,0] = fig.add_subplot(spec2[1, 0],sharex=axarr[0, 0]) axarr[1,1] = fig.add_subplot(spec2[1, 1],sharey=axarr[1, 0]) self.top_ax = axarr[0,0] self.spec_ax = axarr[1,0] self.side_ax = axarr[1,1] self.Box = HBox( [self.scale, self.posview, self.negview]) display( self.Box ) self.disp(new=True)
[docs] def on_done(self, b): self.scale.close()
[docs] def ob(self, event): "observe events and display" if event['name'] != 'value': return self.disp()
[docs] def disp(self,new=False): if new: self.proj2.display(figure=self.top_ax, title=self.title) xb = self.top_ax.get_xbound() dataxis = self.proj1.axis1.itoc( self.proj1.axis1.points_axis() ) self.side_ax.plot(self.proj1.get_buffer(),dataxis) yb = self.side_ax.get_ybound() else: yb = self.side_ax.get_ybound() xb = self.top_ax.get_xbound() self.spec_ax.clear() if self.posview.value: self.data.display(scale=self.scale.value, new_fig=False, figure=self.spec_ax) if self.negview.value: self.data.display(scale=-self.scale.value, new_fig=False, figure=self.spec_ax, mpldic={'cmap':'Wistia'}) self.spec_ax.set_xbound(xb) self.spec_ax.set_ybound(yb)
[docs]class Phaser1D(object): """ An interactive phaser in 1D NMR Phaser1D(spectrum) best when in %matplotlib inline """ def __init__(self, data): self.scale = widgets.FloatSlider(description='scale:', min=1, max=100, step=0.5, layout=Layout(width='30%'), continuous_update=REACTIVE) self.p0 = widgets.FloatSlider(description='P0:',min=-180, max=180, step=0.1, layout=Layout(width='100%'), continuous_update=REACTIVE) self.p1 = widgets.FloatSlider(description='P1:',min=-360, max=360, step=1.0, layout=Layout(width='100%'), continuous_update=REACTIVE) self.pivot = widgets.FloatSlider(description='pivot:', min=0.0, max=1.0, step=0.01, layout=Layout(width='30%'), value=0.5, readout=False, continuous_update=REACTIVE) for w in [self.p0, self.p1, self.scale, self.pivot]: w.observe(self.ob) self.button = widgets.Button(description="Ok", button_style='success') self.button.on_click(self.on_Apply) self.cancel = widgets.Button(description="Cancel", button_style='warning') self.cancel.on_click(self.on_cancel) display( VBox([ HBox([self.button, self.cancel]), HBox([self.scale, self.pivot]), self.p0, self.p1]) ) fi,ax = plt.subplots() self.ax = ax self.data = data self.data.display(figure=self.ax) ppos = self.data.axis1.itop(self.data.axis1.size/2) self.ax.plot([ppos,ppos], self.ax.get_ybound()) self.xb = self.ax.get_xbound() # initialize zoom
[docs] def close_all(self): for w in [self.p0, self.p1, self.scale, self.button, self.cancel, self.pivot]: w.close()
[docs] def on_cancel(self, b): self.close_all() self.ax.clear() self.data.display(new_fig=False, figure=self.ax)
[docs] def on_Apply(self, b): lp0, lp1 = self.ppivot() # get centered values if lp0 != 0 or lp1 != 0: print("Applied: phase(%.1f, %.1f)"%(lp0, lp1)) self.data.phase(lp0, lp1).display(new_fig=False, figure=self.ax) else: print("no applied phase") self.close_all()
# self.ax.clear()
[docs] def ppivot(self): "converts from pivot values to centered ones" pp = 1.0-self.pivot.value return (self.p0.value + (pp-0.5)*self.p1.value, self.p1.value)
[docs] def ob(self, event): "observe changes and start phasing" if event['name']=='value': self.phase()
[docs] def phase(self): "apply phase and display" self.xb = self.ax.get_xbound() # get current zoom self.ax.clear() lp0, lp1 = self.ppivot() # get centered values self.data.copy().phase(lp0, lp1).display(scale=self.scale.value, new_fig=False, figure=self.ax) ppos = (1-self.pivot.value)*(self.data.axis1.itop(0)-self.data.axis1.itop(self.data.size1))+self.data.axis1.itop(self.data.size1) self.ax.plot([ppos,ppos], self.ax.get_ybound()) self.ax.set_xbound( self.xb )
#z = self.zm #self.ax.set_xlim(left=z[0], right=z[1] )
[docs]class Phaser2D(object): """ An interactive phaser in 2D NMR Phaser2D(spec) best when in %matplotlib inline """ def __init__(self, data): self.data = data self.scale = widgets.FloatLogSlider(description='scale:', value=1.0, min=-1, max=2, base=10, step=0.01, layout=Layout(width='80%'), continuous_update=HEAVY) self.F1p0 = widgets.FloatSlider(min=-180, max=180, step=0.1, description='F1 p0',continuous_update=HEAVY) self.F1p1 = widgets.FloatSlider(min=-250, max=250, step=1.0, description='F1 p1',continuous_update=HEAVY) self.F2p0 = widgets.FloatSlider(min=-180, max=180, step=0.1, description='F2 p0',continuous_update=HEAVY) self.F2p1 = widgets.FloatSlider(min=-250, max=250, step=1.0, description='F2 p1',continuous_update=HEAVY) for w in [self.F1p0, self.F1p1, self.F2p0, self.F2p1, self.scale]: w.observe(self.ob) self.button = widgets.Button(description="Apply correction",button_style='success') self.button.on_click(self.on_Apply) self.cancel = widgets.Button(description="Cancel",button_style='warning') self.cancel.on_click(self.on_cancel) # interact(self.phase, scale=self.scale, F1p0=self.F1p0, F1p1=self.F1p1, F2p0=self.F2p0, F2p1=self.F2p1) display(VBox([self.scale, HBox([VBox([self.F1p0, self.F1p1], layout=Layout(width='40%')), VBox([self.F2p0, self.F2p1], layout=Layout(width='40%'))], layout=Layout(width='80%')) ], layout=Layout(width='100%'))) display(HBox([self.button, self.cancel])) fi,ax = plt.subplots() self.ax = ax self.display() #self.data.display(figure=self.ax)
[docs] def ob(self, event): "observe changes and start phasing" if event['name']=='value': self.phase()
[docs] def close(self): for w in [self.F1p0, self.F1p1, self.F2p0, self.F2p1, self.scale, self.button, self.cancel]: w.close()
[docs] def on_cancel(self, b): print("No action") self.ax.clear() self.data.display(figure=self.ax,scale=self.scale.value) self.ax.set_xlim(xmin=self.data.axis2.itop(0), xmax=self.data.axis2.itop(self.data.size2)) self.ax.set_ylim(ymin=self.data.axis1.itop(0), ymax=self.data.axis1.itop(self.data.size1)) self.close()
[docs] def on_Apply(self, b): print("Applied: phase(%.1f,%.1f,axis='F1').phase(%.1f,%.1f,axis='F')"%(self.F1p0.value, self.F1p1.value, self.F2p0.value, self.F2p1.value)) self.data.phase(self.F2p0.value, self.F2p1.value, axis='F2').phase(self.F1p0.value, self.F1p1.value, axis='F1') self.data.display(figure=self.ax,scale=self.scale.value) self.ax.set_xlim(xmin=self.data.axis2.itop(0), xmax=self.data.axis2.itop(self.data.size2)) self.ax.set_ylim(ymin=self.data.axis1.itop(0), ymax=self.data.axis1.itop(self.data.size1)) self.close()
[docs] def display(self,todisplay=None): "display either the current data or the one provided - red and blue" self.ax.clear() if not todisplay: todisplay = self.data todisplay.display(scale=self.scale.value, new_fig=False, figure=self.ax,color='blue') todisplay.display(scale=-self.scale.value, new_fig=False, figure=self.ax, color='red') self.ax.set_xlim(xmin=self.data.axis2.itop(0), xmax=self.data.axis2.itop(self.data.size2)) self.ax.set_ylim(ymin=self.data.axis1.itop(0), ymax=self.data.axis1.itop(self.data.size1))
[docs] def phase(self): "compute phase and display" dp = self.data.copy().phase(self.F2p0.value, self.F2p1.value, axis='F2').phase(self.F1p0.value, self.F1p1.value, axis='F1') self.display(dp)
# def phase(self, scale, F1p0, F1p1, F2p0, F2p1): # self.data.copy().phase(F1p0,F1p1,axis='F1').phase(F2p0,F2p1,axis='F2').display(scale=scale);
[docs]class AvProc1D: "Detailed 1D NMR Processing" def __init__(self, filename=""): self.wfile = widgets.Text(description='File to process',layout=Layout(width='80%'), value=filename) self.wapod = widgets.Dropdown( options=['None', 'apod_sin (sine bell)', 'apod_em (Exponential)', 'apod_gm (Gaussian)', 'gaussenh (Gaussian Enhacement)', 'kaiser'], value='apod_sin (sine bell)', description='Apodisation') self.wpapod_Hz = widgets.FloatText( value=1.0, min=0, # max exponent of base max=30, # min exponent of base description='Width in Hz', layout=Layout(width='15%'), disabled = True) self.wpapod_enh = widgets.FloatText( value=2.0, min=0.0, # max exponent of base max=5.0, # min exponent of base description='strength', layout=Layout(width='15%'), step=1, disabled = True) self.wpapod_sin = widgets.FloatText( value=0.0, min=0, # max exponent of base max=0.5, # min exponent of base description='bell shape', layout=Layout(width='15%'), step=0.01, tooltip='value is the maximum of the bell, 0 is pure cosine, 0.5 is pure sine', disabled = False) self.wzf = widgets.Dropdown( options=[0, 1, 2, 4, 8], value=1, description='Zero-Filling') self.wphase0 = widgets.FloatText( value=0, description='Phase : P0', layout=Layout(width='20%'), disabled = True) self.wphase1 = widgets.FloatText( value=0, description='P1', layout=Layout(width='20%'), disabled = True) self.wapmin = widgets.Checkbox( value=True, description='AutoPhasing', tooltip='Perform AutoPhasing') self.wapmin.observe(self.apmin_select) self.wbcorr = widgets.Checkbox( value=False, description='Baseline Correction', tooltip='Perform AutoPhasing') self.wapod.observe(self.apod_select) self.bapod = widgets.Button(description='Show effect on FID') self.bapod.on_click(self.show_apod) self.bdoit = widgets.Button(description='Process') self.bdoit.on_click(self.process) self.show() fi,ax = plt.subplots() self.ax = ax if os.path.exists(filename): self.load() #self.data.set_unit('sec') self.display()
[docs] def apod_select(self, e): test = self.wapod.value.split()[0] self.wpapod_sin.disabled = True self.wpapod_Hz.disabled = True self.wpapod_enh.disabled = True if test == "apod_sin": self.wpapod_sin.disabled = False if test in ('apod_em', 'apod_gm','gaussenh'): self.wpapod_Hz.disabled = False if test == 'gaussenh': self.wpapod_enh.disabled = False
[docs] def apmin_select(self, e): for w in self.wphase0, self.wphase1: w.disabled = self.wapmin.value
[docs] def load(self): self.data = Import_1D(self.wfile.value)
[docs] def apod(self): func = self.wapod.value.split()[0] todo = None if func == 'apod_sin': todo = 'self.data.apod_sin(%f)'%(self.wpapod_sin.value,) elif func in ('apod_em', 'apod_gm'): todo = 'self.data.%s(%f)'%(func, self.wpapod_Hz.value) elif func == 'gaussenh': todo = 'self.data.gaussenh(%f,enhancement=%f)'%(self.wpapod_Hz.value, self.wpapod_enh.value) if todo is not None: eval(todo) return self.data
[docs] def show_apod(self, e): self.load() self.apod() self.display()
[docs] def process(self, e): self.load() self.apod().zf(self.wzf.value).ft_sim().bk_corr().set_unit('ppm') if self.wapmin.value: self.data.apmin() self.wphase0.value = round(self.data.axis1.P0,1) self.wphase1.value = self.data.axis1.P1 else: self.data.phase(self.wphase0.value, self.wphase1.value) self.display()
[docs] def display(self): self.ax.clear() self.data.display(figure=self.ax)
[docs] def show(self): display( VBox([self.wfile, HBox([self.wapod, self.wpapod_sin, self.wpapod_Hz, self.wpapod_enh, self.bapod]), self.wzf, HBox([self.wapmin, self.wphase0, self.wphase1]), # self.wbcorr, self.bdoit]) )
[docs]class NMRPeaker1D(Show1D): "a peak-picker for NMR experiments" def __init__(self, data, figsize=None): super().__init__( data, figsize=figsize) self.Box.add_class("hidden") self.data = data.real() self.thresh = widgets.FloatLogSlider(value=20.0, min=-1, max=2.0, base=10, step=0.01, layout=Layout(width='30%'), continuous_update=False, readout=True, readout_format='.2f') self.thresh.observe(self.pickpeak) self.peak_mode = widgets.Dropdown(options=['marker', 'bar'],value='marker',description='show as') self.peak_mode.observe(self.ob) self.bprint = widgets.Button(description="Print", layout=Layout(width='10%'), button_style='success', # 'success', 'info', 'warning', 'danger' or '' tooltip='Print to screen') self.bprint.on_click(self.pkprint) self.out = Output(layout={'border': '1px solid red'}) self.done = widgets.Button(description="Ok", button_style='success') self.done.on_click(self.on_done) self.cancel = widgets.Button(description="Cancel", button_style='warning') self.cancel.on_click(self.on_cancel) self.Box = HBox([self.done,self.cancel]) self.Box2 = VBox([self.Box, HBox([Label('threshold - % largest signal'), self.thresh, self.peak_mode, self.bprint] ) ]) display(self.Box2 ) display(self.out ) self.pp() self.display()
[docs] def on_cancel(self, b): self.Box2.close() self.out.close() del self.data.peaks self.ax.clear() self.data.display(new_fig=False, figure=self.ax)
[docs] def on_done(self, b): pkm = self.peak_mode.value self.Box2.close() self.ax.clear() self.data.display(figure=self.ax ) self.data.display_peaks(peak_mode=pkm,figure=self.ax ) self.data.mplfigure.annotate('%d peaks detected'%len(self.data.peaks) ,(0.05,0.95), xycoords='figure fraction')
[docs] def pkprint(self,event): self.out.clear_output(wait=True) with self.out: display(HTML(self.data.pk2pandas().to_html()))
def _pkprint(self,event): self.out.clear_output(wait=True) with self.out: print(self.pklist())
[docs] def pklist(self): "creates peaklist for printing or exporting" text = ["ppm\tInt.(%)\twidth (Hz)"] data = self.data intmax = max(data.peaks.intens)/100 for pk in data.peaks: ppm = data.axis1.itop(pk.pos) width = 2*pk.width*data.axis1.specwidth/data.size1 l = "%.3f\t%.1f\t%.2f"%(ppm, pk.intens/intmax, width) text.append(l) return "\n".join(text)
[docs] def ob(self, event): if event['name']=='value': self.display()
[docs] def display(self): "interactive wrapper to peakpick" self.xb = self.ax.get_xbound() self.yb = self.ax.get_ybound() super().disp() x = [self.data.axis1.itoc(z) for z in (0, self.data.size1) ] y = [self.data.absmax*self.thresh.value/100]*2 self.ax.plot(x,y,':r') try: self.data.display_peaks(peak_label=True, peak_mode=self.peak_mode.value, figure=self.ax) except: pass self.ax.set_xbound(self.xb) self.ax.set_ybound(self.yb)
[docs] def pickpeak(self, event): "interactive wrapper to peakpick" if event['name']=='value': self.pp()
[docs] def pp(self): "do the peak-picking calling pp().centroid()" #self.spec.clear_output(wait=True) th = self.data.absmax*self.thresh.value/100 zm = None self.data.set_unit('ppm').peakpick(threshold=th, verbose=False, zoom=zm).centroid() self.display() self.ax.annotate('%d peaks detected'%len(self.data.peaks) ,(0.05,0.95), xycoords='figure fraction')
def _pp(self): "do the peak-picking calling pp().centroid()" self.ax.clear() self.data.set_unit('m/z').peakpick(autothresh=self.thresh.value, verbose=False).centroid() self.data.display(new_fig=False, figure=self.ax) x = [self.data.axis1.lowmass, self.data.axis1.highmass] y = [self.data.peaks.threshold]*2 self.ax.plot(x,y,':r') self.data.display_peaks(peak_label=True, figure=self.ax) self.ax.annotate('%d peaks detected'%len(self.data.peaks) ,(0.05,0.95), xycoords='figure fraction')
[docs]class NMRIntegrate(object): "an integrator for NMR experiments" def __init__(self, npkd): self.npkd = npkd.real().integrate() self.bias = widgets.FloatSlider( description='bias', layout=Layout(width='30%'), value=0.0,min=-10.0, max=10.0, step=0.1, continuous_update=True, readout=True, readout_format='.1f') self.sep = widgets.FloatSlider( description='peak separation', layout=Layout(width='30%'), value=3.0,min=0.0, max=10.0, step=0.1, continuous_update=True, readout=False, readout_format='.1f') self.wings = widgets.FloatSlider( description='width', layout=Layout(width='30%'), value=5.0,min=0.5, max=10.0, step=0.1, continuous_update=True, readout=False, readout_format='.1f') self.bias.observe(self.integrate) self.sep.observe(self.integrate) self.wings.observe(self.integrate) self.Ok = widgets.Button(description="Ok", button_style='success') self.Ok.on_click(self.on_Apply) self.cancel = widgets.Button(description="Cancel", button_style='warning') self.cancel.on_click(self.on_cancel) self.bprint = widgets.Button(description="Print", layout=Layout(width='10%'), button_style='success', # 'success', 'info', 'warning', 'danger' or '' tooltip='Print to screen') self.bprint.on_click(self.print) self.entry = widgets.IntText(value=0,description='Entry',min=0,layout=Layout(width='15%')) self.value = widgets.FloatText(value=100,description='Value',layout=Layout(width='15%')) self.set = widgets.Button(description="Set", button_style='success', layout=Layout(width='7%')) self.set.on_click(self.set_value) self.out = Output(layout={'border': '1px solid red'}) self.Box = VBox([ HBox([self.Ok, self.cancel]), HBox([self.bias, self.sep, self.wings,] ), HBox([self.entry, self.value, self.set, self.bprint] ),]) display( self.Box) self.fig, self.ax = plt.subplots() self.npkd.display(figure=self.ax) display( self.out) self.int() self.display()
[docs] def on_cancel(self, b): self.Box.close() self.out.close() self.ax.clear() self.npkd.display(figure=self.ax)
[docs] def on_Apply(self, b): self.Box.close() self.ax.clear() self.npkd.display(figure=self.ax) self.npkd.display_integral(label=True, figure=self.ax, labelyposition=0.01, regions=False)
[docs] def set_value(self,b): self.npkd.integral_calibrate(self.entry.value, self.value.value) self.display()
[docs] def print(self,event): self.out.clear_output(wait=True) with self.out: display(HTML( self.npkd.integrals.to_pandas().to_html() ))
[docs] def integrate(self, event): "integrate from event" if event['name']=='value': self.int()
[docs] def int(self): "do the integration" try: calib = self.npkd.integrals.calibration except: calib = None self.npkd.set_unit('ppm').integrate(separation=self.sep.value, wings=self.wings.value, bias=self.npkd.absmax*self.bias.value/100) self.npkd.integrals.calibrate(calibration=calib) self.display()
[docs] def ob(self, event): if event['name']=='value': self.display()
[docs] def display(self): "refresh display from event" self.xb = self.ax.get_xbound() self.yb = self.ax.get_ybound() self.ax.clear() self.npkd.display(new_fig=False, figure=self.ax) try: self.npkd.display_integral(label=True, figure=self.ax, labelyposition=0.01, regions=False) except: pass self.ax.set_xbound(self.xb) self.ax.set_ybound(self.yb)
#if __name__ == '__main__': # unittest.main()