source: sasview/src/sas/sascalc/dataloader/readers/abs_reader.py @ 0d64713

Last change on this file since 0d64713 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.8 KB
RevLine 
[a7a5886]1"""
2"""
[0997158f]3#####################################################################
4#This software was developed by the University of Tennessee as part of the
5#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
[7d6351e]6#project funded by the US National Science Foundation.
[0997158f]7#See the license text in license.txt
8#copyright 2008, University of Tennessee
9######################################################################
[d8a5f12]10
11import numpy
12import os
[b699768]13from sas.sascalc.dataloader.data_info import Data1D
14from sas.sascalc.dataloader.data_info import Detector
[d8a5f12]15
[99d1af6]16has_converter = True
17try:
[b699768]18    from sas.sascalc.data_util.nxsunit import Converter
[99d1af6]19except:
20    has_converter = False
[aac129aa]21   
[7d6351e]22   
[d8a5f12]23class Reader:
24    """
[0997158f]25    Class to load IGOR reduced .ABS files
[d8a5f12]26    """
[8780e9a]27    ## File type
[7d6351e]28    type_name = "IGOR 1D"
[28caa03]29    ## Wildcards
[8780e9a]30    type = ["IGOR 1D files (*.abs)|*.abs"]
[d8a5f12]31    ## List of allowed extensions
[7d6351e]32    ext = ['.abs', '.ABS']
[d8a5f12]33   
34    def read(self, path):
35        """
[0997158f]36        Load data file.
37       
38        :param path: file path
39       
40        :return: Data1D object, or None
41       
42        :raise RuntimeError: when the file can't be opened
43        :raise ValueError: when the length of the data vectors are inconsistent
[d8a5f12]44        """
45        if os.path.isfile(path):
[7d6351e]46            basename = os.path.basename(path)
[d8a5f12]47            root, extension = os.path.splitext(basename)
48            if extension.lower() in self.ext:
49                try:
[7d6351e]50                    input_f = open(path,'r')
51                except:
[d8a5f12]52                    raise  RuntimeError, "abs_reader: cannot open %s" % path
53                buff = input_f.read()
54                lines = buff.split('\n')
55                x  = numpy.zeros(0)
56                y  = numpy.zeros(0)
57                dy = numpy.zeros(0)
[148ad64]58                dx = numpy.zeros(0)
59                output = Data1D(x, y, dy=dy, dx=dx)
[99d1af6]60                detector = Detector()
61                output.detector.append(detector)
[b99ac227]62                output.filename = basename
[d8a5f12]63               
64                is_info = False
65                is_center = False
66                is_data_started = False
67               
[99d1af6]68                data_conv_q = None
69                data_conv_i = None
70               
[ca10d8e]71                if has_converter == True and output.x_unit != '1/A':
72                    data_conv_q = Converter('1/A')
[99d1af6]73                    # Test it
74                    data_conv_q(1.0, output.x_unit)
75                   
[ca10d8e]76                if has_converter == True and output.y_unit != '1/cm':
77                    data_conv_i = Converter('1/cm')
[99d1af6]78                    # Test it
79                    data_conv_i(1.0, output.y_unit)
80               
[d8a5f12]81                for line in lines:
[470bf7e]82                   
[d8a5f12]83                    # Information line 1
[a7a5886]84                    if is_info == True:
[d8a5f12]85                        is_info = False
86                        line_toks = line.split()
87                       
88                        # Wavelength in Angstrom
89                        try:
[99d1af6]90                            value = float(line_toks[1])
[a7a5886]91                            if has_converter == True and \
92                                output.source.wavelength_unit != 'A':
[99d1af6]93                                conv = Converter('A')
[7d6351e]94                                output.source.wavelength = conv(value,
[a7a5886]95                                        units=output.source.wavelength_unit)
[99d1af6]96                            else:
97                                output.source.wavelength = value
[d8a5f12]98                        except:
[470bf7e]99                            #goes to ASC reader
[a7a5886]100                            msg = "abs_reader: cannot open %s" % path
101                            raise  RuntimeError, msg
[d8a5f12]102                       
103                        # Distance in meters
104                        try:
[99d1af6]105                            value = float(line_toks[3])
[a7a5886]106                            if has_converter == True and \
107                                detector.distance_unit != 'm':
[99d1af6]108                                conv = Converter('m')
[7d6351e]109                                detector.distance = conv(value,
[a7a5886]110                                                units=detector.distance_unit)
[99d1af6]111                            else:
112                                detector.distance = value
[d8a5f12]113                        except:
[470bf7e]114                            #goes to ASC reader
[a7a5886]115                            msg = "abs_reader: cannot open %s" % path
116                            raise  RuntimeError, msg
[7d6351e]117                        # Transmission
[d8a5f12]118                        try:
119                            output.sample.transmission = float(line_toks[4])
120                        except:
121                            # Transmission is not a mandatory entry
122                            pass
123                   
[99d1af6]124                        # Thickness in mm
[d8a5f12]125                        try:
[99d1af6]126                            value = float(line_toks[5])
[a7a5886]127                            if has_converter == True and \
128                                output.sample.thickness_unit != 'cm':
[b99ac227]129                                conv = Converter('cm')
[7d6351e]130                                output.sample.thickness = conv(value,
[a7a5886]131                                            units=output.sample.thickness_unit)
[99d1af6]132                            else:
133                                output.sample.thickness = value
[d8a5f12]134                        except:
135                            # Thickness is not a mandatory entry
136                            pass
[470bf7e]137                   
[a7a5886]138                    #MON CNT   LAMBDA   DET ANG   DET DIST   TRANS   THICK
139                    #  AVE   STEP
140                    if line.count("LAMBDA") > 0:
[470bf7e]141                        is_info = True
[d8a5f12]142                       
[470bf7e]143                    # Find center info line
[a7a5886]144                    if is_center == True:
[7d6351e]145                        is_center = False
[470bf7e]146                        line_toks = line.split()
147                        # Center in bin number
148                        center_x = float(line_toks[0])
149                        center_y = float(line_toks[1])
[99d1af6]150                       
[470bf7e]151                        # Bin size
[a7a5886]152                        if has_converter == True and \
153                            detector.pixel_size_unit != 'mm':
[470bf7e]154                            conv = Converter('mm')
[7d6351e]155                            detector.pixel_size.x = conv(5.0,
[a7a5886]156                                                units=detector.pixel_size_unit)
157                            detector.pixel_size.y = conv(5.0,
158                                                units=detector.pixel_size_unit)
[470bf7e]159                        else:
160                            detector.pixel_size.x = 5.0
161                            detector.pixel_size.y = 5.0
[99d1af6]162                       
[470bf7e]163                        # Store beam center in distance units
164                        # Det 640 x 640 mm
[7d6351e]165                        if has_converter == True and \
[a7a5886]166                            detector.beam_center_unit != 'mm':
[470bf7e]167                            conv = Converter('mm')
[a7a5886]168                            detector.beam_center.x = conv(center_x * 5.0,
169                                             units=detector.beam_center_unit)
[7d6351e]170                            detector.beam_center.y = conv(center_y * 5.0,
[a7a5886]171                                            units=detector.beam_center_unit)
[470bf7e]172                        else:
[a7a5886]173                            detector.beam_center.x = center_x * 5.0
174                            detector.beam_center.y = center_y * 5.0
[d8a5f12]175                       
[470bf7e]176                        # Detector type
177                        try:
178                            detector.name = line_toks[7]
179                        except:
180                            # Detector name is not a mandatory entry
181                            pass
182                   
[7d6351e]183                    #BCENT(X,Y)   A1(mm)   A2(mm)   A1A2DIST(m)   DL/L
184                    #  BSTOP(mm)   DET_TYP
[a7a5886]185                    if line.count("BCENT") > 0:
[470bf7e]186                        is_center = True
[d8a5f12]187                       
[470bf7e]188                    # Parse the data
[a7a5886]189                    if is_data_started == True:
[470bf7e]190                        toks = line.split()
191
[7d6351e]192                        try:
[470bf7e]193                            _x  = float(toks[0])
[7d6351e]194                            _y  = float(toks[1])
[470bf7e]195                            _dy = float(toks[2])
196                            _dx = float(toks[3])
[99d1af6]197                           
[470bf7e]198                            if data_conv_q is not None:
199                                _x = data_conv_q(_x, units=output.x_unit)
200                                _dx = data_conv_i(_dx, units=output.x_unit)
[148ad64]201                               
[470bf7e]202                            if data_conv_i is not None:
203                                _y = data_conv_i(_y, units=output.y_unit)
204                                _dy = data_conv_i(_dy, units=output.y_unit)
205                           
[7d6351e]206                            x = numpy.append(x, _x)
207                            y = numpy.append(y, _y)
[470bf7e]208                            dy = numpy.append(dy, _dy)
[7d6351e]209                            dx = numpy.append(dx, _dx)
[470bf7e]210                           
211                        except:
212                            # Could not read this data line. If we are here
213                            # it is because we are in the data section. Just
214                            # skip it.
215                            pass
[148ad64]216                           
[a7a5886]217                    #The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev.
218                    # I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|
[7d6351e]219                    if line.count("The 6 columns") > 0:
[470bf7e]220                        is_data_started = True
221           
[d8a5f12]222                # Sanity check
223                if not len(y) == len(dy):
[a7a5886]224                    msg = "abs_reader: y and dy have different length"
225                    raise ValueError, msg
[8bd8ea4]226                # If the data length is zero, consider this as
227                # though we were not able to read the file.
[a7a5886]228                if len(x) == 0:
[8bd8ea4]229                    raise ValueError, "ascii_reader: could not load file"
[aac129aa]230               
[7d6351e]231                output.x = x[x != 0]
232                output.y = y[x != 0]
233                output.dy = dy[x != 0]
234                output.dx = dx[x != 0]
[99d1af6]235                if data_conv_q is not None:
236                    output.xaxis("\\rm{Q}", output.x_unit)
237                else:
238                    output.xaxis("\\rm{Q}", 'A^{-1}')
239                if data_conv_i is not None:
[0e2aa40]240                    output.yaxis("\\rm{Intensity}", output.y_unit)
[99d1af6]241                else:
[7d6351e]242                    output.yaxis("\\rm{Intensity}", "cm^{-1}")
[fe78c7b]243                   
244                # Store loading process information
[7d6351e]245                output.meta_data['loader'] = self.type_name
[d8a5f12]246                return output
247        else:
248            raise RuntimeError, "%s is not a file" % path
249        return None
Note: See TracBrowser for help on using the repository browser.