Exemple #1
0
    def test_allowed_bins(self):
        x = numpy.asarray(numpy.asarray([0, 1, 2, 3]))
        y = numpy.asarray(numpy.asarray([1, 1, 1, 1]))
        dy = numpy.asarray(numpy.asarray([1, 1, 1, 1]))
        g = invariant.Guinier()
        data = Data1D(x=x, y=y, dy=dy)
        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])

        data = Data1D(x=y, y=x, dy=dy)
        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])

        data = Data1D(x=dy, y=y, dy=x)
        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])
Exemple #2
0
    def read(self, path):
        """ 
            Load data file
            
            @param path: file path
            @return: Data1D object, or None
            @raise RuntimeError: when the file can't be opened
            @raise ValueError: when the length of the data vectors are inconsistent
        """
        if os.path.isfile(path):
            basename = os.path.basename(path)
            root, extension = os.path.splitext(basename)
            if extension.lower() in self.ext:
                try:
                    input_f = open(path, 'r')
                except:
                    raise RuntimeError, "ascii_reader: cannot open %s" % path
                buff = input_f.read()
                lines = buff.split('\n')
                x = numpy.zeros(0)
                y = numpy.zeros(0)
                dy = numpy.zeros(0)
                output = Data1D(x, y, dy=dy)
                self.filename = output.filename = basename

                for line in lines:
                    x = numpy.append(x, float(line))

                output.x = x
                return output
        else:
            raise RuntimeError, "%s is not a file" % path
        return None
Exemple #3
0
 def setUp(self):
     """
         Generate a power law distribution. After extrapolating, we will
         verify that we obtain the scale and m parameters
     """
     self.scale = 1.5
     self.m = 3.0
     x = numpy.arange(0.0001, 0.1, 0.0001)
     y = numpy.asarray([self.scale * math.pow(q, -1.0 * self.m) for q in x])
     dy = y * .1
     self.data = Data1D(x=x, y=y, dy=dy)
Exemple #4
0
 def setUp(self):
     """
         Generate a Guinier distribution. After extrapolating, we will
         verify that we obtain the scale and rg parameters
     """
     self.scale = 1.5
     self.rg = 30.0
     x = numpy.arange(0.0001, 0.1, 0.0001)
     y = numpy.asarray(
         [self.scale * math.exp(-(q * self.rg)**2 / 3.0) for q in x])
     dy = y * .1
     self.data = Data1D(x=x, y=y, dy=dy)
Exemple #5
0
 def test_linearization(self):
     """
         Check that the linearization process filters out points
         that can't be transformed
     """
     x = numpy.asarray(numpy.asarray([0, 1, 2, 3]))
     y = numpy.asarray(numpy.asarray([1, 1, 1, 1]))
     g = invariant.Guinier()
     data_in = Data1D(x=x, y=y)
     data_out = g.linearize_data(data_in)
     x_out, y_out, dy_out = data_out.x, data_out.y, data_out.dy
     self.assertEqual(len(x_out), 3)
     self.assertEqual(len(y_out), 3)
     self.assertEqual(len(dy_out), 3)
Exemple #6
0
    def test_error_treatment(self):
        x = numpy.asarray(numpy.asarray([0, 1, 2, 3]))
        y = numpy.asarray(numpy.asarray([1, 1, 1, 1]))

        # These are all the values of the dy array that would cause
        # us to set all dy values to 1.0 at __init__ time.
        dy_list = [[], None, [0, 0, 0, 0]]

        for dy in dy_list:
            data = Data1D(x=x, y=y, dy=dy)
            inv = invariant.InvariantCalculator(data)
            self.assertEqual(len(inv._data.x), len(inv._data.dy))
            self.assertEqual(len(inv._data.dy), 4)
            for i in range(4):
                self.assertEqual(inv._data.dy[i], 1)
