Changeset bc570f4 in sasview for src/sas


Ignore:
Timestamp:
Jul 26, 2017 7:26:45 AM (7 years ago)
Author:
lewis
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
7477fb9
Parents:
3ece5dd
Message:

Refactor CanSASReader/XMLReader to use FileReader? class

Location:
src/sas/sascalc/dataloader
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/dataloader/file_reader_base_class.py

    rad92c5a rbc570f4  
    4141    def read(self, filepath): 
    4242        """ 
    43         Basic file reader  
    44          
     43        Basic file reader 
     44 
    4545        :param filepath: The full or relative path to a file to be loaded 
    4646        """ 
     
    5555                    self.get_file_contents() 
    5656                    self.sort_one_d_data() 
    57                 except FileContentsException as e: 
     57                except DataReaderException as e: 
    5858                    self.handle_error_message(e.message) 
    5959                except OSError as e: 
  • src/sas/sascalc/dataloader/readers/cansas_reader.py

    r3ece5dd rbc570f4  
    7777    ns_list = None 
    7878    # Temporary storage location for loading multiple data sets in a single file 
    79     current_datainfo = None 
    80     current_dataset = None 
    8179    current_data1d = None 
    8280    data = None 
    83     # List of data1D objects to be sent back to SasView 
    84     output = None 
    8581    # Wildcards 
    8682    type = ["XML files (*.xml)|*.xml", "SasView Save Files (*.svs)|*.svs"] 
     
    112108 
    113109    def read(self, xml_file, schema_path="", invalid=True): 
     110        if schema_path != "" or invalid != True: 
     111            # read has been called from self.get_file_contents because xml file doens't conform to schema 
     112            _, self.extension = os.path.splitext(os.path.basename(xml_file)) 
     113            return self.get_file_contents(xml_file=xml_file, schema_path=schema_path, invalid=invalid) 
     114 
     115        # Otherwise, read has been called by the data loader - file_reader_base_class handles this 
     116        return super(XMLreader, self).read(xml_file) 
     117 
     118    def get_file_contents(self, xml_file=None, schema_path="", invalid=True): 
    114119        """ 
    115120        Validate and read in an xml_file file in the canSAS format. 
     
    121126        self.reset_state() 
    122127        self.invalid = invalid 
    123         # Check that the file exists 
    124         if os.path.isfile(xml_file): 
    125             basename, extension = os.path.splitext(os.path.basename(xml_file)) 
     128        # We don't use f_open since libxml handles opening/closing files 
     129        if xml_file is None: 
     130            xml_file = self.f_open.name 
     131        if not self.f_open.closed: 
     132            self.f_open.close() 
     133        basename, _ = os.path.splitext(os.path.basename(xml_file)) 
     134        try: 
     135            # Get the file location of 
     136            self.load_file_and_schema(xml_file, schema_path) 
     137            self.add_data_set() 
     138            # Try to load the file, but raise an error if unable to. 
     139            # Check the file matches the XML schema 
     140            self.is_cansas(self.extension) # Raises FileContentsException if not CanSAS 
     141            self.invalid = False 
     142            # Get each SASentry from XML file and add it to a list. 
     143            entry_list = self.xmlroot.xpath( 
     144                    '/ns:SASroot/ns:SASentry', 
     145                    namespaces={'ns': self.cansas_defaults.get("ns")}) 
     146            self.names.append("SASentry") 
     147 
     148            # Get all preprocessing events and encoding 
     149            self.set_processing_instructions() 
     150 
     151            # Parse each <SASentry> item 
     152            for entry in entry_list: 
     153                # Create a new DataInfo object for every <SASentry> 
     154 
     155                # Set the file name and then parse the entry. 
     156                self.current_datainfo.filename = basename + self.extension 
     157                self.current_datainfo.meta_data["loader"] = "CanSAS XML 1D" 
     158                self.current_datainfo.meta_data[PREPROCESS] = \ 
     159                    self.processing_instructions 
     160 
     161                # Parse the XML SASentry 
     162                self._parse_entry(entry) 
     163                # Combine datasets with datainfo 
     164                self.add_data_set() 
     165        except FileContentsException as fc_exc: 
    126166            try: 
    127                 # Get the file location of 
    128                 self.load_file_and_schema(xml_file, schema_path) 
    129                 self.add_data_set() 
    130                 # Try to load the file, but raise an error if unable to. 
    131                 # Check the file matches the XML schema 
    132                 self.is_cansas(extension) # Raises FileContentsException if not CanSAS 
    133                 self.invalid = False 
    134                 # Get each SASentry from XML file and add it to a list. 
    135                 entry_list = self.xmlroot.xpath( 
    136                         '/ns:SASroot/ns:SASentry', 
    137                         namespaces={'ns': self.cansas_defaults.get("ns")}) 
    138                 self.names.append("SASentry") 
    139  
    140                 # Get all preprocessing events and encoding 
    141                 self.set_processing_instructions() 
    142  
    143                 # Parse each <SASentry> item 
    144                 for entry in entry_list: 
    145                     # Create a new DataInfo object for every <SASentry> 
    146  
    147                     # Set the file name and then parse the entry. 
    148                     self.current_datainfo.filename = basename + extension 
    149                     self.current_datainfo.meta_data["loader"] = "CanSAS XML 1D" 
    150                     self.current_datainfo.meta_data[PREPROCESS] = \ 
    151                         self.processing_instructions 
    152  
    153                     # Parse the XML SASentry 
    154                     self._parse_entry(entry) 
    155                     # Combine datasets with datainfo 
    156                     self.add_data_set() 
     167                # Try again with an invalid CanSAS schema, that requires only a data set in each 
     168                base_name = xml_reader.__file__ 
     169                base_name = base_name.replace("\\", "/") 
     170                base = base_name.split("/sas/")[0] 
     171                if self.cansas_version == "1.1": 
     172                    invalid_schema = INVALID_SCHEMA_PATH_1_1.format(base, self.cansas_defaults.get("schema")) 
     173                else: 
     174                    invalid_schema = INVALID_SCHEMA_PATH_1_0.format(base, self.cansas_defaults.get("schema")) 
     175                self.set_schema(invalid_schema) 
     176                if self.invalid: 
     177                    self.output = self.read(xml_file, invalid_schema, False) 
     178                    # If the file does not match the schema, but can still be read, raise this error 
     179                    self.load_file_and_schema(xml_file) # Relaod valid schema so we can find errors 
     180                    invalid_xml = self.find_invalid_xml() 
     181                    invalid_xml = INVALID_XML.format(basename + self.extension) + invalid_xml 
     182                    raise DataReaderException(invalid_xml) 
     183                else: 
     184                    raise fc_exc 
    157185            except FileContentsException as fc_exc: 
    158                 try: 
    159                     # If the file does not match the schema, raise this error 
    160                     invalid_xml = self.find_invalid_xml() 
    161                     invalid_xml = INVALID_XML.format(basename + extension) + invalid_xml 
    162                     self.errors.add(invalid_xml) 
    163                     # Try again with an invalid CanSAS schema, that requires only a data set in each 
    164                     base_name = xml_reader.__file__ 
    165                     base_name = base_name.replace("\\", "/") 
    166                     base = base_name.split("/sas/")[0] 
    167                     if self.cansas_version == "1.1": 
    168                         invalid_schema = INVALID_SCHEMA_PATH_1_1.format(base, self.cansas_defaults.get("schema")) 
    169                     else: 
    170                         invalid_schema = INVALID_SCHEMA_PATH_1_0.format(base, self.cansas_defaults.get("schema")) 
    171                     self.set_schema(invalid_schema) 
    172                     if self.invalid: 
    173                         self.output = self.read(xml_file, invalid_schema, False) 
    174                     else: 
    175                         raise fc_exc 
    176                 except FileContentsException as fc_exc: 
    177                     msg = "CanSAS Reader could not load the file {}".format(xml_file) 
    178                     if not extension in self.ext: 
    179                         raise DefaultReaderException(msg) 
    180                     if fc_exc.message is not None: 
    181                         msg = fc_exc.message 
    182                     raise FileContentsException(msg) 
    183                 except Exception as e: 
    184                     raise FileContentsException(e.message) 
    185         else: 
    186             self.output.append("Not a valid file path.") 
     186                msg = "CanSAS Reader could not load the file {}".format(xml_file) 
     187                if not self.extension in self.ext: # If the file has no associated loader 
     188                    raise DefaultReaderException(msg) 
     189                if fc_exc.message is not None: # Propagate error messages from earlier 
     190                    msg = fc_exc.message 
     191                raise FileContentsException(msg) 
     192            except DataReaderException as dr_exc: # Handled by file_reader_base_class 
     193                raise dr_exc 
     194            except Exception as e: # Convert any other exceptions to FileContentsExceptions 
     195                raise FileContentsException(e.message) 
    187196        # Return a list of parsed entries that dataloader can manage 
    188197        return self.output 
  • src/sas/sascalc/dataloader/readers/xml_reader.py

    r3ece5dd rbc570f4  
    1818from lxml import etree 
    1919from lxml.builder import E 
     20from sas.sascalc.dataloader.file_reader_base_class import FileReader 
    2021 
    2122logger = logging.getLogger(__name__) 
     
    2324PARSER = etree.ETCompatXMLParser(remove_comments=True, remove_pis=False) 
    2425 
    25 class XMLreader(): 
     26class XMLreader(FileReader): 
    2627    """ 
    2728    Generic XML read and write class. Mostly helper functions. 
Note: See TracChangeset for help on using the changeset viewer.