source: sasview/src/sas/sascalc/dataloader/readers/danse_reader.py @ 98ae0ba

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 98ae0ba was b699768, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Initial commit of the refactored SasCalc? module.

  • Property mode set to 100644
File size: 10.4 KB
RevLine 
[7d6351e]1"""
2    DANSE/SANS file reader
3"""
[0997158f]4############################################################################
5#This software was developed by the University of Tennessee as part of the
6#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
7#project funded by the US National Science Foundation.
[7d6351e]8#If you use DANSE applications to do scientific research that leads to
9#publication, we ask that you acknowledge the use of the software with the
[0997158f]10#following sentence:
[7d6351e]11#This work benefited from DANSE software developed under NSF award DMR-0520547.
[0997158f]12#copyright 2008, University of Tennessee
13#############################################################################
[11a0319]14import math
[99d1af6]15import os
[ed09638]16import sys
[11a0319]17import numpy
[8d6440f]18import logging
[b699768]19from sas.sascalc.dataloader.data_info import Data2D, Detector
20from sas.sascalc.dataloader.manipulations import reader2D_converter
[99d1af6]21
22# Look for unit converter
23has_converter = True
24try:
[b699768]25    from sas.sascalc.data_util.nxsunit import Converter
[99d1af6]26except:
27    has_converter = False
[16d8e5f]28
[7d6351e]29
[bb03739]30class Reader:
[11a0319]31    """
[0997158f]32    Example data manipulation
[11a0319]33    """
34    ## File type
[7d6351e]35    type_name = "DANSE"
[28caa03]36    ## Wildcards
[fd5ac0d]37    type = ["DANSE files (*.sans)|*.sans"]
[11a0319]38    ## Extension
[fd5ac0d]39    ext  = ['.sans', '.SANS']
[11a0319]40       
41    def read(self, filename=None):
42        """
[0997158f]43        Open and read the data in a file
44        @param file: path of the file
[11a0319]45        """
46       
47        read_it = False
48        for item in self.ext:
[a7a5886]49            if filename.lower().find(item) >= 0:
[11a0319]50                read_it = True
51               
52        if read_it:
[8d6440f]53            try:
[a7a5886]54                datafile = open(filename, 'r')
[7d6351e]55            except:
[a7a5886]56                raise  RuntimeError,"danse_reader cannot open %s" % (filename)
57       
[11a0319]58            # defaults
59            # wavelength in Angstrom
60            wavelength = 10.0
61            # Distance in meter
62            distance   = 11.0
63            # Pixel number of center in x
64            center_x   = 65
65            # Pixel number of center in y
66            center_y   = 65
67            # Pixel size [mm]
68            pixel      = 5.0
69            # Size in x, in pixels
70            size_x     = 128
71            # Size in y, in pixels
72            size_y     = 128
73            # Format version
74            fversion   = 1.0
75           
[99d1af6]76            output = Data2D()
77            output.filename = os.path.basename(filename)
78            detector = Detector()
79            output.detector.append(detector)
80           
81            output.data = numpy.zeros([size_x,size_y])
[a7a5886]82            output.err_data = numpy.zeros([size_x, size_y])
[99d1af6]83           
84            data_conv_q = None
85            data_conv_i = None
86           
[ca10d8e]87            if has_converter == True and output.Q_unit != '1/A':
88                data_conv_q = Converter('1/A')
[99d1af6]89                # Test it
90                data_conv_q(1.0, output.Q_unit)
91               
[ca10d8e]92            if has_converter == True and output.I_unit != '1/cm':
93                data_conv_i = Converter('1/cm')
[99d1af6]94                # Test it
[7d6351e]95                data_conv_i(1.0, output.I_unit)
[99d1af6]96       
[11a0319]97            read_on = True
98            while read_on:
99                line = datafile.readline()
[a7a5886]100                if line.find("DATA:") >= 0:
[11a0319]101                    read_on = False
102                    break
103                toks = line.split(':')
[a7a5886]104                if toks[0] == "FORMATVERSION":
[11a0319]105                    fversion = float(toks[1])
[7d6351e]106                if toks[0] == "WAVELENGTH":
107                    wavelength = float(toks[1])
[a7a5886]108                elif toks[0] == "DISTANCE":
[11a0319]109                    distance = float(toks[1])
[a7a5886]110                elif toks[0] == "CENTER_X":
[11a0319]111                    center_x = float(toks[1])
[a7a5886]112                elif toks[0] == "CENTER_Y":
[11a0319]113                    center_y = float(toks[1])
[a7a5886]114                elif toks[0] == "PIXELSIZE":
[11a0319]115                    pixel = float(toks[1])
[a7a5886]116                elif toks[0] == "SIZE_X":
[11a0319]117                    size_x = int(toks[1])
[a7a5886]118                elif toks[0] == "SIZE_Y":
[11a0319]119                    size_y = int(toks[1])
120           
121            # Read the data
122            data = []
123            error = []
[a7a5886]124            if fversion == 1.0:
[11a0319]125                data_str = datafile.readline()
126                data = data_str.split(' ')
127            else:
128                read_on = True
129                while read_on:
130                    data_str = datafile.readline()
[a7a5886]131                    if len(data_str) == 0:
[11a0319]132                        read_on = False
133                    else:
134                        toks = data_str.split()
135                        try:
136                            val = float(toks[0])
137                            err = float(toks[1])
[99d1af6]138                            if data_conv_i is not None:
[ed09638]139                                val = data_conv_i(val, units=output._yunit)
140                                err = data_conv_i(err, units=output._yunit)
[11a0319]141                            data.append(val)
142                            error.append(err)
143                        except:
[7d6351e]144                            logging.info("Skipping line:%s,%s" %(data_str,
[a7a5886]145                                                                sys.exc_value))
[11a0319]146           
[7d6351e]147            # Initialize
[11a0319]148            x_vals = []
[7d6351e]149            y_vals = []
[11a0319]150            ymin = None
151            ymax = None
152            xmin = None
153            xmax = None
154           
155            # Qx and Qy vectors
[4fe4394]156            theta = pixel / distance / 100.0
[7d6351e]157            stepq = 4.0 * math.pi / wavelength * math.sin(theta / 2.0)
[11a0319]158            for i_x in range(size_x):
[a7a5886]159                theta = (i_x - center_x + 1) * pixel / distance / 100.0
[7d6351e]160                qx = 4.0 * math.pi / wavelength * math.sin(theta / 2.0)
[99d1af6]161               
[ca10d8e]162                if has_converter == True and output.Q_unit != '1/A':
[99d1af6]163                    qx = data_conv_q(qx, units=output.Q_unit)
164               
[11a0319]165                x_vals.append(qx)
[a7a5886]166                if xmin == None or qx < xmin:
[11a0319]167                    xmin = qx
[a7a5886]168                if xmax == None or qx > xmax:
[11a0319]169                    xmax = qx
170           
171            ymin = None
172            ymax = None
173            for i_y in range(size_y):
[a7a5886]174                theta = (i_y - center_y + 1) * pixel / distance / 100.0
[7d6351e]175                qy = 4.0 * math.pi / wavelength * math.sin(theta/2.0)
[99d1af6]176               
[ca10d8e]177                if has_converter == True and output.Q_unit != '1/A':
[99d1af6]178                    qy = data_conv_q(qy, units=output.Q_unit)
179               
[11a0319]180                y_vals.append(qy)
[a7a5886]181                if ymin == None or qy < ymin:
[11a0319]182                    ymin = qy
[a7a5886]183                if ymax == None or qy > ymax:
[11a0319]184                    ymax = qy
185           
[99d1af6]186            # Store the data in the 2D array
[7d6351e]187            i_x = 0
188            i_y = -1
[b99ac227]189           
[11a0319]190            for i_pt in range(len(data)):
191                try:
[99d1af6]192                    value = float(data[i_pt])
[11a0319]193                except:
[99d1af6]194                    # For version 1.0, the data were still
195                    # stored as strings at this point.
[7d6351e]196                    msg = "Skipping entry (v1.0):%s,%s" % (str(data[i_pt]),
[a7a5886]197                                                           sys.exc_value)
198                    logging.info(msg)
[11a0319]199               
200                # Get bin number
[a7a5886]201                if math.fmod(i_pt, size_x) == 0:
[11a0319]202                    i_x = 0
203                    i_y += 1
204                else:
205                    i_x += 1
206                   
[7d6351e]207                output.data[i_y][i_x] = value
[11a0319]208                if fversion>1.0:
[b99ac227]209                    output.err_data[i_y][i_x] = error[i_pt]
[11a0319]210               
[7d6351e]211            # Store all data
[99d1af6]212            # Store wavelength
[a7a5886]213            if has_converter == True and output.source.wavelength_unit != 'A':
[99d1af6]214                conv = Converter('A')
[a7a5886]215                wavelength = conv(wavelength,
216                                  units=output.source.wavelength_unit)
[99d1af6]217            output.source.wavelength = wavelength
218               
219            # Store distance
[a7a5886]220            if has_converter == True and detector.distance_unit != 'm':
[99d1af6]221                conv = Converter('m')
222                distance = conv(distance, units=detector.distance_unit)
223            detector.distance = distance
224           
225            # Store pixel size
[a7a5886]226            if has_converter == True and detector.pixel_size_unit != 'mm':
[99d1af6]227                conv = Converter('mm')
228                pixel = conv(pixel, units=detector.pixel_size_unit)
229            detector.pixel_size.x = pixel
230            detector.pixel_size.y = pixel
231
232            # Store beam center in distance units
[7d6351e]233            detector.beam_center.x = center_x * pixel
234            detector.beam_center.y = center_y * pixel
[99d1af6]235           
236            # Store limits of the image (2D array)
[a7a5886]237            xmin = xmin - stepq / 2.0
238            xmax = xmax + stepq / 2.0
[7d6351e]239            ymin = ymin - stepq /2.0
[a7a5886]240            ymax = ymax + stepq / 2.0
[4fe4394]241           
[ca10d8e]242            if has_converter == True and output.Q_unit != '1/A':
[99d1af6]243                xmin = data_conv_q(xmin, units=output.Q_unit)
244                xmax = data_conv_q(xmax, units=output.Q_unit)
245                ymin = data_conv_q(ymin, units=output.Q_unit)
246                ymax = data_conv_q(ymax, units=output.Q_unit)
247            output.xmin = xmin
248            output.xmax = xmax
249            output.ymin = ymin
250            output.ymax = ymax
251           
252            # Store x and y axis bin centers
[7d6351e]253            output.x_bins = x_vals
254            output.y_bins = y_vals
[99d1af6]255           
256            # Units
257            if data_conv_q is not None:
[eeaabb1]258                output.xaxis("\\rm{Q_{x}}", output.Q_unit)
259                output.yaxis("\\rm{Q_{y}}", output.Q_unit)
[99d1af6]260            else:
[eeaabb1]261                output.xaxis("\\rm{Q_{x}}", 'A^{-1}')
262                output.yaxis("\\rm{Q_{y}}", 'A^{-1}')
[99d1af6]263               
264            if data_conv_i is not None:
[0e2aa40]265                output.zaxis("\\rm{Intensity}", output.I_unit)
[99d1af6]266            else:
[7d6351e]267                output.zaxis("\\rm{Intensity}", "cm^{-1}")
[16d8e5f]268           
[a7a5886]269            if not fversion >= 1.0:
270                msg = "Danse_reader can't read this file %s" % filename
271                raise ValueError, msg
[11a0319]272            else:
[a7a5886]273                logging.info("Danse_reader Reading %s \n" % filename)
[fe78c7b]274           
275            # Store loading process information
[7d6351e]276            output.meta_data['loader'] = self.type_name
[eadf1f9]277            output = reader2D_converter(output)
[fe78c7b]278            return output
[11a0319]279       
280        return None
Note: See TracBrowser for help on using the repository browser.