Exemple #7
0
    def _check_for_empty_data(self, data1d):
        """
        Creates an empty data set if no data is passed to the reader

        :param data1d: presumably a Data1D object
        """
        if data1d == None:
            self.errors = set()
            x_vals = numpy.empty(0)
            y_vals = numpy.empty(0)
            dx_vals = numpy.empty(0)
            dy_vals = numpy.empty(0)
            dxl = numpy.empty(0)
            dxw = numpy.empty(0)
            data1d = Data1D(x_vals, y_vals, dx_vals, dy_vals)
            data1d.dxl = dxl
            data1d.dxw = dxw
        return data1d
    def test_cyl_times_square(self):
        """ Simple cylinder model fit  """

        out = Loader().load("cyl_400_20.txt")
        data = Data1D(x=out.x, y=out.y, dx=out.dx, dy=out.dy)
        # Receives the type of model for the fitting
        model1 = MultiplicationModel(CylinderModel(), SquareWellStructure())
        model1.setParam('background', 0.0)
        model1.setParam('sldCyl', 3e-006)
        model1.setParam('sldSolv', 0.0)
        model1.setParam('length', 420)
        model1.setParam('radius', 40)
        model1.setParam('scale_factor', 2)
        model1.setParam('volfraction', 0.04)
        model1.setParam('welldepth', 1.5)
        model1.setParam('wellwidth', 1.2)

        model = Model(model1)

        pars1 = ['length', 'radius', 'scale_factor']
        fitter = Fit('bumps')
        fitter.set_data(data, 1)
        fitter.set_model(model, 1, pars1)
        fitter.select_problem_for_fit(id=1, value=1)
        result1, = fitter.fit()

        self.assert_(result1)
        self.assertTrue(len(result1.pvec) >= 0)
        self.assertTrue(len(result1.stderr) >= 0)

        #print "results",list(zip(result1.pvec, result1.stderr))
        self.assertTrue(
            math.fabs(result1.pvec[0] - 612) / 3.0 <= result1.stderr[0])
        self.assertTrue(
            math.fabs(result1.pvec[1] - 20.3) / 3.0 <= result1.stderr[1])
        self.assertTrue(
            math.fabs(result1.pvec[2] - 25) / 3.0 <= result1.stderr[2])

        self.assertTrue(result1.fitness / len(data.x) < 1.0)
Exemple #9
0
    def read(self, xml_file):
        """
        Validate and read in an xml_file file in the canSAS format.

        :param xml_file: A canSAS file path in proper XML format
        """
        # output - Final list of Data1D objects
        output = []
        # ns - Namespace hierarchy for current xml_file object
        ns_list = []

        # Check that the file exists
        if os.path.isfile(xml_file):
            basename = os.path.basename(xml_file)
            _, extension = os.path.splitext(basename)
            # If the file type is not allowed, return nothing
            if extension in self.ext or self.allow_all:
                # Get the file location of
                cansas_defaults = self.load_file_and_schema(xml_file)

                # Try to load the file, but raise an error if unable to.
                # Check the file matches the XML schema
                try:
                    if self.is_cansas(extension):
                        # Get each SASentry from XML file and add it to a list.
                        entry_list = self.xmlroot.xpath(
                            '/ns:SASroot/ns:SASentry',
                            namespaces={'ns': cansas_defaults.get("ns")})
                        ns_list.append("SASentry")

                        # If multiple files, modify the name for each is unique
                        increment = 0
                        # Parse each SASentry item
                        for entry in entry_list:
                            # Define a new Data1D object with zeroes for
                            # x_vals and y_vals
                            data1d = Data1D(numpy.empty(0), numpy.empty(0),
                                            numpy.empty(0), numpy.empty(0))
                            data1d.dxl = numpy.empty(0)
                            data1d.dxw = numpy.empty(0)

                            # If more than one SASentry, increment each in order
                            name = basename
                            if len(entry_list) - 1 > 0:
                                name += "_{0}".format(increment)
                                increment += 1

                            # Set the Data1D name and then parse the entry.
                            # The entry is appended to a list of entry values
                            data1d.filename = name
                            data1d.meta_data["loader"] = "CanSAS 1D"

                            # Get all preprocessing events and encoding
                            self.set_processing_instructions()
                            data1d.meta_data[PREPROCESS] = \
                                    self.processing_instructions

                            # Parse the XML file
                            return_value, extras = \
                                self._parse_entry(entry, ns_list, data1d)
                            del extras[:]

                            return_value = self._final_cleanup(return_value)
                            output.append(return_value)
                    else:
                        output.append("Invalid XML at: {0}".format(\
                                                    self.find_invalid_xml()))
                except:
                    # If the file does not match the schema, raise this error
                    raise RuntimeError, "%s cannot be read" % xml_file
                return output
        # Return a list of parsed entries that dataloader can manage
        return None
