Really hideous merge of Rolf Schmidt's code.
[hooke.git] / hooke / libhooke.py
index eb4ce79bd03909fd534e6d08735e91317c482d1c..a1d623f65a2a2cf453e1a36025917143b3df35d8 100644 (file)
@@ -19,307 +19,23 @@ import os
 import os.path
 import string
 import csv
-from matplotlib.ticker import ScalarFormatter
 
 
-from . import libhookecurve as lhc
-
-HOOKE_VERSION=['0.8.3_devel', 'Seinei', '2008-04-16']
+HOOKE_VERSION=['0.9.0_devel', 'Kenzo', '2009-09-xx']
 WX_GOOD=['2.6','2.8']
+hookeDir=''
 
-class PlaylistXML(object):
-        '''
-        This module allows for import/export of an XML playlist into/out of a list of HookeCurve objects
-        '''
-
-        def __init__(self):
-
-            self.playlist=None #the DOM object representing the playlist data structure
-            self.playpath=None #the path of the playlist XML file
-            self.plaything=None
-            self.hidden_attributes=['curve'] #This list contains hidden attributes that we don't want to go into the playlist.
-
-        def export(self, list_of_hooke_curves, generics):
-            '''
-            Creates an initial playlist from a list of files.
-            A playlist is an XML document with the following syntaxis:
-            <playlist>
-            <element path="/my/file/path/"/ attribute="attribute">
-            <element path="...">
-            </playlist>
-            '''
-
-            #create the output playlist, a simple XML document
-            impl=xml.dom.minidom.getDOMImplementation()
-            #create the document DOM object and the root element
-            newdoc=impl.createDocument(None, "playlist",None)
-            top_element=newdoc.documentElement
-
-            #save generics variables
-            playlist_generics=newdoc.createElement("generics")
-            top_element.appendChild(playlist_generics)
-            for key in generics.keys():
-                newdoc.createAttribute(key)
-                playlist_generics.setAttribute(key,str(generics[key]))
-
-            #save curves and their attributes
-            for item in list_of_hooke_curves:
-                #playlist_element=newdoc.createElement("curve")
-                playlist_element=newdoc.createElement("element")
-                top_element.appendChild(playlist_element)
-                for key in item.__dict__:
-                    if not (key in self.hidden_attributes):
-                        newdoc.createAttribute(key)
-                        playlist_element.setAttribute(key,str(item.__dict__[key]))
-
-            self.playlist=newdoc
-
-        def load(self,filename):
-            '''
-            loads a playlist file
-            '''
-            myplay=file(filename)
-            self.playpath=filename
-
-            #the following 3 lines are needed to strip newlines. otherwise, since newlines
-            #are XML elements too (why?), the parser would read them (and re-save them, multiplying
-            #newlines...)
-            #yes, I'm an XML n00b
-            the_file=myplay.read()
-            the_file_lines=the_file.split('\n')
-            the_file=''.join(the_file_lines)
-
-            self.playlist=xml.dom.minidom.parseString(the_file)
 
-            #inner parsing functions
-            def handlePlaylist(playlist):
-                list_of_files=playlist.getElementsByTagName("element")
-                generics=playlist.getElementsByTagName("generics")
-                return handleFiles(list_of_files), handleGenerics(generics)
+def get_file_path(filename, folders = []):
+    if os.path.dirname(filename) == '' or os.path.isabs(filename) == False:
+        path = ''
+        for folder in folders:
+            path = os.path.join(path, folder)
+        filename = os.path.join(hookeDir, path, filename)
 
-            def handleGenerics(generics):
-                generics_dict={}
-                if len(generics)==0:
-                    return generics_dict
+    return filename
 
