Changeset b1f7ec6 in sasview


Ignore:
Timestamp:
Sep 10, 2009 8:39:01 PM (15 years ago)
Author:
Mathieu Doucet <doucetm@…>
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:
72f719b
Parents:
aeb3c20
Message:

prview: fixed loading of .prv files

File:
1 edited

Legend:

Unmodified
Added
Removed
  • prview/perspectives/pr/inversion_state.py

    r0d88a09 rb1f7ec6  
    88copyright 2009, University of Tennessee 
    99""" 
    10 import time, os 
     10import time, os, sys 
    1111import logging 
    1212import DataLoader 
     13from xml.dom.minidom import parse 
     14from lxml import etree 
     15 
    1316from DataLoader.readers.cansas_reader import Reader as CansasReader 
     17from DataLoader.readers.cansas_reader import get_content 
    1418 
    1519PRNODE_NAME = 'pr_inversion' 
     20CANSAS_NS = "cansas1d/1.0" 
    1621 
    1722## List of P(r) inversion inputs  
     
    213218        """ 
    214219        if file is not None: 
    215             # Check whether the file is valid 
    216             if not os.path.isfile(file): 
    217                 raise  RuntimeError, "P(r) reader: cannot open %s" % file 
    218          
    219             from xml.dom.minidom import parse 
    220             doc = parse(file) 
    221             node = doc.documentElement 
    222              
    223         if node.tagName == PRNODE_NAME: 
    224             if node.hasAttribute('version')\ 
    225                 and node.getAttribute('version') == '1.0': 
     220            raise RuntimeError, "InversionState no longer supports non-CanSAS format for P(r) files" 
     221             
     222        if node.get('version')\ 
     223            and node.get('version') == '1.0': 
     224             
     225            # Get file name 
     226            entry = get_content('ns:filename', node) 
     227            if entry is not None: 
     228                self.file = entry.text.strip() 
     229             
     230            # Get time stamp 
     231            entry = get_content('ns:timestamp', node) 
     232            if entry is not None and entry.get('epoch'): 
     233                try: 
     234                    self.timestamp = float(entry.get('epoch')) 
     235                except: 
     236                    logging.error("InversionState.fromXML: Could not read timestamp\n %s" % sys.exc_value) 
     237             
     238            # Parse inversion inputs 
     239            entry = get_content('ns:inputs', node) 
     240            if entry is not None: 
     241                for item in in_list: 
     242                    input_field = get_content('ns:%s' % item[0], entry) 
     243                    if input_field is not None: 
     244                        try: 
     245                            exec '%s = float(input_field.text.strip())' % item[1] 
     246                        except: 
     247                            exec '%s = None' % item[1] 
     248                input_field = get_content('ns:estimate_bck', entry) 
     249                if input_field is not None: 
     250                    try: 
     251                        self.estimate_bck = input_field.text.strip()=='True' 
     252                    except: 
     253                        self.estimate_bck = False 
     254                     
     255            # Parse inversion outputs 
     256            entry = get_content('ns:outputs', node) 
     257            if entry is not None: 
     258                # Output parameters (scalars) 
     259                for item in out_list: 
     260                    input_field = get_content('ns:%s' % item[0], entry) 
     261                    if input_field is not None: 
     262                        try: 
     263                            exec '%s = float(input_field.text.strip())' % item[1] 
     264                        except: 
     265                            exec '%s = None' % item[1] 
     266             
     267                # Look for coefficients 
     268                # Format is [value, value, value, value] 
     269                coeff = get_content('ns:coefficients', entry) 
     270                if coeff is not None: 
     271                    # Remove brackets 
     272                    c_values = coeff.text.strip().replace('[','') 
     273                    c_values = c_values.replace(']','') 
     274                    toks = c_values.split() 
     275                    self.coefficients = [] 
     276                    for c in toks: 
     277                        try: 
     278                            self.coefficients.append(float(c)) 
     279                        except: 
     280                            # Bad data, skip. We will count the number of  
     281                            # coefficients at the very end and deal with  
     282                            # inconsistencies then. 
     283                            pass 
     284                    # Sanity check 
     285                    if not len(self.coefficients) == self.nfunc: 
     286                        # Inconsistent number of coefficients. Don't keep the data. 
     287                        err_msg = "InversionState.fromXML: inconsistant number of coefficients: " 
     288                        err_msg += "%d %d" % (len(self.coefficients), self.nfunc) 
     289                        logging.error(err_msg) 
     290                        self.coefficients = None 
    226291                 
    227                 if node.hasChildNodes(): 
    228                     for node in node.childNodes: 
    229                         if node.nodeName == 'filename': 
    230                             if node.hasChildNodes(): 
    231                                 self.file = node.childNodes[0].nodeValue.strip() 
    232                         elif node.nodeName == 'timestamp': 
    233                             if node.hasAttribute('epoch'): 
    234                                 try: 
    235                                     self.timestamp = float(node.getAttribute('epoch')) 
    236                                 except: 
    237                                     # Could not read timestamp: pass 
    238                                     pass 
    239                                  
    240                         # Parse inversion inputs 
    241                         elif node.nodeName == 'inputs': 
    242                             if node.hasChildNodes(): 
    243                                 for item in node.childNodes: 
    244                                     for out in in_list: 
    245                                         if item.nodeName == out[0]: 
    246                                             try: 
    247                                                 exec '%s = float(item.childNodes[0].nodeValue.strip())' % out[1] 
    248                                             except: 
    249                                                 exec '%s = None' % out[1] 
    250                                         elif item.nodeName == 'estimate_bck': 
    251                                             try: 
    252                                                 self.estimate_bck = item.childNodes[0].nodeValue.strip()=='True' 
    253                                             except: 
    254                                                 self.estimate_bck = False 
    255                              
    256                         # Parse inversion outputs 
    257                         elif node.nodeName == 'outputs': 
    258                             if node.hasChildNodes(): 
    259                                 for item in node.childNodes: 
    260                                     # Look for standard outputs 
    261                                     for out in out_list: 
    262                                         if item.nodeName == out[0]: 
    263                                             try: 
    264                                                 exec '%s = float(item.childNodes[0].nodeValue.strip())' % out[1] 
    265                                             except: 
    266                                                 exec '%s = None' % out[1] 
    267                                                  
    268                                     # Look for coefficients 
    269                                     # Format is [value, value, value, value] 
    270                                     if item.nodeName == 'coefficients': 
    271                                         # Remove brackets 
    272                                         c_values = item.childNodes[0].nodeValue.strip().replace('[','') 
    273                                         c_values = c_values.replace(']','') 
    274                                         toks = c_values.split() 
    275                                         self.coefficients = [] 
    276                                         for c in toks: 
    277                                             try: 
    278                                                 self.coefficients.append(float(c)) 
    279                                             except: 
    280                                                 # Bad data, skip. We will count the number of  
    281                                                 # coefficients at the very end and deal with  
    282                                                 # inconsistencies then. 
    283                                                 pass 
    284                                         # Sanity check 
    285                                         if not len(self.coefficients) == self.nfunc: 
    286                                             # Inconsistent number of coefficients. Don't keep the data. 
    287                                             err_msg = "InversionState.fromXML: inconsistant number of coefficients: " 
    288                                             err_msg += "%d %d" % (len(self.coefficients), self.nfunc) 
    289                                             logging.error(err_msg) 
    290                                             self.coefficients = None 
    291                                              
    292                                     # Look for covariance matrix 
    293                                     # Format is [ [value, value], [value, value] ] 
    294                                     elif item.nodeName == "covariance": 
    295                                         # Parse rows 
    296                                         rows = item.childNodes[0].nodeValue.strip().split('[') 
    297                                         self.covariance = [] 
    298                                         for row in rows: 
    299                                             row = row.strip() 
    300                                             if len(row) == 0: continue 
    301                                             # Remove end bracket 
    302                                             row = row.replace(']','') 
    303                                             c_values = row.split() 
    304                                             cov_row = [] 
    305                                             for c in c_values: 
    306                                                 try: 
    307                                                     cov_row.append(float(c)) 
    308                                                 except: 
    309                                                     # Bad data, skip. We will count the number of  
    310                                                     # coefficients at the very end and deal with  
    311                                                     # inconsistencies then. 
    312                                                     pass 
    313                                             # Sanity check: check the number of entries in the row 
    314                                             if len(cov_row) == self.nfunc: 
    315                                                 self.covariance.append(cov_row) 
    316                                         # Sanity check: check the number of rows in the covariance 
    317                                         # matrix 
    318                                         if not len(self.covariance) == self.nfunc: 
    319                                             # Inconsistent dimensions of the covariance matrix. 
    320                                             # Don't keep the data. 
    321                                             err_msg = "InversionState.fromXML: inconsistant dimensions of the covariance matrix: " 
    322                                             err_msg += "%d %d" % (len(self.covariance), self.nfunc) 
    323                                             logging.error(err_msg) 
    324                                             self.covariance = None 
    325             else: 
    326                 raise RuntimeError, "Unsupported P(r) file version" 
    327          
    328                      
     292                # Look for covariance matrix 
     293                # Format is [ [value, value], [value, value] ] 
     294                coeff = get_content('ns:covariance', entry) 
     295                if coeff is not None: 
     296                    # Parse rows 
     297                    rows = coeff.text.strip().split('[') 
     298                    self.covariance = [] 
     299                    for row in rows: 
     300                        row = row.strip() 
     301                        if len(row) == 0: continue 
     302                        # Remove end bracket 
     303                        row = row.replace(']','') 
     304                        c_values = row.split() 
     305                        cov_row = [] 
     306                        for c in c_values: 
     307                            try: 
     308                                cov_row.append(float(c)) 
     309                            except: 
     310                                # Bad data, skip. We will count the number of  
     311                                # coefficients at the very end and deal with  
     312                                # inconsistencies then. 
     313                                pass 
     314                        # Sanity check: check the number of entries in the row 
     315                        if len(cov_row) == self.nfunc: 
     316                            self.covariance.append(cov_row) 
     317                    # Sanity check: check the number of rows in the covariance 
     318                    # matrix 
     319                    if not len(self.covariance) == self.nfunc: 
     320                        # Inconsistent dimensions of the covariance matrix. 
     321                        # Don't keep the data. 
     322                        err_msg = "InversionState.fromXML: inconsistant dimensions of the covariance matrix: " 
     323                        err_msg += "%d %d" % (len(self.covariance), self.nfunc) 
     324                        logging.error(err_msg) 
     325                        self.covariance = None 
     326     
    329327class Reader(CansasReader): 
    330328    """ 
     
    387385            @return: InversionState object 
    388386        """ 
    389         from xml import xpath 
    390  
    391387        # Create an empty state 
    392388        state = InversionState() 
     
    394390        # Locate the P(r) node 
    395391        try: 
    396             nodes = xpath.Evaluate(PRNODE_NAME, entry) 
     392            nodes = entry.xpath('ns:%s' % PRNODE_NAME, namespaces={'ns': CANSAS_NS}) 
    397393            state.fromXML(node=nodes[0]) 
    398394        except: 
    399             #raise RuntimeError, "%s is not a file with P(r) information." % path 
    400             logging.info("XML document does not contain P(r) information.") 
    401             import sys 
    402             print sys.exc_value 
     395            logging.info("XML document does not contain P(r) information.\n %s" % sys.exc_value) 
    403396             
    404397        return state 
     
    415408            @raise ValueError: when the length of the data vectors are inconsistent 
    416409        """ 
    417         from xml.dom.minidom import parse 
    418         from xml import xpath 
    419410        output = [] 
    420411         
     
    427418                extension.lower() == '.xml': 
    428419                 
    429                 dom = parse(path) 
     420                tree = etree.parse(path, parser=etree.ETCompatXMLParser()) 
     421                # Check the format version number 
     422                # Specifying the namespace will take care of the file format version  
     423                root = tree.getroot() 
    430424                 
    431                 # Format 1: check whether we have a CanSAS file 
    432                 nodes = xpath.Evaluate('SASroot', dom) 
    433                 # Check the format version number 
    434                 if nodes[0].hasAttributes(): 
    435                     for i in range(nodes[0].attributes.length): 
    436                         if nodes[0].attributes.item(i).nodeName=='version': 
    437                             if nodes[0].attributes.item(i).nodeValue != self.version: 
    438                                 raise ValueError, "cansas_reader: unrecognized version number %s" % \ 
    439                                     nodes[0].attributes.item(i).nodeValue 
    440                  
    441                 entry_list = xpath.Evaluate('SASroot/SASentry', dom) 
     425                entry_list = root.xpath('/ns:SASroot/ns:SASentry', namespaces={'ns': CANSAS_NS}) 
     426 
    442427                for entry in entry_list: 
    443428                    sas_entry = self._parse_entry(entry) 
     
    490475            prstate.toXML(file=filename) 
    491476         
    492          
    493 if __name__ == "__main__":  
    494     #TODO: turn all this into unit tests 
    495      
    496     state = InversionState() 
    497     #print state.fromXML('../../test/pr_state.prv')      
    498     print state.fromXML('../../test/test.prv')      
    499     print state    
    500     state.toXML('test_copy.prv') 
    501      
    502     from DataLoader.loader import Loader 
    503     l = Loader() 
    504     datainfo = l.load("../../test/cansas1d.xml") 
    505      
    506     def call_back(state, datainfo=None): 
    507         print state 
    508          
    509     reader = Reader(call_back) 
    510     reader.cansas = False 
    511     reader.write("test_copy_from_reader.prv", prstate=state) 
    512     reader.cansas = True 
    513     reader.write("testout.prv", datainfo, state) 
    514     reader.write("testout_wo_datainfo.prv", prstate=state) 
    515      
    516     # Now try to load things back 
    517     reader.cansas = False 
    518     #print reader.read("test_copy_from_reader.prv") 
    519     reader.cansas = True 
    520     #data = reader.read("testout.prv") 
    521     data = reader.read("testout_wo_datainfo.prv") 
    522     print data 
    523     print data.meta_data['prstate'] 
    524      
    525      
     477     
     478     
Note: See TracChangeset for help on using the changeset viewer.