Exemple #10
0
 def test_guinier_incompatible_length(self):
     g = invariant.Guinier()
     data_in = Data1D(x=[1], y=[1, 2], dy=None)
     self.assertRaises(AssertionError, g.linearize_data, data_in)
     data_in = Data1D(x=[1, 1], y=[1, 2], dy=[1])
     self.assertRaises(AssertionError, g.linearize_data, data_in)
Exemple #11
0
    def setUp(self):
        x = numpy.asarray([1., 2., 3., 4., 5., 6., 7., 8., 9.])
        y = numpy.asarray([1., 2., 3., 4., 5., 6., 7., 8., 9.])
        dy = y / 10.0

        self.data = Data1D(x=x, y=y, dy=dy)
Exemple #12
0
    def read(self, path):
        """
        Load data file
        
        :param path: file path
        
        :return: Data1D object, or None
        
        :raise RuntimeError: when the file can't be opened
        :raise ValueError: when the length of the data vectors are inconsistent
        """
        if os.path.isfile(path):
            basename = os.path.basename(path)
            _, extension = os.path.splitext(basename)
            if self.allow_all or extension.lower() in self.ext:
                try:
                    # Read in binary mode since GRASP frequently has no-ascii
                    # characters that brakes the open operation
                    input_f = open(path, 'rb')
                except:
                    raise RuntimeError, "ascii_reader: cannot open %s" % path
                buff = input_f.read()
                lines = buff.splitlines()

                x = numpy.zeros(0)
                y = numpy.zeros(0)
                dy = numpy.zeros(0)
                dx = numpy.zeros(0)

                #temp. space to sort data
                tx = numpy.zeros(0)
                ty = numpy.zeros(0)
                tdy = numpy.zeros(0)
                tdx = numpy.zeros(0)

                output = Data1D(x, y, dy=dy, dx=dx)
                self.filename = output.filename = basename

                data_conv_q = None
                data_conv_i = None

                if has_converter == True and output.x_unit != '1/A':
                    data_conv_q = Converter('1/A')
                    # Test it
                    data_conv_q(1.0, output.x_unit)

                if has_converter == True and output.y_unit != '1/cm':
                    data_conv_i = Converter('1/cm')
                    # Test it
                    data_conv_i(1.0, output.y_unit)

                # The first good line of data will define whether
                # we have 2-column or 3-column ascii
                has_error_dx = None
                has_error_dy = None

                #Initialize counters for data lines and header lines.
                is_data = False  # Has more than 5 lines
                # More than "5" lines of data is considered as actual
                # data unless that is the only data
                mum_data_lines = 5
                # To count # of current data candidate lines
                i = -1
                # To count total # of previous data candidate lines
                i1 = -1
                # To count # of header lines
                j = -1
                # Helps to count # of header lines
                j1 = -1
                #minimum required number of columns of data; ( <= 4).
                lentoks = 2
                for line in lines:
                    # Initial try for CSV (split on ,)
                    toks = line.split(',')
                    # Now try SCSV (split on ;)
                    if len(toks) < 2:
                        toks = line.split(';')
                    # Now go for whitespace
                    if len(toks) < 2:
                        toks = line.split()
                    try:
                        #Make sure that all columns are numbers.
                        for colnum in range(len(toks)):
                            float(toks[colnum])

                        _x = float(toks[0])
                        _y = float(toks[1])

                        #Reset the header line counters
                        if j == j1:
                            j = 0
                            j1 = 0

                        if i > 1:
                            is_data = True

                        if data_conv_q is not None:
                            _x = data_conv_q(_x, units=output.x_unit)

                        if data_conv_i is not None:
                            _y = data_conv_i(_y, units=output.y_unit)

                        # If we have an extra token, check
                        # whether it can be interpreted as a
                        # third column.
                        _dy = None
                        if len(toks) > 2:
                            try:
                                _dy = float(toks[2])

                                if data_conv_i is not None:
                                    _dy = data_conv_i(_dy, units=output.y_unit)

                            except:
                                # The third column is not a float, skip it.
                                pass

                        # If we haven't set the 3rd column
                        # flag, set it now.
                        if has_error_dy == None:
                            has_error_dy = False if _dy == None else True

                        #Check for dx
                        _dx = None
                        if len(toks) > 3:
                            try:
                                _dx = float(toks[3])

                                if data_conv_i is not None:
                                    _dx = data_conv_i(_dx, units=output.x_unit)

                            except:
                                # The 4th column is not a float, skip it.
                                pass

                        # If we haven't set the 3rd column
                        # flag, set it now.
                        if has_error_dx == None:
                            has_error_dx = False if _dx == None else True

                        #After talked with PB, we decided to take care of only
                        # 4 columns of data for now.
                        #number of columns in the current line
                        #To remember the # of columns in the current
                        #line of data
                        new_lentoks = len(toks)

                        #If the previous columns not equal to the current,
                        #mark the previous as non-data and reset the dependents.
                        if lentoks != new_lentoks:
                            if is_data == True:
                                break
                            else:
                                i = -1
                                i1 = 0
                                j = -1
                                j1 = -1

                        #Delete the previously stored lines of data candidates
                        # if is not data.
                        if i < 0 and -1 < i1 < mum_data_lines and \
                            is_data == False:
                            try:
                                x = numpy.zeros(0)
                                y = numpy.zeros(0)
                            except:
                                pass

                        x = numpy.append(x, _x)
                        y = numpy.append(y, _y)

                        if has_error_dy == True:
                            #Delete the previously stored lines of
                            # data candidates if is not data.
                            if i < 0 and -1 < i1 < mum_data_lines and \
                                is_data == False:
                                try:
                                    dy = numpy.zeros(0)
                                except:
                                    pass
                            dy = numpy.append(dy, _dy)

                        if has_error_dx == True:
                            #Delete the previously stored lines of
                            # data candidates if is not data.
                            if i < 0 and -1 < i1 < mum_data_lines and \
                                is_data == False:
                                try:
                                    dx = numpy.zeros(0)
                                except:
                                    pass
                            dx = numpy.append(dx, _dx)

                        #Same for temp.
                        #Delete the previously stored lines of data candidates
                        # if is not data.
                        if i < 0 and -1 < i1 < mum_data_lines and\
                            is_data == False:
                            try:
                                tx = numpy.zeros(0)
                                ty = numpy.zeros(0)
                            except:
                                pass

                        tx = numpy.append(tx, _x)
                        ty = numpy.append(ty, _y)

                        if has_error_dy == True:
                            #Delete the previously stored lines of
                            # data candidates if is not data.
                            if i < 0 and -1 < i1 < mum_data_lines and \
                                is_data == False:
                                try:
                                    tdy = numpy.zeros(0)
                                except:
                                    pass
                            tdy = numpy.append(tdy, _dy)
                        if has_error_dx == True:
                            #Delete the previously stored lines of
                            # data candidates if is not data.
                            if i < 0 and -1 < i1 < mum_data_lines and \
                                is_data == False:
                                try:
                                    tdx = numpy.zeros(0)
                                except:
                                    pass
                            tdx = numpy.append(tdx, _dx)

                        #reset i1 and flag lentoks for the next
                        if lentoks < new_lentoks:
                            if is_data == False:
                                i1 = -1
                        #To remember the # of columns on the current line
                        # for the next line of data
                        lentoks = len(toks)

                        #Reset # of header lines and counts #
                        # of data candidate lines
                        if j == 0 and j1 == 0:
                            i1 = i + 1
                        i += 1
                    except:
                        # It is data and meet non - number, then stop reading
                        if is_data == True:
                            break
                        lentoks = 2
                        #Counting # of header lines
                        j += 1
                        if j == j1 + 1:
                            j1 = j
                        else:
                            j = -1
                        #Reset # of lines of data candidates
                        i = -1

                        # Couldn't parse this line, skip it
                        pass

                input_f.close()
                # Sanity check
                if has_error_dy == True and not len(y) == len(dy):
                    msg = "ascii_reader: y and dy have different length"
                    raise RuntimeError, msg
                if has_error_dx == True and not len(x) == len(dx):
                    msg = "ascii_reader: y and dy have different length"
                    raise RuntimeError, msg
                # If the data length is zero, consider this as
                # though we were not able to read the file.
                if len(x) == 0:
                    raise RuntimeError, "ascii_reader: could not load file"

                #Let's re-order the data to make cal.
                # curve look better some cases
                ind = numpy.lexsort((ty, tx))
                for i in ind:
                    x[i] = tx[ind[i]]
                    y[i] = ty[ind[i]]
                    if has_error_dy == True:
                        dy[i] = tdy[ind[i]]
                    if has_error_dx == True:
                        dx[i] = tdx[ind[i]]
                # Zeros in dx, dy
                if has_error_dx:
                    dx[dx == 0] = _ZERO
                if has_error_dy:
                    dy[dy == 0] = _ZERO
                #Data
                output.x = x[x != 0]
                output.y = y[x != 0]
                output.dy = dy[x != 0] if has_error_dy == True\
                    else numpy.zeros(len(output.y))
                output.dx = dx[x != 0] if has_error_dx == True\
                    else numpy.zeros(len(output.x))

                if data_conv_q is not None:
                    output.xaxis("\\rm{Q}", output.x_unit)
                else:
                    output.xaxis("\\rm{Q}", 'A^{-1}')
                if data_conv_i is not None:
                    output.yaxis("\\rm{Intensity}", output.y_unit)
                else:
                    output.yaxis("\\rm{Intensity}", "cm^{-1}")

                # Store loading process information
                output.meta_data['loader'] = self.type_name
                if len(output.x) < 1:
                    raise RuntimeError, "%s is empty" % path
                return output

        else:
            raise RuntimeError, "%s is not a file" % path
        return None
