Ignore:
Timestamp:
May 5, 2014 3:41:43 PM (11 years ago)
Author:
Jeff Krzywon <jeffery.krzywon@…>
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.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
c81aa18
Parents:
0089be3
Message:

Ticket #249 fix: Saving and loading projects and analysis is now working.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sans/dataloader/readers/cansas_reader.py

    r2e3b055 rac5b69d  
    1818import sys 
    1919import datetime 
     20import inspect 
     21# For saving individual sections of data 
    2022from sans.dataloader.data_info import Data1D 
    2123from sans.dataloader.data_info import Collimation 
     
    2426from sans.dataloader.data_info import Process 
    2527from sans.dataloader.data_info import Aperture 
     28# Both imports used. Do not remove either. 
     29from xml.dom.minidom import parseString 
    2630import sans.dataloader.readers.xml_reader as xml_reader 
    27 from sans.dataloader.readers.cansas_constants import cansasConstants 
     31from sans.dataloader.readers.xml_reader import XMLreader 
     32from sans.dataloader.readers.cansas_constants import CansasConstants 
    2833 
    2934_ZERO = 1e-16 
     
    3641    HAS_CONVERTER = False 
    3742 
    38 constants = cansasConstants()     
    39 CANSAS_FORMAT = constants.format 
    40 CANSAS_NS = constants.ns 
     43CONSTANTS = CansasConstants()     
     44CANSAS_FORMAT = CONSTANTS.format 
     45CANSAS_NS = CONSTANTS.names 
    4146ALLOW_ALL = True 
    4247 
    4348 
     49# minidom used in functions called by outside classes 
     50import xml.dom.minidom 
     51# DO NOT REMOVE 
     52# Called by outside packages: 
     53#    sans.perspectives.invariant.invariant_state 
     54#    sans.perspectives.fitting.pagestate 
    4455def get_content(location, node): 
    4556    """ 
     
    5162    :return: Element, or None 
    5263    """ 
    53     nodes = node.xpath(location, namespaces={'ns': CANSAS_NS}) 
     64    nodes = node.xpath(location,  
     65                       namespaces={'ns': CANSAS_NS.get("1.0").get("ns")}) 
    5466     
    5567    if len(nodes) > 0: 
     
    5971 
    6072 
    61 def get_float(location, node): 
    62     """ 
    63     Get the content of a node as a float 
    64      
    65     :param location: xpath location 
    66     :param node: node to start at 
    67     """ 
    68     nodes = node.xpath(location, namespaces={'ns': CANSAS_NS}) 
    69      
    70     value = None 
    71     attr = {} 
    72     if len(nodes) > 0: 
    73         try: 
    74             value = float(nodes[0].text) 
    75         except: 
    76             # Could not pass, skip and return None 
    77             msg = "cansas_reader.get_float: could not " 
    78             msg += " convert '%s' to float" % nodes[0].text 
    79             logging.error(msg) 
    80         if nodes[0].get('unit') is not None: 
    81             attr['unit'] = nodes[0].get('unit') 
    82     return value, attr 
    83  
    84  
    85 # This is called by sans.perspectives.fitting.pagestate.py 
    86 # Do not remove 
     73# DO NOT REMOVE 
     74# Called by outside packages: 
     75#    sans.perspectives.fitting.pagestate 
    8776def write_node(doc, parent, name, value, attr={}): 
    8877    """ 
     
    10594                 
    10695 
    107 class Reader(): 
     96class Reader(XMLreader): 
    10897    """ 
    10998    Class to load cansas 1D XML files 
     
    114103    ##CanSAS version - defaults to version 1.0 
    115104    cansas_version = "1.0" 
    116     ##Data reader 
    117     # TODO: make the reader extend the XMLreader class? 
    118     reader = xml_reader.XMLreader() 
     105     
     106    logging = [] 
    119107    errors = [] 
    120108     
    121109    type_name = "canSAS" 
    122      
    123110    ## Wildcards 
    124     type = ["XML files (*.xml)|*.xml"] 
     111    type = ["XML files (*.xml)|*.xml", "SasView Save Files (*.svs)|*.svs"] 
    125112    ## List of allowed extensions 
    126     ext = ['.xml', '.XML'] 
     113    ext = ['.xml', '.XML', '.svs', '.SVS'] 
    127114     
    128115    ## Flag to bypass extension check 
     
    133120        self.errors = [] 
    134121         
    135     def is_cansas(self): 
     122    def is_cansas(self, ext="xml"): 
    136123        """ 
    137124        Checks to see if the xml file is a CanSAS file 
    138125        """ 
    139         if self.reader.validateXML(): 
     126        if self.validate_xml(): 
    140127            name = "{http://www.w3.org/2001/XMLSchema-instance}schemaLocation" 
    141             value = self.reader.xmlroot.get(name) 
    142             if (CANSAS_NS.get(self.cansas_version).get("ns") == \ 
    143                     value.rsplit(" ")[0]): 
     128            value = self.xmlroot.get(name) 
     129            if CANSAS_NS.get(self.cansas_version).get("ns") == \ 
     130                    value.rsplit(" ")[0]: 
    144131                return True 
     132        if ext == "svs": 
     133            return True 
    145134        return False 
    146135     
     
    152141        """ 
    153142        # X - Q value; Y - Intensity (Abs) 
    154         x = numpy.empty(0) 
    155         y = numpy.empty(0) 
    156         dx = numpy.empty(0) 
    157         dy = numpy.empty(0) 
     143        x_vals = numpy.empty(0) 
     144        y_vals = numpy.empty(0) 
     145        dx_vals = numpy.empty(0) 
     146        dy_vals = numpy.empty(0) 
    158147        dxl = numpy.empty(0) 
    159148        dxw = numpy.empty(0) 
     
    162151        output = [] 
    163152        # ns - Namespace hierarchy for current xml object 
    164         ns = [] 
     153        ns_list = [] 
    165154         
    166155        # Check that the file exists 
     
    168157            basename = os.path.basename(xml) 
    169158            _, extension = os.path.splitext(basename) 
    170             # If the fiel type is not allowed, return nothing 
     159            # If the file type is not allowed, return nothing 
    171160            if extension in self.ext or self.allow_all: 
     161                # Get the file location of  
    172162                base_name = xml_reader.__file__ 
    173163                base_name = base_name.replace("\\","/") 
     
    175165                 
    176166                # Load in xml file and get the cansas version from the header 
    177                 self.reader.setXMLFile(xml) 
    178                 root = self.reader.xmlroot 
     167                self.set_xml_file(xml) 
     168                root = self.xmlroot 
    179169                if root is None: 
    180170                    root = {} 
     
    187177                 
    188178                # Link a schema to the XML file. 
    189                 self.reader.setSchema(schema_path) 
     179                self.set_schema(schema_path) 
    190180                 
    191181                # Try to load the file, but raise an error if unable to. 
    192182                # Check the file matches the XML schema 
    193183                try: 
    194                     if self.is_cansas(): 
     184                    if self.is_cansas(extension): 
    195185                        # Get each SASentry from XML file and add it to a list. 
    196186                        entry_list = root.xpath('/ns:SASroot/ns:SASentry', 
    197187                                namespaces={'ns': cansas_defaults.get("ns")}) 
    198                         ns.append("SASentry") 
     188                        ns_list.append("SASentry") 
    199189                         
    200190                        # If multiple files, modify the name for each is unique 
     
    204194                        # Parse each SASentry item 
    205195                        for entry in entry_list: 
    206                             # Define a new Data1D object with zeroes for x and y 
    207                             data1d = Data1D(x,y,dx,dy) 
     196                            # Define a new Data1D object with zeroes for  
     197                            # x_vals and y_vals 
     198                            data1d = Data1D(x_vals, y_vals, dx_vals, dy_vals) 
    208199                            data1d.dxl = dxl 
    209200                            data1d.dxw = dxw 
     
    220211                             
    221212                            # Get all preprocessing events and encoding 
    222                             self.reader.setProcessingInstructions() 
     213                            self.set_processing_instructions() 
    223214                            data1d.meta_data[PREPROCESS] = \ 
    224                                     self.reader.processingInstructions 
     215                                    self.processing_instructions 
    225216                             
    226217                            # Parse the XML file 
    227218                            return_value, extras = \ 
    228                                 self._parse_entry(entry, ns, data1d) 
     219                                self._parse_entry(entry, ns_list, data1d) 
    229220                            del extras[:] 
    230221                             
     
    251242                            output.append(return_value) 
    252243                    else: 
    253                         value = self.reader.findInvalidXML() 
     244                        value = self.find_invalid_xml() 
    254245                        output.append("Invalid XML at: {0}".format(value)) 
    255246                except: 
    256247                    # If the file does not match the schema, raise this error 
    257                     raise RuntimeError, "%s cannot be read \increment" % xml 
     248                    raise RuntimeError, "%s cannot be read" % xml 
    258249                return output 
    259250        # Return a list of parsed entries that dataloader can manage 
    260251        return None 
    261252     
    262     def _create_unique_key(self, dictionary, name, i = 0): 
     253    def _create_unique_key(self, dictionary, name, numb = 0): 
    263254        """ 
    264255        Create a unique key value for any dictionary to prevent overwriting 
     
    267258        :param dictionary: A dictionary with any number of entries 
    268259        :param name: The index of the item to be added to dictionary 
    269         :param i: The number to be appended to the name, starts at 0 
     260        :param numb: The number to be appended to the name, starts at 0 
    270261        """ 
    271262        if dictionary.get(name) is not None: 
    272             i += 1 
     263            numb += 1 
    273264            name = name.split("_")[0] 
    274             name += "_{0}".format(i) 
    275             name = self._create_unique_key(dictionary, name, i) 
     265            name += "_{0}".format(numb) 
     266            name = self._create_unique_key(dictionary, name, numb) 
    276267        return name 
    277268     
     
    284275         
    285276        :param new_current_level: cansas_constants level as returned by  
    286             _iterate_namespace 
     277            iterate_namespace 
    287278        :param attr: The attributes of the node 
    288279        :param data1d: Where the values will be saved 
     
    318309                            return 
    319310                        except: 
    320                             err_msg = "CanSAS reader: could not convert the units" 
     311                            err_msg = \ 
     312                                "CanSAS reader: could not convert the units" 
    321313                            self.errors.append(err_msg) 
    322314                            return 
     
    343335        return node_value, value_unit 
    344336     
    345     def _parse_entry(self, dom, ns, data1d, extras = []): 
     337    def _parse_entry(self, dom, names=["SASentry"], data1d=None, extras=[]): 
    346338        """ 
    347339        Parse a SASEntry - new recursive method for parsing the dom of 
     
    349341            and extra nodes to be read in simultaneously. 
    350342         
    351         :param dom: dom object with a namespace base of ns 
    352         :param ns: A list of element names that lead up to the dom object 
     343        :param dom: dom object with a namespace base of names 
     344        :param names: A list of element names that lead up to the dom object 
    353345        :param data1d: The data1d object that will be modified 
    354346        :param extras: Any values that should go into meta_data when data1d 
    355347            is not a Data1D object 
    356348        """ 
    357           
     349         
    358350        # A portion of every namespace entry 
     351        if data1d == None: 
     352            x_vals = numpy.empty(0) 
     353            y_vals = numpy.empty(0) 
     354            dx_vals = numpy.empty(0) 
     355            dy_vals = numpy.empty(0) 
     356            dxl = numpy.empty(0) 
     357            dxw = numpy.empty(0) 
     358            data1d = Data1D(x_vals, y_vals, dx_vals, dy_vals) 
     359            data1d.dxl = dxl 
     360            data1d.dxw = dxw 
     361                             
    359362        base_ns = "{0}{1}{2}".format("{", \ 
    360363                            CANSAS_NS.get(self.cansas_version).get("ns"), "}") 
     
    366369        for node in dom: 
    367370            try: 
    368                 # Get the element name and set the current ns level 
     371                # Get the element name and set the current names level 
    369372                tagname = node.tag.replace(base_ns, "") 
    370373                tagname_original = tagname 
    371                 ns.append(tagname) 
     374                if tagname == "fitting_plug_in": 
     375                    continue 
     376                names.append(tagname) 
    372377                attr = node.attrib 
    373378                children = node.getchildren() 
     379                if len(children) == 0: 
     380                    children = None 
    374381                save_data1d = data1d 
    375382                 
     
    410417                                 
    411418                # Get where to store content 
    412                 cs_values = constants._iterate_namespace(ns) 
     419                cs_values = CONSTANTS.iterate_namespace(names) 
    413420                # If the element is a child element, recurse 
    414421                if children is not None: 
    415422                    # Returned value is new Data1D object with all previous and  
    416423                    # new values in it. 
    417                     data1d, extras = self._parse_entry(node, ns, data1d, extras) 
     424                    data1d, extras = self._parse_entry(node,  
     425                                                       names, data1d, extras) 
    418426                     
    419427                #Get the information from the node 
     
    488496                            pass 
    489497             
    490             except TypeError: 
     498            except TypeError as e: 
    491499                pass 
    492500            except Exception as e: 
     
    509517                else: 
    510518                    save_data1d = data1d 
    511                 data1d = save_data1d 
    512                 # Remove tagname from ns to restore original base 
    513                 ns.remove(tagname_original) 
    514          
     519                if tagname_original != "fitting_plug_in": 
     520                    data1d = save_data1d 
     521                    # Remove tagname from names to restore original base 
     522                    names.remove(tagname_original) 
    515523        return data1d, extras 
    516524         
     525     
    517526    def _to_xml_doc(self, datainfo): 
    518527        """ 
     
    526535         
    527536        # Get PIs and create root element 
    528         pis = self.reader.return_processing_instructions() 
    529         doc = self.reader.create_tree(pis[0]) 
    530         i = 1 
    531         for i in range(1,len(pis) - 1): 
    532             doc = self.reader.append(pis[i], doc) 
     537        pis = self.return_processing_instructions() 
     538        if len(pis) > 0: 
     539            pi_tree = self.create_tree(pis[0]) 
     540            i = 1 
     541            for i in range(1,len(pis) - 1): 
     542                pi_tree = self.append(pis[i], pi_tree) 
     543            pi_string = self.to_string(pi_tree) 
     544        else: 
     545            pi_string = "" 
    533546         
    534547        # Define namespaces and create SASroot object 
     
    540553        else: 
    541554            url = "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/" 
    542         schemaLocation = "{0} {1}cansas1d.xsd".format(ns, url) 
    543         attrib = {"{" + xsi + "}schemaLocation" : schemaLocation, 
     555        schema_location = "{0} {1}cansas1d.xsd".format(ns, url) 
     556        attrib = {"{" + xsi + "}schemaLocation" : schema_location, 
    544557                  "version" : version} 
    545558        nsmap = {'xsi' : xsi, None: ns} 
    546559         
    547         main_node = self.reader.create_element("{" + ns + "}SASroot", \ 
     560        main_node = self.create_element("{" + ns + "}SASroot", \ 
    548561                                               attrib = attrib, \ 
    549562                                               nsmap = nsmap) 
    550563         
    551564        # Create ElementTree, append SASroot and apply processing instructions 
    552         base_string = self.reader.toString(doc) + \ 
    553                     self.reader.toString(main_node) 
    554         base_element = self.reader.create_element_from_string(base_string) 
    555         doc = self.reader.create_tree(base_element) 
     565        base_string = pi_string + self.to_string(main_node) 
     566        base_element = self.create_element_from_string(base_string) 
     567        doc = self.create_tree(base_element) 
    556568         
    557569        # Create SASentry Element 
    558         entry_node = self.reader.create_element("SASentry") 
     570        entry_node = self.create_element("SASentry") 
    559571        root = doc.getroot() 
    560572        root.append(entry_node) 
     
    576588         
    577589        # Data info 
    578         node = self.reader.create_element("SASdata") 
    579         self.reader.append(node, entry_node) 
     590        node = self.create_element("SASdata") 
     591        self.append(node, entry_node) 
    580592         
    581593        for i in range(len(datainfo.x)): 
    582             pt = self.reader.create_element("Idata") 
     594            pt = self.create_element("Idata") 
    583595            node.append(pt) 
    584596            self.write_node(pt, "Q", datainfo.x[i], {'unit': datainfo.x_unit}) 
     
    598610                self.write_node(pt, "dQl", datainfo.dxl[i], 
    599611                            {'unit': datainfo.x_unit}) 
    600  
     612         
    601613        # Transmission Spectrum Info 
    602614        for i in range(len(datainfo.trans_spectrum)): 
    603615            spectrum = datainfo.trans_spectrum[i] 
    604             node = self.reader.create_element("SAStransmission_spectrum", 
     616            node = self.create_element("SAStransmission_spectrum", 
    605617                                              {"name" : spectrum.name}) 
    606             self.reader.append(node, entry_node) 
     618            self.append(node, entry_node) 
    607619            if isinstance(spectrum.timestamp, datetime.datetime): 
    608620                node.setAttribute("timestamp", spectrum.timestamp) 
    609621            for i in range(len(spectrum.wavelength)): 
    610                 pt = self.reader.create_element("Tdata") 
     622                pt = self.create_element("Tdata") 
    611623                node.append(pt) 
    612624                self.write_node(pt, "Lambda", spectrum.wavelength[i],  
     
    621633 
    622634        # Sample info 
    623         sample = self.reader.create_element("SASsample") 
     635        sample = self.create_element("SASsample") 
    624636        if datainfo.sample.name is not None: 
    625             self.reader.write_attribute(sample,  
     637            self.write_attribute(sample,  
    626638                                        "name",  
    627639                                        str(datainfo.sample.name)) 
    628         self.reader.append(sample, entry_node) 
     640        self.append(sample, entry_node) 
    629641        self.write_node(sample, "ID", str(datainfo.sample.ID)) 
    630642        self.write_node(sample, "thickness", datainfo.sample.thickness, 
     
    634646                   {"unit": datainfo.sample.temperature_unit}) 
    635647         
    636         pos = self.reader.create_element("position") 
     648        pos = self.create_element("position") 
    637649        written = self.write_node(pos,  
    638650                                  "x",  
     
    648660                                       {"unit": datainfo.sample.position_unit}) 
    649661        if written == True: 
    650             self.reader.append(pos, sample) 
    651          
    652         ori = self.reader.create_element("orientation") 
     662            self.append(pos, sample) 
     663         
     664        ori = self.create_element("orientation") 
    653665        written = self.write_node(ori, "roll", 
    654666                                  datainfo.sample.orientation.x, 
     
    661673                                    {"unit": datainfo.sample.orientation_unit}) 
    662674        if written == True: 
    663             self.reader.append(ori, sample) 
     675            self.append(ori, sample) 
    664676         
    665677        for item in datainfo.sample.details: 
     
    667679         
    668680        # Instrument info 
    669         instr = self.reader.create_element("SASinstrument") 
    670         self.reader.append(instr, entry_node) 
     681        instr = self.create_element("SASinstrument") 
     682        self.append(instr, entry_node) 
    671683         
    672684        self.write_node(instr, "name", datainfo.instrument) 
    673685         
    674686        #   Source 
    675         source = self.reader.create_element("SASsource") 
     687        source = self.create_element("SASsource") 
    676688        if datainfo.source.name is not None: 
    677             self.reader.write_attribute(source, 
     689            self.write_attribute(source, 
    678690                                        "name", 
    679691                                        str(datainfo.source.name)) 
    680         self.reader.append(source, instr) 
     692        self.append(source, instr) 
    681693        if datainfo.source.radiation == None or datainfo.source.radiation == '': 
    682694            datainfo.source.radiation = "neutron" 
    683695        self.write_node(source, "radiation", datainfo.source.radiation) 
    684696         
    685         size = self.reader.create_element("beam_size") 
     697        size = self.create_element("beam_size") 
    686698        if datainfo.source.beam_size_name is not None: 
    687             self.reader.write_attribute(size, 
     699            self.write_attribute(size, 
    688700                                        "name", 
    689701                                        str(datainfo.source.beam_size_name)) 
     
    697709                                       {"unit": datainfo.source.beam_size_unit}) 
    698710        if written == True: 
    699             self.reader.append(size, source) 
     711            self.append(size, source) 
    700712             
    701713        self.write_node(source, "beam_shape", datainfo.source.beam_shape) 
     
    718730            datainfo.collimation.append(coll) 
    719731        for item in datainfo.collimation: 
    720             coll = self.reader.create_element("SAScollimation") 
     732            coll = self.create_element("SAScollimation") 
    721733            if item.name is not None: 
    722                 self.reader.write_attribute(coll, "name", str(item.name)) 
    723             self.reader.append(coll, instr) 
     734                self.write_attribute(coll, "name", str(item.name)) 
     735            self.append(coll, instr) 
    724736             
    725737            self.write_node(coll, "length", item.length, 
     
    727739             
    728740            for apert in item.aperture: 
    729                 ap = self.reader.create_element("aperture") 
     741                ap = self.create_element("aperture") 
    730742                if apert.name is not None: 
    731                     self.reader.write_attribute(ap, "name", str(apert.name)) 
     743                    self.write_attribute(ap, "name", str(apert.name)) 
    732744                if apert.type is not None: 
    733                     self.reader.write_attribute(ap, "type", str(apert.type)) 
    734                 self.reader.append(ap, coll) 
    735                  
    736                 size = self.reader.create_element("size") 
     745                    self.write_attribute(ap, "type", str(apert.type)) 
     746                self.append(ap, coll) 
     747                 
     748                size = self.create_element("size") 
    737749                if apert.size_name is not None: 
    738                     self.reader.write_attribute(size,  
     750                    self.write_attribute(size,  
    739751                                                "name",  
    740752                                                str(apert.size_name)) 
     
    746758                                               {"unit": apert.size_unit}) 
    747759                if written == True: 
    748                     self.reader.append(size, ap) 
     760                    self.append(size, ap) 
    749761                 
    750762                self.write_node(ap, "distance", apert.distance, 
     
    758770                 
    759771        for item in datainfo.detector: 
    760             det = self.reader.create_element("SASdetector") 
     772            det = self.create_element("SASdetector") 
    761773            written = self.write_node(det, "name", item.name) 
    762774            written = written | self.write_node(det, "SDD", item.distance, 
    763775                                           {"unit": item.distance_unit}) 
    764776            if written == True: 
    765                 self.reader.append(det, instr) 
     777                self.append(det, instr) 
    766778             
    767             off = self.reader.create_element("offset") 
     779            off = self.create_element("offset") 
    768780            written = self.write_node(off, "x", item.offset.x, 
    769781                                 {"unit": item.offset_unit}) 
     
    773785                                           {"unit": item.offset_unit}) 
    774786            if written == True: 
    775                 self.reader.append(off, det) 
    776                  
    777             ori = self.reader.create_element("orientation") 
     787                self.append(off, det) 
     788                 
     789            ori = self.create_element("orientation") 
    778790            written = self.write_node(ori, "roll", item.orientation.x, 
    779791                                 {"unit": item.orientation_unit}) 
     
    785797                                           {"unit": item.orientation_unit}) 
    786798            if written == True: 
    787                 self.reader.append(ori, det) 
     799                self.append(ori, det) 
    788800             
    789             center = self.reader.create_element("beam_center") 
     801            center = self.create_element("beam_center") 
    790802            written = self.write_node(center, "x", item.beam_center.x, 
    791803                                 {"unit": item.beam_center_unit}) 
     
    797809                                           {"unit": item.beam_center_unit}) 
    798810            if written == True: 
    799                 self.reader.append(center, det) 
    800                  
    801             pix = self.reader.create_element("pixel_size") 
     811                self.append(center, det) 
     812                 
     813            pix = self.create_element("pixel_size") 
    802814            written = self.write_node(pix, "x", item.pixel_size.x, 
    803815                                 {"unit": item.pixel_size_unit}) 
     
    810822                                           {"unit": item.slit_length_unit}) 
    811823            if written == True: 
    812                 self.reader.append(pix, det) 
     824                self.append(pix, det) 
    813825             
    814826        # Processes info 
    815827        for item in datainfo.process: 
    816             node = self.reader.create_element("SASprocess") 
    817             self.reader.append(node, entry_node) 
     828            node = self.create_element("SASprocess") 
     829            self.append(node, entry_node) 
    818830 
    819831            self.write_node(node, "name", item.name) 
     
    831843        # Note info 
    832844        if len(datainfo.notes) == 0: 
    833             node = self.reader.create_element("SASnote") 
    834             self.reader.append(node, entry_node) 
     845            node = self.create_element("SASnote") 
     846            self.append(node, entry_node) 
    835847        else: 
    836848            for item in datainfo.notes: 
    837                 node = self.reader.create_element("SASnote") 
    838                 self.reader.write_text(node, item) 
    839                 self.reader.append(node, entry_node) 
     849                node = self.create_element("SASnote") 
     850                self.write_text(node, item) 
     851                self.append(node, entry_node) 
    840852                 
    841853         
    842854        # Return the document, and the SASentry node associated with 
    843855        # the data we just wrote 
     856         
     857        frm = inspect.stack()[1] 
     858        mod = inspect.getmodule(frm[0]) 
     859        mod_name = mod.__name__ 
     860        if mod_name != "sans.dataloader.readers.cansas_reader": 
     861            string = self.to_string(doc, pp=True) 
     862            doc = parseString(string) 
     863            node_name = entry_node.tag 
     864            node_list = doc.getElementsByTagName(node_name) 
     865            entry_node = node_list.item(0) 
     866         
    844867        return doc, entry_node 
    845868     
    846869     
    847     def write_node(self, parent, name, value, attr={}): 
     870    def write_node(self, parent, name, value, attr=None): 
    848871        """ 
    849872        :param doc: document DOM 
     
    856879        """ 
    857880        if value is not None: 
    858             parent = self.reader.ebuilder(parent, name, value, attr) 
     881            parent = self.ebuilder(parent, name, value, attr) 
    859882            return True 
    860883        return False 
     
    872895        # Write the file 
    873896        fd = open(filename, 'w') 
    874         if self.reader.encoding == None: 
    875             self.reader.encoding = "UTF-8" 
    876         doc.write(fd, encoding=self.reader.encoding, 
     897        if self.encoding == None: 
     898            self.encoding = "UTF-8" 
     899        doc.write(fd, encoding=self.encoding, 
    877900                  pretty_print=True, xml_declaration=True) 
    878901        fd.close() 
    879902     
     903     
     904    # DO NOT REMOVE - used in saving and loading panel states. 
     905    def _store_float(self, location, node, variable, storage, optional=True): 
     906        """ 
     907        Get the content of a xpath location and store 
     908        the result. Check that the units are compatible 
     909        with the destination. The value is expected to 
     910        be a float. 
     911         
     912        The xpath location might or might not exist. 
     913        If it does not exist, nothing is done 
     914        
     915        :param location: xpath location to fetch 
     916        :param node: node to read the data from 
     917        :param variable: name of the data member to store it in [string] 
     918        :param storage: data object that has the 'variable' data member 
     919        :param optional: if True, no exception will be raised 
     920            if unit conversion can't be done 
     921 
     922        :raise ValueError: raised when the units are not recognized 
     923        """ 
     924        entry = get_content(location, node) 
     925        try: 
     926            value = float(entry.text) 
     927        except: 
     928            value = None 
     929             
     930        if value is not None: 
     931            # If the entry has units, check to see that they are 
     932            # compatible with what we currently have in the data object 
     933            units = entry.get('unit') 
     934            if units is not None: 
     935                toks = variable.split('.') 
     936                local_unit = None 
     937                exec "local_unit = storage.%s_unit" % toks[0] 
     938                if local_unit != None and units.lower() != local_unit.lower(): 
     939                    if HAS_CONVERTER == True: 
     940                        try: 
     941                            conv = Converter(units) 
     942                            exec "storage.%s = %g" % (variable, 
     943                                           conv(value, units=local_unit)) 
     944                        except: 
     945                            err_mess = "CanSAS reader: could not convert" 
     946                            err_mess += " %s unit [%s]; expecting [%s]\n  %s" \ 
     947                                % (variable, units, local_unit, sys.exc_value) 
     948                            self.errors.append(err_mess) 
     949                            if optional: 
     950                                logging.info(err_mess) 
     951                            else: 
     952                                raise ValueError, err_mess 
     953                    else: 
     954                        err_mess = "CanSAS reader: unrecognized %s unit [%s];"\ 
     955                        % (variable, units) 
     956                        err_mess += " expecting [%s]" % local_unit 
     957                        self.errors.append(err_mess) 
     958                        if optional: 
     959                            logging.info(err_mess) 
     960                        else: 
     961                            raise ValueError, err_mess 
     962                else: 
     963                    exec "storage.%s = value" % variable 
     964            else: 
     965                exec "storage.%s = value" % variable 
     966                 
     967     
     968    # DO NOT REMOVE - used in saving and loading panel states. 
     969    def _store_content(self, location, node, variable, storage): 
     970        """ 
     971        Get the content of a xpath location and store 
     972        the result. The value is treated as a string. 
     973         
     974        The xpath location might or might not exist. 
     975        If it does not exist, nothing is done 
     976         
     977        :param location: xpath location to fetch 
     978        :param node: node to read the data from 
     979        :param variable: name of the data member to store it in [string] 
     980        :param storage: data object that has the 'variable' data member 
     981         
     982        :return: return a list of errors 
     983        """ 
     984        entry = get_content(location, node) 
     985        if entry is not None and entry.text is not None: 
     986            exec "storage.%s = entry.text.strip()" % variable 
Note: See TracChangeset for help on using the changeset viewer.