[80c5d46] | 1 | """ |
---|
| 2 | CanSAS 2D data reader for reading HDF5 formatted CanSAS files. |
---|
| 3 | """ |
---|
| 4 | |
---|
| 5 | import numpy as np |
---|
| 6 | import re |
---|
| 7 | import os |
---|
| 8 | import sys |
---|
| 9 | |
---|
| 10 | from sas.sascalc.dataloader.readers.xml_reader import XMLreader |
---|
| 11 | from sas.sascalc.dataloader.data_info import plottable_1D, Data1D, Sample, Source |
---|
| 12 | from sas.sascalc.dataloader.data_info import Process, Aperture, Collimation, TransmissionSpectrum, Detector |
---|
| 13 | |
---|
| 14 | |
---|
| 15 | class Reader(XMLreader): |
---|
| 16 | """ |
---|
| 17 | A class for reading in CanSAS v2.0 data files. The existing iteration opens Mantid generated HDF5 formatted files |
---|
| 18 | with file extension .h5/.H5. Any number of data sets may be present within the file and any dimensionality of data |
---|
| 19 | may be used. Currently 1D and 2D SAS data sets are supported, but future implementations will include 1D and 2D |
---|
| 20 | SESANS data. This class assumes a single data set for each sasentry. |
---|
| 21 | |
---|
| 22 | :Dependencies: |
---|
| 23 | The CanSAS HDF5 reader requires h5py v2.5.0 or later. |
---|
| 24 | """ |
---|
| 25 | |
---|
| 26 | ## Logged warnings or messages |
---|
| 27 | logging = None |
---|
| 28 | ## List of errors for the current data set |
---|
| 29 | errors = None |
---|
| 30 | ## Raw file contents to be processed |
---|
| 31 | raw_data = None |
---|
| 32 | ## Data set being modified |
---|
| 33 | current_dataset = None |
---|
| 34 | ## For recursion and saving purposes, remember parent objects |
---|
| 35 | parent_list = None |
---|
| 36 | ## Data type name |
---|
| 37 | type_name = "Anton Paar SAXSess" |
---|
| 38 | ## Wildcards |
---|
| 39 | type = ["Anton Paar SAXSess Files (*.pdh)|*.pdh"] |
---|
| 40 | ## List of allowed extensions |
---|
| 41 | ext = ['.pdh', '.PDH'] |
---|
| 42 | ## Flag to bypass extension check |
---|
| 43 | allow_all = False |
---|
| 44 | ## List of files to return |
---|
| 45 | output = None |
---|
| 46 | |
---|
| 47 | def __init__(self): |
---|
| 48 | self.current_dataset = Data1D(np.empty(0), np.empty(0), |
---|
| 49 | np.empty(0), np.empty(0)) |
---|
| 50 | self.datasets = [] |
---|
| 51 | self.raw_data = None |
---|
| 52 | self.errors = set() |
---|
| 53 | self.logging = [] |
---|
| 54 | self.output = [] |
---|
| 55 | self.detector = Detector() |
---|
| 56 | self.collimation = Collimation() |
---|
| 57 | self.aperture = Aperture() |
---|
| 58 | self.process = Process() |
---|
| 59 | self.source = Source() |
---|
| 60 | self.sample = Sample() |
---|
| 61 | self.trans_spectrum = TransmissionSpectrum() |
---|
| 62 | self.upper = 5 |
---|
| 63 | self.lower = 5 |
---|
| 64 | |
---|
| 65 | def read(self, filename): |
---|
| 66 | """ |
---|
| 67 | This is the general read method that all SasView data_loaders must have. |
---|
| 68 | |
---|
| 69 | :param filename: A path for an XML formatted Anton Paar SAXSess data file. |
---|
| 70 | :return: List of Data1D objects or a list of errors. |
---|
| 71 | """ |
---|
| 72 | |
---|
| 73 | ## Reinitialize the class when loading a new data file to reset all class variables |
---|
| 74 | self.__init__() |
---|
| 75 | ## Check that the file exists |
---|
| 76 | if os.path.isfile(filename): |
---|
| 77 | basename = os.path.basename(filename) |
---|
| 78 | _, extension = os.path.splitext(basename) |
---|
| 79 | # If the file type is not allowed, return empty list |
---|
| 80 | if extension in self.ext or self.allow_all: |
---|
| 81 | ## Load the data file |
---|
| 82 | input_f = open(filename, 'r') |
---|
| 83 | buff = input_f.read() |
---|
| 84 | self.raw_data = buff.splitlines() |
---|
| 85 | self.read_data() |
---|
| 86 | xml_intermediate = self.raw_data[self.upper:] |
---|
| 87 | xml = ''.join(xml_intermediate) |
---|
| 88 | self.set_xml_file(xml) |
---|
| 89 | return self.output |
---|
| 90 | |
---|
| 91 | def read_data(self): |
---|
| 92 | q_unit = "1/nm" |
---|
| 93 | i_unit = "1/um^2" |
---|
| 94 | self.current_dataset.title = self.raw_data[0] |
---|
| 95 | self.current_dataset.meta_data["Keywords"] = self.raw_data[1] |
---|
| 96 | line3 = self.raw_data[2].split() |
---|
| 97 | line4 = self.raw_data[3].split() |
---|
| 98 | line5 = self.raw_data[4].split() |
---|
| 99 | self.data_points = int(line3[0]) |
---|
| 100 | self.lower = 5 |
---|
| 101 | self.upper = self.lower + self.data_points |
---|
| 102 | self.detector.distance = float(line4[1]) |
---|
| 103 | self.current_dataset.source.radiation = "x-ray" |
---|
| 104 | self.current_dataset.source.name = "Anton Paar SAXSess Instrument" |
---|
| 105 | self.current_dataset.source.wavelength = float(line4[4]) |
---|
| 106 | normal = line4[3] |
---|
| 107 | for i in range(self.lower, self.upper): |
---|
| 108 | data = self.raw_data[i].split() |
---|
| 109 | x_val = [float(data[0])] |
---|
| 110 | y_val = [float(data[1])] |
---|
| 111 | dy_val = [float(data[2])] |
---|
| 112 | self.current_dataset.x = np.append(self.current_dataset.x, x_val) |
---|
| 113 | self.current_dataset.y = np.append(self.current_dataset.y, y_val) |
---|
| 114 | self.current_dataset.dy = np.append(self.current_dataset.dy, dy_val) |
---|
| 115 | self.current_dataset.xaxis("Q (%s)" % (q_unit), q_unit) |
---|
| 116 | self.current_dataset.yaxis("Intensity (%s)" % (i_unit), i_unit) |
---|
| 117 | self.current_dataset.detector.append(self.detector) |
---|
| 118 | self.output.append(self.current_dataset) |
---|