Exemple #13
0
    def read(self, path):
        """ 
        Load data file
        
        :param path: file path
        
        :return: Data1D object, or None
        
        :raise RuntimeError: when the file can't be opened
        :raise ValueError: when the length of the data vectors are inconsistent
        """
        if os.path.isfile(path):
            basename = os.path.basename(path)
            root, extension = os.path.splitext(basename)
            if extension.lower() in self.ext:
                try:
                    input_f = open(path, 'r')
                except:
                    raise RuntimeError, "hfir1d_reader: cannot open %s" % path
                buff = input_f.read()
                lines = buff.split('\n')
                x = numpy.zeros(0)
                y = numpy.zeros(0)
                dx = numpy.zeros(0)
                dy = numpy.zeros(0)
                output = Data1D(x, y, dx=dx, dy=dy)
                self.filename = output.filename = basename

                data_conv_q = None
                data_conv_i = None

                if has_converter == True and output.x_unit != '1/A':
                    data_conv_q = Converter('1/A')
                    # Test it
                    data_conv_q(1.0, output.x_unit)

                if has_converter == True and output.y_unit != '1/cm':
                    data_conv_i = Converter('1/cm')
                    # Test it
                    data_conv_i(1.0, output.y_unit)

                for line in lines:
                    toks = line.split()
                    try:
                        _x = float(toks[0])
                        _y = float(toks[1])
                        _dx = float(toks[3])
                        _dy = float(toks[2])

                        if data_conv_q is not None:
                            _x = data_conv_q(_x, units=output.x_unit)
                            _dx = data_conv_q(_dx, units=output.x_unit)

                        if data_conv_i is not None:
                            _y = data_conv_i(_y, units=output.y_unit)
                            _dy = data_conv_i(_dy, units=output.y_unit)

                        x = numpy.append(x, _x)
                        y = numpy.append(y, _y)
                        dx = numpy.append(dx, _dx)
                        dy = numpy.append(dy, _dy)
                    except:
                        # Couldn't parse this line, skip it
                        pass

                # Sanity check
                if not len(y) == len(dy):
                    msg = "hfir1d_reader: y and dy have different length"
                    raise RuntimeError, msg
                if not len(x) == len(dx):
                    msg = "hfir1d_reader: x and dx have different length"
                    raise RuntimeError, msg

                # If the data length is zero, consider this as
                # though we were not able to read the file.
                if len(x) == 0:
                    raise RuntimeError, "hfir1d_reader: could not load file"

                output.x = x
                output.y = y
                output.dy = dy
                output.dx = dx
                if data_conv_q is not None:
                    output.xaxis("\\rm{Q}", output.x_unit)
                else:
                    output.xaxis("\\rm{Q}", 'A^{-1}')
                if data_conv_i is not None:
                    output.yaxis("\\rm{Intensity}", output.y_unit)
                else:
                    output.yaxis("\\rm{Intensity}", "cm^{-1}")

                # Store loading process information
                output.meta_data['loader'] = self.type_name
                return output
        else:
            raise RuntimeError, "%s is not a file" % path
        return None
