Ignore:
Timestamp:
Dec 24, 2013 1:32:14 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:
81b524f
Parents:
a25d242
Message:

Pushing this here before I merge with trunk to be sure I don't lose anything.

File:
1 edited

Legend:

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

    reda8972 r75eeb425  
    123123    errors = [] 
    124124     
     125    type_name = "canSAS" 
     126     
     127    ## Wildcards 
     128    type = ["XML files (*.xml)|*.xml"] 
     129    ## List of allowed extensions 
     130    ext = ['.xml', '.XML'] 
     131     
     132    ## Flag to bypass extension check 
     133    allow_all = True 
     134     
    125135    def __init__(self): 
    126136        ## List of errors 
     
    156166        ns = [] 
    157167         
    158         try: 
    159             # Load in the xml file and get the cansas version from the header 
    160             self.reader.setXMLFile(xml) 
    161             root = self.reader.xmlroot 
    162             self.cansasVersion = root.get("version") 
    163             # Generic values for the cansas file based on the version 
    164             cansas_defaults = CANSAS_NS.get(self.cansasVersion) 
    165          
    166             # Link a schema to the XML file. 
     168        # Check that the file exists 
     169        if os.path.isfile(xml): 
    167170            basename = os.path.basename(xml) 
    168             base_name = xml_reader.__file__ 
    169             base = base_name.split("\\sans\\")[0] 
    170             schema_path = "{0}\\sans\\dataloader\\readers\\schema\\{1}".format(base, cansas_defaults.get("schema")).replace("\\", "/") 
    171             self.reader.setSchema(schema_path) 
    172          
    173             # Try to load the file, but raise an error if unable to. 
    174             # Check the file matches the XML schema 
    175             if self.isCansas(): 
    176                 # Get each SASentry from the XML file and add it to a list. 
    177                 entry_list = root.xpath('/ns:SASroot/ns:SASentry', 
    178                                              namespaces={'ns': cansas_defaults.get("ns")}) 
    179                 ns.append("SASentry") 
    180                  
    181                 # If there are multiple files, modify the name for each is unique 
    182                 multipleFiles = len(entry_list) - 1 
    183                 n = 0 
    184                 name = basename 
    185                 # Parse each SASentry item 
    186                 for entry in entry_list: 
    187                      
    188                     # Define a new Data1D object with zeroes for x and y 
    189                     data1D = Data1D(x,y,dx,dy) 
    190                     data1D.dxl = dxl 
    191                     data1D.dxw = dxw 
    192                      
    193                     # If more than one SASentry, number each in order 
    194                     if multipleFiles: 
    195                         name += "_{0}".format(n) 
    196                         n += 1 
    197                      
    198                     # Set the Data1D name and then parse the entry. The entry is appended to a list of entry values 
    199                     data1D.filename = name 
    200                     data1D.meta_data["loader"] = "CanSAS 1D" 
    201                     return_value, extras = self._parse_entry(entry, ns, data1D) 
    202                     del extras[:] 
    203                      
    204                     #Final cleanup - Remove empty nodes, verify array sizes are correct 
    205                     return_value.errors = self.errors 
    206                     del self.errors[:] 
    207                     numpy.trim_zeros(return_value.x) 
    208                     numpy.trim_zeros(return_value.y) 
    209                     numpy.trim_zeros(return_value.dy) 
    210                     size_dx = return_value.dx.size 
    211                     size_dxl = return_value.dxl.size 
    212                     size_dxw = return_value.dxw.size 
    213                     if size_dxl == 0 and size_dxw == 0: 
    214                         return_value.dxl = None 
    215                         return_value.dxw = None 
    216                         numpy.trim_zeros(return_value.dx) 
    217                     elif size_dx == 0: 
    218                         return_value.dx = None 
    219                         size_dx = size_dxl 
    220                         numpy.trim_zeros(return_value.dxl) 
    221                         numpy.trim_zeros(return_value.dxw) 
    222                      
    223                     output.append(return_value) 
    224             else: 
    225                 # If the file does not match the schema, raise this error 
    226                 raise RuntimeError, "%s cannot be read \n" % xml 
    227         # If an exception occurs while loading the file, give a descriptive output. 
    228         except Exception: 
    229             raise RuntimeError, "%s cannot be read \n" % xml 
     171            _, extension = os.path.splitext(basename) 
     172            # If the fiel type is not allowed, return nothing 
     173            if extension in self.ext or self.allow_all: 
     174                base_name = xml_reader.__file__ 
     175                base = base_name.split("\\sans\\")[0] 
     176                 
     177                # Load in the xml file and get the cansas version from the header 
     178                self.reader.setXMLFile(xml) 
     179                root = self.reader.xmlroot 
     180                if root is None: 
     181                    root = {} 
     182                self.cansasVersion = root.get("version", "1.0") 
     183                 
     184                # Generic values for the cansas file based on the version 
     185                cansas_defaults = CANSAS_NS.get(self.cansasVersion, "1.0") 
     186                schema_path = "{0}\\sans\\dataloader\\readers\\schema\\{1}".format(base, cansas_defaults.get("schema")).replace("\\", "/") 
     187                 
     188                # Link a schema to the XML file. 
     189                self.reader.setSchema(schema_path) 
    230190             
     191                # Try to load the file, but raise an error if unable to. 
     192                # Check the file matches the XML schema 
     193                try: 
     194                    if self.isCansas(): 
     195                        # Get each SASentry from the XML file and add it to a list. 
     196                        entry_list = root.xpath('/ns:SASroot/ns:SASentry', 
     197                                                     namespaces={'ns': cansas_defaults.get("ns")}) 
     198                        ns.append("SASentry") 
     199                         
     200                        # If there are multiple files, modify the name for each is unique 
     201                        multipleFiles = len(entry_list) - 1 
     202                        n = 0 
     203                        name = basename 
     204                        # Parse each SASentry item 
     205                        for entry in entry_list: 
     206                             
     207                            # Define a new Data1D object with zeroes for x and y 
     208                            data1D = Data1D(x,y,dx,dy) 
     209                            data1D.dxl = dxl 
     210                            data1D.dxw = dxw 
     211                             
     212                            # If more than one SASentry, number each in order 
     213                            if multipleFiles: 
     214                                name += "_{0}".format(n) 
     215                                n += 1 
     216                             
     217                            # Set the Data1D name and then parse the entry. The entry is appended to a list of entry values 
     218                            data1D.filename = name 
     219                            data1D.meta_data["loader"] = "CanSAS 1D" 
     220                            return_value, extras = self._parse_entry(entry, ns, data1D) 
     221                            del extras[:] 
     222                             
     223                            #Final cleanup - Remove empty nodes, verify array sizes are correct 
     224                            for error in self.errors: 
     225                                return_value.errors.append(error) 
     226                            del self.errors[:] 
     227                            numpy.trim_zeros(return_value.x) 
     228                            numpy.trim_zeros(return_value.y) 
     229                            numpy.trim_zeros(return_value.dy) 
     230                            size_dx = return_value.dx.size 
     231                            size_dxl = return_value.dxl.size 
     232                            size_dxw = return_value.dxw.size 
     233                            if size_dxl == 0 and size_dxw == 0: 
     234                                return_value.dxl = None 
     235                                return_value.dxw = None 
     236                                numpy.trim_zeros(return_value.dx) 
     237                            elif size_dx == 0: 
     238                                return_value.dx = None 
     239                                size_dx = size_dxl 
     240                                numpy.trim_zeros(return_value.dxl) 
     241                                numpy.trim_zeros(return_value.dxw) 
     242                             
     243                            output.append(return_value) 
     244                    else: 
     245                        value = self.reader.findInvalidXML() 
     246                        output.append("Invalid XML at: {0}".format(value)) 
     247                except: 
     248                    # If the file does not match the schema, raise this error 
     249                    raise RuntimeError, "%s cannot be read \n" % xml 
     250                return output 
    231251        # Return a list of parsed entries that dataloader can manage 
    232         return output 
     252        return None 
    233253     
    234254    def _create_unique_key(self, dictionary, name, i): 
     
    264284    def _unit_conversion(self, new_current_level, attr, data1D, node_value, optional = True): 
    265285        value_unit = '' 
    266         if 'unit' in attr and 'unit' in new_current_level: 
     286        if 'unit' in attr and new_current_level.get('unit') is not None: 
    267287            try: 
    268288                if isinstance(node_value, float) is False: 
     
    270290                default_unit = None 
    271291                unitname = new_current_level.get("unit") 
    272                 exec "default_unit = data1D.{0}.lower()".format(unitname) 
    273                 local_unit = attr['unit'].lower() 
    274                 if local_unit != default_unit: 
     292                exec "default_unit = data1D.{0}".format(unitname) 
     293                local_unit = attr['unit'] 
     294                if local_unit.lower() != default_unit.lower() and local_unit is not None\ 
     295                    and local_unit.lower() != "none" and default_unit is not None: 
    275296                    if HAS_CONVERTER == True: 
    276297                        try: 
     
    279300                            exec "node_value = data_conv_q(node_value, units=data1D.{0})".format(unitname) 
    280301                        except: 
    281                             msg = "CanSAS reader: could not convert " 
    282                             msg += "Q unit [%s]; " % attr['unit'], 
    283                             exec "msg += \"expecting [%s]\n  %s\" % (data1D.{0}, sys.exc_info()[1])".format(unitname) 
    284                             raise ValueError, msg 
     302                            err_msg = "CanSAS reader: could not convert " 
     303                            err_msg += "Q unit {0}; ".format(local_unit) 
     304                            intermediate = "err_msg += \"expecting [{1}]  {2}\".format(data1D.{0}, sys.exc_info()[1])".format(unitname, "{0}", "{1}") 
     305                            exec intermediate 
     306                            self.errors.append(err_msg) 
     307                            if optional: 
     308                                logging.info(err_msg) 
     309                            else: 
     310                                raise ValueError, err_msg 
    285311                    else: 
    286312                        value_unit = local_unit 
    287                         err_mess = "CanSAS reader: unrecognized %s unit [%s];"\ 
     313                        err_msg = "CanSAS reader: unrecognized %s unit [%s];"\ 
    288314                        % (node_value, default_unit) 
    289                         err_mess += " expecting [%s]" % local_unit 
    290                         self.errors.append(err_mess) 
     315                        err_msg += " expecting [%s]" % local_unit 
     316                        self.errors.append(err_msg) 
    291317                        if optional: 
    292                             logging.info(err_mess) 
     318                            logging.info(err_msg) 
    293319                        else: 
    294                             raise ValueError, err_mess 
    295             except Exception as e: 
    296                 msg = "CanSAS reader: could not convert " 
    297                 msg += "Q unit [%s]; " % attr['unit'], 
    298                 exec "msg += \"expecting [%s]\n  %s\" % (data1D.{0}, sys.exc_info()[1])".format(unitname) 
    299                 self.errors.append(msg) 
    300                 raise ValueError, msg 
     320                            raise ValueError, err_msg 
     321                else: 
     322                    value_unit = local_unit 
     323            except: 
     324                err_msg = "CanSAS reader: could not convert " 
     325                err_msg += "Q unit [%s]; " % attr['unit'], 
     326                exec "err_msg += \"expecting [%s]\n  %s\" % (data1D.{0}, sys.exc_info()[1])".format(unitname) 
     327                self.errors.append(err_msg) 
     328                if optional: 
     329                    logging.info(err_msg) 
     330                else: 
     331                    raise ValueError, err_msg 
    301332        elif 'unit' in attr: 
    302333            value_unit = attr['unit'] 
     
    340371                            term_attr = {} 
    341372                            for attr in child.keys(): 
    342                                 term_attr[attr] = child.get(attr).strip() 
     373                                term_attr[attr] = ' '.join(child.get(attr).split()) 
    343374                            if child.text is not None: 
    344                                 term_attr['value'] = child.text.strip() 
    345                                 data1D.term.append(term_attr) 
     375                                term_attr['value'] = ' '.join(child.text.split()) 
     376                            data1D.term.append(term_attr) 
    346377                elif tagname == "aperture": 
    347378                    data1D = Aperture() 
     
    356387                #Get the information from the node 
    357388                node_value = node.text 
    358                 if node_value is not None: 
    359                     node_value = node_value.strip().replace("\r"," ").replace("\n"," ") 
    360389                if node_value == "": 
    361390                    node_value = None 
     391                if node_value is not None: 
     392                    node_value = ' '.join(node_value.split()) 
    362393                 
    363394                # If the value is a float, compile with units. 
    364395                if ns_datatype == "float": 
    365396                    # If an empty value is given, store as zero. 
    366                     if node_value is None: 
    367                         node_value = "0.0" 
    368                     elif node_value.isspace(): 
     397                    if node_value is None or node_value.isspace() or node_value.lower() == "nan": 
    369398                        node_value = "0.0" 
    370399                    node_value, unit = self._unit_conversion(new_current_level, attr, data1D, node_value, optional) 
     
    438467            raise RuntimeError, "The cansas writer expects a Data1D instance" 
    439468         
     469        ns = CANSAS_NS.get(self.cansasVersion).get("ns") 
    440470        doc = xml.dom.minidom.Document() 
    441471        main_node = doc.createElement("SASroot") 
    442         main_node.setAttribute("cansasVersion", self.cansasVersion) 
    443         main_node.setAttribute("xmlns", "cansas1d/%s" % self.cansasVersion) 
     472        main_node.setAttribute("version", self.cansasVersion) 
     473        main_node.setAttribute("xmlns", ns) 
    444474        main_node.setAttribute("xmlns:xsi", 
    445475                               "http://www.w3.org/2001/XMLSchema-instance") 
    446476        main_node.setAttribute("xsi:schemaLocation", 
    447                                "cansas1d/%s http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" % self.cansasVersion) 
     477                               "{0} http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd".format(ns)) 
    448478         
    449479        doc.appendChild(main_node) 
     
    471501                write_node(doc, pt, "I", datainfo.y[i], 
    472502                            {'unit': datainfo.y_unit}) 
     503            if datainfo.dy != None and len(datainfo.dy) >= i: 
     504                write_node(doc, pt, "Idev", datainfo.dy[i], 
     505                            {'unit': datainfo.y_unit}) 
    473506            if datainfo.dx != None and len(datainfo.dx) >= i: 
    474507                write_node(doc, pt, "Qdev", datainfo.dx[i], 
     508                            {'unit': datainfo.x_unit}) 
     509            if datainfo.dxw != None and len(datainfo.dxw) >= i: 
     510                write_node(doc, pt, "dQw", datainfo.dxw[i], 
    475511                            {'unit': datainfo.x_unit}) 
    476512            if datainfo.dxl != None and len(datainfo.dxl) >= i: 
    477513                write_node(doc, pt, "dQl", datainfo.dxl[i], 
    478514                            {'unit': datainfo.x_unit}) 
    479             if datainfo.dxw != None and len(datainfo.dxw) >= i: 
    480                 write_node(doc, pt, "dQw", datainfo.dxw[i], 
    481                             {'unit': datainfo.x_unit}) 
    482             if datainfo.dy != None and len(datainfo.dy) >= i: 
    483                 write_node(doc, pt, "Idev", datainfo.dy[i], 
    484                             {'unit': datainfo.y_unit}) 
     515 
     516        # Transmission Spectrum Info 
     517        if len(datainfo.trans_spectrum.wavelength) > 0: 
     518            node = doc.createElement("SAStransmission_spectrum") 
     519            entry_node.appendChild(node) 
     520            for i in range(len(datainfo.trans_spectrum.wavelength)): 
     521                pt = doc.createElement("Tdata") 
     522                node.appendChild(pt) 
     523                write_node(doc, pt, "Lambda", datainfo.trans_spectrum.wavelength[i],  
     524                           {'unit': datainfo.trans_spectrum.wavelength_unit}) 
     525                write_node(doc, pt, "T", datainfo.trans_spectrum.transmission[i],  
     526                           {'unit': datainfo.trans_spectrum.transmission_unit}) 
     527                if datainfo.trans_spectrum.transmission_deviation != None \ 
     528                and len(datainfo.trans_spectrum.transmission_deviation) >= i: 
     529                    write_node(doc, pt, "Tdev", datainfo.trans_spectrum.transmission_deviation[i],  
     530                               {'unit': datainfo.trans_spectrum.transmission_deviation_unit}) 
    485531 
    486532        # Sample info 
     
    495541        write_node(doc, sample, "temperature", datainfo.sample.temperature, 
    496542                   {"unit": datainfo.sample.temperature_unit}) 
    497          
    498         for item in datainfo.sample.details: 
    499             write_node(doc, sample, "details", item) 
    500543         
    501544        pos = doc.createElement("position") 
     
    524567            sample.appendChild(ori) 
    525568         
     569        for item in datainfo.sample.details: 
     570            write_node(doc, sample, "details", item) 
     571         
    526572        # Instrument info 
    527573        instr = doc.createElement("SASinstrument") 
     
    535581            source.setAttribute("name", str(datainfo.source.name)) 
    536582        instr.appendChild(source) 
    537          
    538583        write_node(doc, source, "radiation", datainfo.source.radiation) 
    539         write_node(doc, source, "beam_shape", datainfo.source.beam_shape) 
     584         
    540585        size = doc.createElement("beam_size") 
    541586        if datainfo.source.beam_size_name is not None: 
     
    552597            source.appendChild(size) 
    553598             
     599        write_node(doc, source, "beam_shape", datainfo.source.beam_shape) 
    554600        write_node(doc, source, "wavelength", 
    555601                   datainfo.source.wavelength, 
     
    583629                coll.appendChild(ap) 
    584630                 
    585                 write_node(doc, ap, "distance", apert.distance, 
    586                            {"unit": apert.distance_unit}) 
    587                  
    588631                size = doc.createElement("size") 
    589632                if apert.size_name is not None: 
     
    597640                if written == True: 
    598641                    ap.appendChild(size) 
     642                 
     643                write_node(doc, ap, "distance", apert.distance, 
     644                           {"unit": apert.distance_unit}) 
    599645 
    600646        #   Detectors 
     
    604650            written = written | write_node(doc, det, "SDD", item.distance, 
    605651                                           {"unit": item.distance_unit}) 
    606             written = written | write_node(doc, det, "slit_length", 
    607                                            item.slit_length, 
    608                                            {"unit": item.slit_length_unit}) 
    609652            if written == True: 
    610653                instr.appendChild(det) 
     
    619662            if written == True: 
    620663                det.appendChild(off) 
     664                 
     665            ori = doc.createElement("orientation") 
     666            written = write_node(doc, ori, "roll", item.orientation.x, 
     667                                 {"unit": item.orientation_unit}) 
     668            written = written | write_node(doc, ori, "pitch", 
     669                                           item.orientation.y, 
     670                                           {"unit": item.orientation_unit}) 
     671            written = written | write_node(doc, ori, "yaw", 
     672                                           item.orientation.z, 
     673                                           {"unit": item.orientation_unit}) 
     674            if written == True: 
     675                det.appendChild(ori) 
    621676             
    622677            center = doc.createElement("beam_center") 
     
    641696            if written == True: 
    642697                det.appendChild(pix) 
    643                  
    644             ori = doc.createElement("orientation") 
    645             written = write_node(doc, ori, "roll", item.orientation.x, 
    646                                  {"unit": item.orientation_unit}) 
    647             written = written | write_node(doc, ori, "pitch", 
    648                                            item.orientation.y, 
    649                                            {"unit": item.orientation_unit}) 
    650             written = written | write_node(doc, ori, "yaw", 
    651                                            item.orientation.z, 
    652                                            {"unit": item.orientation_unit}) 
    653             if written == True: 
    654                 det.appendChild(ori) 
    655                  
     698            written = written | write_node(doc, det, "slit_length", 
     699                                           item.slit_length, 
     700                                           {"unit": item.slit_length_unit}) 
     701             
    656702        # Processes info 
    657703        for item in datainfo.process: 
     
    668714            for note in item.notes: 
    669715                write_node(doc, node, "SASprocessnote", note) 
    670          
     716            if len(item.notes) == 0: 
     717                write_node(doc, node, "SASprocessnote", "") 
     718                 
     719        # Note info 
     720        if len(datainfo.notes) == 0: 
     721            node = doc.createElement("SASnote") 
     722            entry_node.appendChild(node) 
     723            if node.hasChildNodes(): 
     724                for child in node.childNodes: 
     725                    node.removeChild(child) 
     726        else: 
     727            for item in datainfo.notes: 
     728                node = doc.createElement("SASnote") 
     729                entry_node.appendChild(node) 
     730                node.appendChild(doc.createTextNode(item)) 
     731                 
    671732        # Return the document, and the SASentry node associated with 
    672733        # the data we just wrote 
Note: See TracChangeset for help on using the changeset viewer.