Ignore:
Timestamp:
Jul 21, 2016 10:47:25 AM (8 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.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
94f4518
Parents:
8976865
Message:

Support loading BSL/OTOKO files with multiple frames

Location:
src/sas/sasgui/perspectives/file_converter
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/file_converter/cansas_writer.py

    r8976865 reb8da5f  
    66class CansasWriter(CansasReader): 
    77 
    8     def write(self, filename, datainfo, sasentry_attrs=None): 
     8    def write(self, filename, frame_data, sasentry_attrs=None): 
    99        """ 
    1010        Write the content of a Data1D as a CanSAS XML file 
     
    1414        """ 
    1515        # Create XML document 
    16         doc, _ = self._to_xml_doc(datainfo, sasentry_attrs) 
     16        doc, _ = self._to_xml_doc(frame_data, sasentry_attrs) 
    1717        # Write the file 
    1818        file_ref = open(filename, 'w') 
     
    2424 
    2525 
    26     def _to_xml_doc(self, datainfo, sasentry_attrs=None): 
     26    def _to_xml_doc(self, frame_data, sasentry_attrs=None): 
    2727        """ 
    28         Create an XML document to contain the content of a Data1D 
     28        Create an XML document to contain the content of an array of Data1Ds 
    2929 
    30         :param datainfo: Data1D object 
     30        :param frame_data: An array of Data1D objects 
    3131        """ 
    32         if not issubclass(datainfo.__class__, Data1D): 
    33             raise RuntimeError, "The cansas writer expects a Data1D instance" 
     32        valid_class = all([issubclass(data.__class__, Data1D) for data in frame_data]) 
     33        if not valid_class: 
     34            raise RuntimeError, ("The cansas writer expects an array of " 
     35                "Data1D instances") 
    3436 
    3537        # Get PIs and create root element 
     
    4648        root.append(entry_node) 
    4749 
     50        # Use the first element in the array for writing metadata 
     51        datainfo = frame_data[0] 
    4852        # Add Title to SASentry 
    4953        self.write_node(entry_node, "Title", datainfo.title) 
     
    5155        self._write_run_names(datainfo, entry_node) 
    5256        # Add Data info to SASEntry 
    53         self._write_data(datainfo, entry_node) 
     57        self._write_data(frame_data, entry_node) 
    5458        # Transmission Spectrum Info 
    5559        self._write_trans_spectrum(datainfo, entry_node) 
     
    7074        # Return the document, and the SASentry node associated with 
    7175        #      the data we just wrote 
    72          
     76 
    7377        return doc, entry_node 
     78 
     79    def _write_data(self, frame_data, entry_node): 
     80        """ 
     81        Writes the I and Q data to the XML file 
     82 
     83        :param datainfo: The Data1D object the information is coming from 
     84        :param entry_node: lxml node ElementTree object to be appended to 
     85        """ 
     86        for datainfo in frame_data: 
     87            node = self.create_element("SASdata") 
     88            self.append(node, entry_node) 
     89 
     90            for i in range(len(datainfo.x)): 
     91                point = self.create_element("Idata") 
     92                node.append(point) 
     93                self.write_node(point, "Q", datainfo.x[i], 
     94                                {'unit': datainfo.x_unit}) 
     95                if len(datainfo.y) >= i: 
     96                    self.write_node(point, "I", datainfo.y[i], 
     97                                    {'unit': datainfo.y_unit}) 
     98                if datainfo.dy != None and len(datainfo.dy) > i: 
     99                    self.write_node(point, "Idev", datainfo.dy[i], 
     100                                    {'unit': datainfo.y_unit}) 
     101                if datainfo.dx != None and len(datainfo.dx) > i: 
     102                    self.write_node(point, "Qdev", datainfo.dx[i], 
     103                                    {'unit': datainfo.x_unit}) 
     104                if datainfo.dxw != None and len(datainfo.dxw) > i: 
     105                    self.write_node(point, "dQw", datainfo.dxw[i], 
     106                                    {'unit': datainfo.x_unit}) 
     107                if datainfo.dxl != None and len(datainfo.dxl) > i: 
     108                    self.write_node(point, "dQl", datainfo.dxl[i], 
     109                                    {'unit': datainfo.x_unit}) 
  • src/sas/sasgui/perspectives/file_converter/converter_panel.py

    r8976865 reb8da5f  
    1414from sas.sasgui.perspectives.file_converter.meta_panels import SamplePanel 
    1515from sas.sasgui.perspectives.file_converter.meta_panels import SourcePanel 
     16from sas.sasgui.perspectives.file_converter.frame_select_dialog import FrameSelectDialog 
    1617from sas.sasgui.guiframe.events import StatusEvent 
    1718from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     
    105106        return np.array(data, dtype=np.float32) 
    106107 
     108    def ask_frame_range(self, n_frames): 
     109        valid_input = False 
     110        dlg = FrameSelectDialog(n_frames) 
     111        frames = None 
     112        increment = None 
     113        while not valid_input: 
     114            if dlg.ShowModal() == wx.ID_OK: 
     115                msg = "" 
     116                try: 
     117                    first_frame = int(dlg.first_input.GetValue()) 
     118                    last_frame = int(dlg.last_input.GetValue()) 
     119                    increment = int(dlg.increment_input.GetValue()) 
     120                    if last_frame < 0 or first_frame < 0: 
     121                        msg = "Frame values must be positive" 
     122                    elif increment < 1: 
     123                        msg = "Increment must be greater than or equal to 1" 
     124                    elif first_frame > last_frame: 
     125                        msg = "First frame must be less than last frame" 
     126                    elif last_frame > n_frames: 
     127                        msg = "Last frame must be less than {}".format(n_frames) 
     128                    else: 
     129                        valid_input = True 
     130                except: 
     131                    valid_input = False 
     132                    msg = "Please enter valid integer values" 
     133 
     134                if not valid_input: 
     135                    wx.PostEvent(self.parent.manager.parent, 
     136                        StatusEvent(status=msg)) 
     137            else: 
     138                return [], 0 
     139        frames = range(first_frame, last_frame + increment, 
     140            increment) 
     141        return frames, increment 
     142 
    107143    def on_convert(self, event): 
    108144        if not self.validate_inputs(): 
     
    120156                bsl_data = loader.load_bsl_data() 
    121157                qdata = bsl_data.q_axis.data[0] 
    122                 iqdata = bsl_data.data_axis.data[0] 
     158                iqdata = bsl_data.data_axis.data 
     159                frames = [iqdata.shape[0]] 
     160                increment = 1 
     161                if frames[0] > 3: 
     162                    frames, increment = self.ask_frame_range(frames[0]) 
     163                    if frames == []: return 
    123164        except Exception as ex: 
    124165            msg = str(ex) 
     
    128169 
    129170        output_path = self.output.GetPath() 
    130         data = Data1D(x=qdata, y=iqdata) 
    131         data.filename = output_path.split('\\')[-1] 
    132171 
    133172        if self.run is None: 
     
    148187        } 
    149188 
     189        frame_data = [] 
     190        for i in frames: 
     191            data = Data1D(x=qdata, y=iqdata[i]) 
     192            frame_data.append(data) 
     193        # Only need to set metadata on first Data1D object 
     194        frame_data[0].filename = output_path.split('\\')[-1] 
    150195        for key, value in metadata.iteritems(): 
    151             setattr(data, key, value) 
    152  
    153         self.convert_to_cansas(data, output_path) 
     196            setattr(frame_data[0], key, value) 
     197 
     198        self.convert_to_cansas(frame_data, output_path) 
    154199        wx.PostEvent(self.parent.manager.parent, 
    155200            StatusEvent(status="Conversion completed.")) 
  • src/sas/sasgui/perspectives/file_converter/media/file_converter_help.rst

    r13b9a63 reb8da5f  
    1414*   Single column ASCII data, with lines that end with a digit, comma or 
    1515    semi-colon. 
    16 *   `BSL formatted 
     16*   `BSL/OTOKO formatted 
    1717    <http://www.diamond.ac.uk/Beamlines/Soft-Condensed-Matter/small-angle/ 
    18     SAXS-Software/CCP13/BSL.html>`_ data files 
     18    SAXS-Software/CCP13/BSL.html>`_ data files. 
    1919 
    2020.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    2323-------------- 
    2424 
    25 1) Select the files containing your Q-Axis and Intensity data 
     251) Select the files containing your Q-Axis and Intensity-Axis data 
    26262) Chose whether the files are in ASCII or BSL format 
    27273) Chose where you would like to save the converted XML file 
    28284) Optionally, input some metadata such as sample size, detector name, etc 
    29295) Click *Convert* to save the converted file to disk 
     30 
     31**Note**: If a BSL/OTOKO file with multiple frames is selected for the 
     32intensity-axis file, a dialog will appear asking which frames you would like 
     33converted. You may enter a start frame, end frame & increment, and all frames 
     34in that subset will be converted. For example: entering 0, 50 and 10 for the 
     35first frame, last frame, and increment respectively will convert frames 0, 10, 
     3620, 30, 40 & 50. To convert a single frame, enter the same value for first 
     37frame & last frame, and 1 as the increment. 
Note: See TracChangeset for help on using the changeset viewer.