Exemple #14
0
    def read(self, path):
        """ 
        Load data file.
        
        :param path: file path
        
        :return: Data1D object, or None
        
        :raise RuntimeError: when the file can't be opened
        :raise ValueError: when the length of the data vectors are inconsistent
        """
        if os.path.isfile(path):
            basename = os.path.basename(path)
            root, extension = os.path.splitext(basename)
            if extension.lower() in self.ext:
                try:
                    input_f = open(path, 'r')
                except:
                    raise RuntimeError, "abs_reader: cannot open %s" % path
                buff = input_f.read()
                lines = buff.split('\n')
                x = numpy.zeros(0)
                y = numpy.zeros(0)
                dy = numpy.zeros(0)
                dx = numpy.zeros(0)
                output = Data1D(x, y, dy=dy, dx=dx)
                detector = Detector()
                output.detector.append(detector)
                output.filename = basename

                is_info = False
                is_center = False
                is_data_started = False

                data_conv_q = None
                data_conv_i = None

                if has_converter == True and output.x_unit != '1/A':
                    data_conv_q = Converter('1/A')
                    # Test it
                    data_conv_q(1.0, output.x_unit)

                if has_converter == True and output.y_unit != '1/cm':
                    data_conv_i = Converter('1/cm')
                    # Test it
                    data_conv_i(1.0, output.y_unit)

                for line in lines:

                    # Information line 1
                    if is_info == True:
                        is_info = False
                        line_toks = line.split()

                        # Wavelength in Angstrom
                        try:
                            value = float(line_toks[1])
                            if has_converter == True and \
                                output.source.wavelength_unit != 'A':
                                conv = Converter('A')
                                output.source.wavelength = conv(
                                    value, units=output.source.wavelength_unit)
                            else:
                                output.source.wavelength = value
                        except:
                            #goes to ASC reader
                            msg = "abs_reader: cannot open %s" % path
                            raise RuntimeError, msg

                        # Distance in meters
                        try:
                            value = float(line_toks[3])
                            if has_converter == True and \
                                detector.distance_unit != 'm':
                                conv = Converter('m')
                                detector.distance = conv(
                                    value, units=detector.distance_unit)
                            else:
                                detector.distance = value
                        except:
                            #goes to ASC reader
                            msg = "abs_reader: cannot open %s" % path
                            raise RuntimeError, msg
                        # Transmission
                        try:
                            output.sample.transmission = float(line_toks[4])
                        except:
                            # Transmission is not a mandatory entry
                            pass

                        # Thickness in mm
                        try:
                            value = float(line_toks[5])
                            if has_converter == True and \
                                output.sample.thickness_unit != 'cm':
                                conv = Converter('cm')
                                output.sample.thickness = conv(
                                    value, units=output.sample.thickness_unit)
                            else:
                                output.sample.thickness = value
                        except:
                            # Thickness is not a mandatory entry
                            pass

                    #MON CNT   LAMBDA   DET ANG   DET DIST   TRANS   THICK
                    #  AVE   STEP
                    if line.count("LAMBDA") > 0:
                        is_info = True

                    # Find center info line
                    if is_center == True:
                        is_center = False
                        line_toks = line.split()
                        # Center in bin number
                        center_x = float(line_toks[0])
                        center_y = float(line_toks[1])

                        # Bin size
                        if has_converter == True and \
                            detector.pixel_size_unit != 'mm':
                            conv = Converter('mm')
                            detector.pixel_size.x = conv(
                                5.0, units=detector.pixel_size_unit)
                            detector.pixel_size.y = conv(
                                5.0, units=detector.pixel_size_unit)
                        else:
                            detector.pixel_size.x = 5.0
                            detector.pixel_size.y = 5.0

                        # Store beam center in distance units
                        # Det 640 x 640 mm
                        if has_converter == True and \
                            detector.beam_center_unit != 'mm':
                            conv = Converter('mm')
                            detector.beam_center.x = conv(
                                center_x * 5.0,
                                units=detector.beam_center_unit)
                            detector.beam_center.y = conv(
                                center_y * 5.0,
                                units=detector.beam_center_unit)
                        else:
                            detector.beam_center.x = center_x * 5.0
                            detector.beam_center.y = center_y * 5.0

                        # Detector type
                        try:
                            detector.name = line_toks[7]
                        except:
                            # Detector name is not a mandatory entry
                            pass

                    #BCENT(X,Y)   A1(mm)   A2(mm)   A1A2DIST(m)   DL/L
                    #  BSTOP(mm)   DET_TYP
                    if line.count("BCENT") > 0:
                        is_center = True

                    # Parse the data
                    if is_data_started == True:
                        toks = line.split()

                        try:
                            _x = float(toks[0])
                            _y = float(toks[1])
                            _dy = float(toks[2])
                            _dx = float(toks[3])

                            if data_conv_q is not None:
                                _x = data_conv_q(_x, units=output.x_unit)
                                _dx = data_conv_i(_dx, units=output.x_unit)

                            if data_conv_i is not None:
                                _y = data_conv_i(_y, units=output.y_unit)
                                _dy = data_conv_i(_dy, units=output.y_unit)

                            x = numpy.append(x, _x)
                            y = numpy.append(y, _y)
                            dy = numpy.append(dy, _dy)
                            dx = numpy.append(dx, _dx)

                        except:
                            # Could not read this data line. If we are here
                            # it is because we are in the data section. Just
                            # skip it.
                            pass

                    #The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev.
                    # I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|
                    if line.count("The 6 columns") > 0:
                        is_data_started = True

                # Sanity check
                if not len(y) == len(dy):
                    msg = "abs_reader: y and dy have different length"
                    raise ValueError, msg
                # If the data length is zero, consider this as
                # though we were not able to read the file.
                if len(x) == 0:
                    raise ValueError, "ascii_reader: could not load file"

                output.x = x[x != 0]
                output.y = y[x != 0]
                output.dy = dy[x != 0]
                output.dx = dx[x != 0]
                if data_conv_q is not None:
                    output.xaxis("\\rm{Q}", output.x_unit)
                else:
                    output.xaxis("\\rm{Q}", 'A^{-1}')
                if data_conv_i is not None:
                    output.yaxis("\\rm{Intensity}", output.y_unit)
                else:
                    output.yaxis("\\rm{Intensity}", "cm^{-1}")

                # Store loading process information
                output.meta_data['loader'] = self.type_name
                return output
        else:
            raise RuntimeError, "%s is not a file" % path
        return None