-                for attribute in generics[0].attributes.keys():
-                    generics_dict[attribute]=generics[0].getAttribute(attribute)
-                return generics_dict
-
-            def handleFiles(list_of_files):
-                new_playlist=[]
-                for myfile in list_of_files:
-                    #rebuild a data structure from the xml attributes
-                    the_curve=lhc.HookeCurve(
-                        os.path.join(os.path.dirname(self.playpath),
-                                     myfile.getAttribute('path')))
-                    for attribute in myfile.attributes.keys():
-                        #extract attributes for the single curve
-                        if attribute == 'path':
-                            continue # we already added this attribute
-                        the_curve.__dict__[attribute]=myfile.getAttribute(attribute)
-                    new_playlist.append(the_curve)
-
-                return new_playlist #this is the true thing returned at the end of this function...(FIXME: clarity)
-
-            return handlePlaylist(self.playlist)
-
-
-        def save(self,output_filename):
-            '''
-            saves the playlist in a XML file.
-            '''
-            try:
-                outfile=file(output_filename,'w')
-            except IOError:
-                print 'libhooke.py : Cannot save playlist. Wrong path or filename'
-                return
-
-            self.playlist.writexml(outfile,indent='\n')
-            outfile.close()
-
-def config_file_path(filename, config_dir=None):
-    if config_dir == None:
-        config_dir = os.path.abspath(
-            os.path.join(os.path.dirname(os.path.dirname(__file__)), 'conf'))
-    return os.path.join(config_dir, filename)
-
-class HookeConfig(object):
-    '''
-    Handling of Hooke 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, config_dir=None):
-        self.config={}
-        self.config['install']={}
-        self.config['plugins']=[]
-        self.config['drivers']=[]
-        self.config['plotmanips']=[]
-        self.config_dir = config_dir
-
-    def load_config(self, filename):
-        myconfig=file(config_file_path(filename, config_dir=self.config_dir))
-
-        #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...)
-        #yes, I'm an XML n00b
-        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)
-
-        def getText(nodelist):
-            #take the text from a nodelist
-            #from Python Library Reference 13.7.2
-            rc = ''
-            for node in nodelist:
-                if node.nodeType == node.TEXT_NODE:
-                    rc += node.data
-            return rc
-
-        def handleConfig(config):
-            install_elements=config.getElementsByTagName("install")
-            display_elements=config.getElementsByTagName("display")
-            plugins_elements=config.getElementsByTagName("plugins")
-            drivers_elements=config.getElementsByTagName("drivers")
-            defaultlist_elements=config.getElementsByTagName("defaultlist")
-            plotmanip_elements=config.getElementsByTagName("plotmanips")
-            handleInstall(install_elements)
-            handleDisplay(display_elements)
-            handlePlugins(plugins_elements)
-            handleDrivers(drivers_elements)
-            handleDefaultlist(defaultlist_elements)
-            handlePlotmanip(plotmanip_elements)
-
-        def handleInstall(install_elements):
-            for install in install_elements:
-                for node in install.childNodes:
-                    if node.nodeType == node.TEXT_NODE:
-                        continue
-                    path = os.path.abspath(getText(node.childNodes).strip())
-                    self.config['install'][str(node.tagName)] = path
-
-        def handleDisplay(display_elements):
-            for element in display_elements:
-                for attribute in element.attributes.keys():
-                    self.config[attribute]=element.getAttribute(attribute)
-
-        def handlePlugins(plugins):
-            for plugin in plugins[0].childNodes:
-                try:
-                    self.config['plugins'].append(str(plugin.tagName))
-                except: #if we allow fancy formatting of xml, there is a text node, so tagName fails for it...
-                    pass
-        #FIXME: code duplication
-        def handleDrivers(drivers):
-            for driver in drivers[0].childNodes:
-                try:
-                    self.config['drivers'].append(str(driver.tagName))
-                except: #if we allow fancy formatting of xml, there is a text node, so tagName fails for it...
-                    pass
-
-        def handlePlotmanip(plotmanips):
-            for plotmanip in plotmanips[0].childNodes:
-                try:
-                    self.config['plotmanips'].append(str(plotmanip.tagName))
-                except: #if we allow fancy formatting of xml, there is a text node, so tagName fails for it...
-                    pass
-
-        def handleDefaultlist(defaultlist):
-            '''
-            default playlist
-            '''
-            dflist=getText(defaultlist[0].childNodes)
-            self.config['defaultlist']=dflist.strip()
-
-        handleConfig(self.config_tree)
-        #making items in the dictionary more machine-readable
-        for item in self.config.keys():
-            try:
-                self.config[item]=float(self.config[item])
-            except TypeError: #we are dealing with a list, probably. keep it this way.
-                try:
-                    self.config[item]=eval(self.config[item])
-                except: #not a list, not a tuple, probably a string?
-                    pass
-            except ValueError: #if we can't get it to a number, it must be None or a string
-                if string.lower(self.config[item])=='none':
-                    self.config[item]=None
-                else:
-                    pass
-
-        return self.config
-
-
-    def save_config(self, config_filename):
-        print 'Not Implemented.'
-        pass
-
-
-class EngrFormatter(ScalarFormatter):
-    """A variation of the standard ScalarFormatter, using only multiples of 
-three
-in the mantissa. A fixed number of decimals can be displayed with the optional 
-parameter `ndec` . If `ndec` is None (default), the number of decimals is 
-defined
-from the current ticks.
-    """
-    def __init__(self, ndec=None, useOffset=True, useMathText=False):
-        ScalarFormatter.__init__(self, useOffset, useMathText)
-        if ndec is None or ndec < 0:
-            self.format = None
-        elif ndec == 0:
-            self.format = "%d"
-        else:
-            self.format = "%%1.%if" % ndec
-    #........................
-
-    def _set_orderOfMagnitude(self, mrange):
-           """Sets the order of magnitude."""        
-           locs = numpy.absolute(self.locs)
-           if self.offset: 
-               oom = numpy.floor(numpy.log10(mrange))
-           else:
-               if locs[0] > locs[-1]: 
-                   val = locs[0]
-               else: 
-                   val = locs[-1]
-               if val == 0: 
-                   oom = 0
-               else: 
-                   oom = numpy.floor(numpy.log10(val))
-           if oom <= -3:
-               self.orderOfMagnitude = 3*(oom//3)
-           elif oom <= -1:
-               self.orderOfMagnitude = -3
-           elif oom >= 4:
-               self.orderOfMagnitude = 3*(oom//3)
-           else:
-               self.orderOfMagnitude = 0
-
-
-    #........................
-    def _set_format(self):
-        """Sets the format string to format all ticklabels."""
-        # set the format string to format all the ticklabels
-        locs = (numpy.array(self.locs)-self.offset) /  10**self.orderOfMagnitude+1e-15
-        sigfigs = [len(str('%1.3f'% loc).split('.')[1].rstrip('0')) \
-                   for loc in locs]
-        sigfigs.sort()
-        if self.format is None:
-            self.format = '%1.' + str(sigfigs[-1]) + 'f'
-        if self._usetex or self._useMathText: self.format = '$%s$'%self.format
-
-
-
-class ClickedPoint:
+class ClickedPoint(object):
     '''
     this class defines what a clicked point on the curve plot is
     '''
@@ -341,13 +57,12 @@ class ClickedPoint:
         '''
 
         #FIXME: a general algorithm using min() is needed!
-        #print '---DEPRECATED FIND_GRAPH_COORDS_OLD---'
         best_index=0
         best_dist=10**9 #should be more than enough given the scale
 
         for index in scipy.arange(1,len(xvector),1):
             dist=((self.absolute_coords[0]-xvector[index])**2)+(100*((self.absolute_coords[1]-yvector[index])))**2
-                        #TODO, generalize? y coordinate is multiplied by 100 due to scale differences in the plot
+                #TODO, generalize? y coordinate is multiplied by 100 due to scale differences in the plot
             if dist<best_dist:
                 best_index=index
                 best_dist=dist
@@ -358,7 +73,7 @@ class ClickedPoint:
 
     def find_graph_coords(self,xvector,yvector):
         '''
-        Given a clicked point on the plot, finds the nearest point in the dataset that
+        Given a clicked point on the plot, finds the nearest point in the dataset (in X) that
         corresponds to the clicked point.
         '''
         dists=[]