X-Git-Url: http://git.tremily.us/?p=hooke.git;a=blobdiff_plain;f=hooke%2Fplugin%2Fflatfilts.py;fp=flatfilts.py;h=e19964c71a2dfd01c8f710916402a16e35a024a2;hp=0843481310c67c2bc3d546e5306d7ee5b2917fe7;hb=41ef0130e16c0cf8d2c0f1acc9e06986d62f7607;hpb=7fc996abaf986c43c0354ac3b4127ed7876ad41a diff --git a/flatfilts.py b/hooke/plugin/flatfilts.py old mode 100755 new mode 100644 similarity index 90% rename from flatfilts.py rename to hooke/plugin/flatfilts.py index 0843481..e19964c --- a/flatfilts.py +++ b/hooke/plugin/flatfilts.py @@ -10,37 +10,29 @@ Licensed under the GNU LGPL version 2 Other plugin dependencies: procplots.py (plot processing plugin) ''' -from libhooke import WX_GOOD + +from hooke.libhooke import WX_GOOD + import wxversion wxversion.select(WX_GOOD) - import xml.dom.minidom - import wx import scipy import numpy from numpy import diff - #import pickle -import libpeakspot as lps -import libhookecurve as lhc +from .. import libpeakspot as lps +from .. import libhookecurve as lhc -class flatfiltsCommands: - +class flatfiltsCommands(object): + def _plug_init(self): #configurate convfilt variables convfilt_configurator=ConvfiltConfig() - - #different OSes have different path conventions - if self.config['hookedir'][0]=='/': - slash='/' #a Unix or Unix-like system - else: - slash='\\' #it's a drive letter, we assume it's Windows - - self.convfilt_config=convfilt_configurator.load_config(self.config['hookedir']+slash+'convfilt.conf') - + self.convfilt_config=convfilt_configurator.load_config('convfilt.conf') + def do_flatfilt(self,args): ''' FLATFILT @@ -64,33 +56,33 @@ class flatfiltsCommands: median_filter=7 min_npks=4 min_deviation=9 - + args=args.split(' ') if len(args) == 2: min_npks=int(args[0]) min_deviation=int(args[1]) else: pass - + print 'Processing playlist...' notflat_list=[] - + c=0 for item in self.current_list: c+=1 - + try: notflat=self.has_features(item, median_filter, min_npks, min_deviation) print 'Curve',item.path, 'is',c,'of',len(self.current_list),': features are ',notflat except: notflat=False print 'Curve',item.path, 'is',c,'of',len(self.current_list),': cannot be filtered. Probably unable to retrieve force data from corrupt file.' - + if notflat: item.features=notflat item.curve=None #empty the item object, to further avoid memory leak notflat_list.append(item) - + if len(notflat_list)==0: print 'Found nothing interesting. Check your playlist, could be a bug or criteria could be too much stringent' return @@ -101,28 +93,28 @@ class flatfiltsCommands: self.current_list=notflat_list self.current=self.current_list[self.pointer] self.do_plot(0) - + def has_features(self,item,median_filter,min_npks,min_deviation): ''' decides if a curve is flat enough to be rejected from analysis: it sees if there are at least min_npks points that are higher than min_deviation times the absolute value of noise. - + Algorithm original idea by Francesco Musiani, with my tweaks and corrections. ''' retvalue=False - - item.identify(self.drivers) + + item.identify(self.drivers) #we assume the first is the plot with the force curve #do the median to better resolve features from noise flat_plot=self.plotmanip_median(item.curve.default_plots()[0], item, customvalue=median_filter) - flat_vects=flat_plot.vectors + flat_vects=flat_plot.vectors item.curve.close_all() #needed to avoid *big* memory leaks! del item.curve del item - - #absolute value of derivate + + #absolute value of derivate yretdiff=diff(flat_vects[1][1]) yretdiff=[abs(value) for value in yretdiff] #average of derivate values @@ -135,12 +127,12 @@ class flatfiltsCommands: c_pks+=1 else: break - + if c_pks>=min_npks: retvalue = c_pks - + del flat_plot, flat_vects, yretdiff - + return retvalue ################################################################ @@ -155,13 +147,13 @@ class flatfiltsCommands: ''' if abs_devs==None: abs_devs=self.convfilt_config['mindeviation'] - - + + xret=plot.vectors[1][0] yret=plot.vectors[1][1] #Calculate convolution. convoluted=lps.conv_dx(yret, self.convfilt_config['convolution']) - + #surely cut everything before the contact point cut_index=self.find_contact_point(plot) #cut even more, before the blind window @@ -173,8 +165,8 @@ class flatfiltsCommands: blind_index+=1 cut_index+=blind_index #do the dirty convolution-peak finding stuff - noise_level=lps.noise_absdev(convoluted[cut_index:], self.convfilt_config['positive'], self.convfilt_config['maxcut'], self.convfilt_config['stable']) - above=lps.abovenoise(convoluted,noise_level,cut_index,abs_devs) + noise_level=lps.noise_absdev(convoluted[cut_index:], self.convfilt_config['positive'], self.convfilt_config['maxcut'], self.convfilt_config['stable']) + above=lps.abovenoise(convoluted,noise_level,cut_index,abs_devs) peak_location,peak_size=lps.find_peaks(above,seedouble=self.convfilt_config['seedouble']) #take the minimum or the maximum of a peak @@ -197,22 +189,22 @@ class flatfiltsCommands: peak_location[i]=index_pk return peak_location,peak_size - - + + def exec_has_peaks(self,item,abs_devs): ''' encapsulates has_peaks for the purpose of correctly treating the curve objects in the convfilt loop, to avoid memory leaks ''' - item.identify(self.drivers) + item.identify(self.drivers) #we assume the first is the plot with the force curve plot=item.curve.default_plots()[0] - + if 'flatten' in self.config['plotmanips']: #If flatten is present, use it for better recognition of peaks... flatten=self._find_plotmanip('flatten') #extract flatten plot manipulator plot=flatten(plot, item, customvalue=1) - + peak_location,peak_size=self.has_peaks(plot,abs_devs) #close all open files item.curve.close_all() @@ -220,10 +212,10 @@ class flatfiltsCommands: del item.curve del item return peak_location, peak_size - + #------------------------ #------commands---------- - #------------------------ + #------------------------ def do_peaks(self,args): ''' PEAKS @@ -236,37 +228,37 @@ class flatfiltsCommands: ''' if len(args)==0: args=self.convfilt_config['mindeviation'] - + try: abs_devs=float(args) except: print 'Wrong argument, using config value' abs_devs=float(self.convfilt_config['mindeviation']) - + defplots=self.current.curve.default_plots()[0] #we need the raw, uncorrected plots - + if 'flatten' in self.config['plotmanips']: flatten=self._find_plotmanip('flatten') #extract flatten plot manipulator defplots=flatten(defplots, self.current) else: print 'You have the flatten plot manipulator not loaded. Enabling it could give you better results.' - + peak_location,peak_size=self.has_peaks(defplots,abs_devs) print 'Found '+str(len(peak_location))+' peaks.' to_dump='peaks '+self.current.path+' '+str(len(peak_location)) self.outlet.push(to_dump) #print peak_location - + #if no peaks, we have nothing to plot. exit. if len(peak_location)==0: return - + #otherwise, we plot the peak locations. xplotted_ret=self.plots[0].vectors[1][0] yplotted_ret=self.plots[0].vectors[1][1] xgood=[xplotted_ret[index] for index in peak_location] ygood=[yplotted_ret[index] for index in peak_location] - + recplot=self._get_displayed_plot() recplot.vectors.append([xgood,ygood]) if recplot.styles==[]: @@ -275,9 +267,9 @@ class flatfiltsCommands: else: recplot.styles+=['scatter'] recplot.colors+=[None] - + self._send_plot([recplot]) - + def do_convfilt(self,args): ''' CONVFILT @@ -297,26 +289,26 @@ class flatfiltsCommands: If called without arguments, it uses default values. ''' - + min_npks=self.convfilt_config['minpeaks'] min_deviation=self.convfilt_config['mindeviation'] - + args=args.split(' ') if len(args) == 2: min_npks=int(args[0]) min_deviation=int(args[1]) else: pass - + print 'Processing playlist...' print '(Please wait)' notflat_list=[] - + c=0 for item in self.current_list: c+=1 - - try: + + try: peak_location,peak_size=self.exec_has_peaks(item,min_deviation) if len(peak_location)>=min_npks: isok='+' @@ -326,7 +318,7 @@ class flatfiltsCommands: except: peak_location,peak_size=[],[] print 'Curve',item.path, 'is',c,'of',len(self.current_list),': cannot be filtered. Probably unable to retrieve force data from corrupt file.' - + if len(peak_location)>=min_npks: item.peak_location=peak_location item.peak_size=peak_size @@ -340,7 +332,7 @@ class flatfiltsCommands: if not ('flatten' in self.config['plotmanips']): print 'Flatten manipulator was not found. Processing was done without flattening.' print 'Try to enable it in your configuration file for better results.' - + if len(notflat_list)==0: print 'Found nothing interesting. Check your playlist, could be a bug or criteria could be too much stringent' return @@ -351,8 +343,8 @@ class flatfiltsCommands: self.current_list=notflat_list self.current=self.current_list[self.pointer] self.do_plot(0) - - + + def do_setconv(self,args): ''' SETCONV @@ -370,7 +362,7 @@ class flatfiltsCommands: print 'This is not an internal convfilt variable!' print 'Run "setconv" without arguments to see a list of defined variables.' return - + if len(args)==1: print self.convfilt_config[args[0]] elif len(args)>1: @@ -382,22 +374,22 @@ class flatfiltsCommands: ######################### #HANDLING OF CONFIGURATION FILE -class ConvfiltConfig: +class ConvfiltConfig(object): ''' Handling of convfilt configuration file - + Mostly based on the simple-yet-useful examples of the Python Library Reference about xml.dom.minidom - + FIXME: starting to look a mess, should require refactoring ''' - + def __init__(self): self.config={} - - + + def load_config(self, filename): - myconfig=file(filename) + myconfig=file(filename) #the following 3 lines are needed to strip newlines. otherwise, since newlines #are XML elements too, the parser would read them (and re-save them, multiplying #newlines...) @@ -405,9 +397,9 @@ class ConvfiltConfig: the_file=myconfig.read() the_file_lines=the_file.split('\n') the_file=''.join(the_file_lines) - - self.config_tree=xml.dom.minidom.parseString(the_file) - + + self.config_tree=xml.dom.minidom.parseString(the_file) + def getText(nodelist): #take the text from a nodelist #from Python Library Reference 13.7.2 @@ -416,23 +408,23 @@ class ConvfiltConfig: if node.nodeType == node.TEXT_NODE: rc += node.data return rc - + def handleConfig(config): noiseabsdev_elements=config.getElementsByTagName("noise_absdev") convfilt_elements=config.getElementsByTagName("convfilt") handleAbsdev(noiseabsdev_elements) handleConvfilt(convfilt_elements) - + def handleAbsdev(noiseabsdev_elements): for element in noiseabsdev_elements: for attribute in element.attributes.keys(): self.config[attribute]=element.getAttribute(attribute) - + def handleConvfilt(convfilt_elements): for element in convfilt_elements: for attribute in element.attributes.keys(): self.config[attribute]=element.getAttribute(attribute) - + handleConfig(self.config_tree) #making items in the dictionary machine-readable for item in self.config.keys(): @@ -440,5 +432,5 @@ class ConvfiltConfig: self.config[item]=eval(self.config[item]) except NameError: #if it's an unreadable string, keep it as a string pass - - return self.config \ No newline at end of file + + return self.config