source: sasview/DataLoader/loader.py @ 77e23a2

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 77e23a2 was 954c045, checked in by Jae Cho <jhjcho@…>, 16 years ago

ACS reads abs files when errored from abs reader

  • Property mode set to 100644
File size: 9.1 KB
Line 
1"""
2    File handler to support different file extensions.
3    Uses reflectometry's registry utility.
4   
5    The default readers are found in the 'readers' sub-module
6    and registered by default at initialization time.
7   
8    To add a new default reader, one must register it in
9    the register_readers method found in readers/__init__.py.
10   
11    A utility method (find_plugins) is available to inspect
12    a directory (for instance, a user plug-in directory) and
13    look for new readers/writers.
14"""
15
16"""
17This software was developed by the University of Tennessee as part of the
18Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
19project funded by the US National Science Foundation.
20
21See the license text in license.txt
22
23copyright 2008, University of Tennessee
24"""
25
26from data_util.registry import ExtensionRegistry
27import os 
28import sys
29import logging
30import time
31from zipfile import ZipFile
32
33# Default readers are defined in the readers sub-module
34import readers
35
36class Registry(ExtensionRegistry):
37    """
38        Registry class for file format extensions.
39        Readers and writers are supported.
40    """
41   
42    def __init__(self):
43        super(Registry, self).__init__()
44       
45        ## Writers
46        self.writers = {}
47       
48        ## List of wildcards
49        self.wildcards = ['All (*.*)|*.*']
50       
51        ## Creation time, for testing
52        self._created = time.time()
53       
54        # Register default readers
55        readers.register_readers(self._identify_plugin)
56       
57    def find_plugins(self, dir):
58        """
59            Find readers in a given directory. This method
60            can be used to inspect user plug-in directories to
61            find new readers/writers.
62           
63            @param dir: directory to search into
64            @return: number of readers found
65        """
66        readers_found = 0
67       
68        # Check whether the directory exists
69        if not os.path.isdir(dir): 
70            logging.warning("DataLoader couldn't load from %s" % dir)
71            return readers_found
72       
73        for item in os.listdir(dir):
74            full_path = os.path.join(dir, item)
75            if os.path.isfile(full_path):
76               
77                # Process python files
78                if item.endswith('.py'):
79                    toks = os.path.splitext(os.path.basename(item))
80                    try:
81                        sys.path.insert(0, os.path.abspath(dir))
82                        module = __import__(toks[0], globals(), locals())
83                        if self._identify_plugin(module):
84                            readers_found += 1
85                    except :
86                        logging.error("Loader: Error importing %s\n  %s" % (item, sys.exc_value))
87                           
88                # Process zip files
89                elif item.endswith('.zip'):
90                    try:
91                        # Find the modules in the zip file
92                        zfile = ZipFile(item)
93                        nlist = zfile.namelist()
94                       
95                        sys.path.insert(0, item)
96                        for mfile in nlist:
97                            try:
98                                # Change OS path to python path
99                                fullname = mfile.replace('/', '.')
100                                fullname = os.path.splitext(fullname)[0]
101                                module = __import__(fullname, globals(), locals(), [""])
102                                if self._identify_plugin(module):
103                                    readers_found += 1
104                            except:
105                                logging.error("Loader: Error importing %s\n  %s" % (mfile, sys.exc_value))
106                           
107                    except:
108                        logging.error("Loader: Error importing %s\n  %s" % (item, sys.exc_value))
109                     
110        return readers_found
111   
112    def _identify_plugin(self, module):
113        """
114            Look into a module to find whether it contains a
115            Reader class. If so, add it to readers and (potentially)
116            to the list of writers.
117            @param module: module object
118        """
119        reader_found = False
120       
121        if hasattr(module, "Reader"):
122            try:
123                # Find supported extensions
124                loader = module.Reader()
125                for ext in loader.ext:
126                    if ext not in self.loaders:
127                        self.loaders[ext] = []
128                    #The first reading will use the reader with only one ext.
129                    if len(self.loaders[ext])>0 and len(loader.ext)>2:
130                        self.loaders[ext].insert(1,loader.read)
131                    else:
132                        self.loaders[ext].insert(0,loader.read)
133
134                    reader_found = True
135                   
136                    # Keep track of wildcards
137                    for wcard in loader.type:
138                        if wcard not in self.wildcards:
139                            self.wildcards.append(wcard)
140                           
141                # Check whether writing is supported
142                if hasattr(loader, 'write'):
143                    for ext in loader.ext:
144                        if ext not in self.writers:
145                            self.writers[ext] = []
146                        self.writers[ext].insert(0,loader.write)
147                       
148            except:
149                logging.error("Loader: Error accessing Reader in %s\n  %s" % (name, sys.exc_value))
150        return reader_found
151
152    def lookup_writers(self, path):
153        """
154        Return the loader associated with the file type of path.
155       
156        Raises ValueError if file type is not known.
157        """       
158        # Find matching extensions
159        extlist = [ext for ext in self.extensions() if path.endswith(ext)]
160        # Sort matching extensions by decreasing order of length
161        extlist.sort(lambda a,b: len(a)<len(b))
162        # Combine loaders for matching extensions into one big list
163        writers = []
164        for L in [self.writers[ext] for ext in extlist]:
165            writers.extend(L)
166        # Remove duplicates if they exist
167        if len(writers) != len(set(writers)):
168            result = []
169            for L in writers:
170                if L not in result: result.append(L)
171            writers = L
172        # Raise an error if there are no matching extensions
173        if len(writers) == 0:
174            raise ValueError, "Unknown file type for "+path
175        # All done
176        return writers
177
178    def save(self, path, data, format=None):
179        """
180        Call the writer for the file type of path.
181
182        Raises ValueError if no writer is available.
183        Raises KeyError if format is not available.
184        May raise a writer-defined exception if writer fails.       
185        """
186        if format is None:
187            writers = self.lookup_writers(path)
188        else:
189            writers = self.writers[format]
190        for fn in writers:
191            try:
192                return fn(path, data)
193            except:
194                pass # give other loaders a chance to succeed
195        # If we get here it is because all loaders failed
196        raise # reraises last exception
197
198       
199class Loader(object):
200    """
201        Utility class to use the Registry as a singleton.
202    """
203    ## Registry instance
204    __registry = Registry()
205   
206    def load(self, file, format=None):
207        """
208            Load a file
209           
210            @param file: file name (path)
211            @param format: specified format to use (optional)
212            @return: DataInfo object
213        """
214        return self.__registry.load(file, format)
215   
216    def save(self, file, data, format):
217        """
218            Save a DataInfo object to file
219            @param file: file name (path)
220            @param data: DataInfo object
221            @param format: format to write the data in
222        """
223        return self.__registry.save(file, data, format)
224       
225    def _get_registry_creation_time(self):
226        """
227            Internal method used to test the uniqueness
228            of the registry object
229        """
230        return self.__registry._created
231   
232    def find_plugins(self, dir):
233        """
234            Find plugins in a given directory
235            @param dir: directory to look into to find new readers/writers
236        """
237        return self.__registry.find_plugins(dir)
238   
239    def get_wildcards(self):
240        return self.__registry.wildcards
241       
242if __name__ == "__main__": 
243    logging.basicConfig(level=logging.INFO,
244                        format='%(asctime)s %(levelname)s %(message)s',
245                        filename='loader.log',
246                        filemode='w')
247    l = Loader()
248    data = l.load('test/cansas1d.xml')
249    l.save('test_file.xml', data, '.xml')
250   
251    print l.get_wildcards()
252       
253       
254   
Note: See TracBrowser for help on using the repository browser.