source: sasview/test/sasdataloader/test/utest_cansas.py @ 56dac0b

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalcmagnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 56dac0b was 56dac0b, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

py3 doesn't have StringIO package

  • Property mode set to 100644
File size: 12.5 KB
Line 
1"""
2    Unit tests for the new recursive cansas reader
3"""
4import os
5import sys
6from io import StringIO
7import unittest
8import logging
9import warnings
10
11from lxml import etree
12from lxml.etree import XMLSyntaxError
13from xml.dom import minidom
14
15import sas.sascalc.dataloader.readers.cansas_reader as cansas
16from sas.sascalc.dataloader.loader import Loader
17from sas.sascalc.dataloader.data_info import Data1D, Data2D
18from sas.sascalc.dataloader.readers.xml_reader import XMLreader
19from sas.sascalc.dataloader.readers.cansas_reader import Reader
20from sas.sascalc.dataloader.readers.cansas_constants import CansasConstants
21
22logger = logging.getLogger(__name__)
23
24warnings.simplefilter("ignore")
25
26CANSAS_FORMAT = CansasConstants.CANSAS_FORMAT
27CANSAS_NS = CansasConstants.CANSAS_NS
28
29class cansas_reader_xml(unittest.TestCase):
30
31    def setUp(self):
32        self.loader = Loader()
33        self.xml_valid = "cansas_test_modified.xml"
34        self.xml_invalid = "cansas_test.xml"
35        self.cansas1d_badunits = "cansas1d_badunits.xml"
36        self.cansas1d = "cansas1d.xml"
37        self.cansas1d_slit = "cansas1d_slit.xml"
38        self.cansas1d_units = "cansas1d_units.xml"
39        self.cansas1d_notitle = "cansas1d_notitle.xml"
40        self.isis_1_0 = "ISIS_1_0.xml"
41        self.isis_1_1 = "ISIS_1_1.xml"
42        self.isis_1_1_notrans = "ISIS_1_1_notrans.xml"
43        self.isis_1_1_doubletrans = "ISIS_1_1_doubletrans.xml"
44        self.schema_1_0 = "cansas1d_v1_0.xsd"
45        self.schema_1_1 = "cansas1d_v1_1.xsd"
46        self.write_1_0_filename = "isis_1_0_write_test.xml"
47        self.write_1_1_filename = "isis_1_1_write_test.xml"
48
49    def get_number_of_entries(self, dictionary, name, i):
50        if dictionary.get(name) is not None:
51            i += 1
52            name = name.split("_")[0]
53            name += "_{0}".format(i)
54            name = self.get_number_of_entries(dictionary, name, i)
55        return name
56
57    def test_invalid_xml(self):
58        """
59        Should fail gracefully and send a message to logger.info()
60        """
61        invalid = StringIO('<a><c></b></a>')
62        self.assertRaises(XMLSyntaxError, lambda: XMLreader(invalid))
63
64    def test_xml_validate(self):
65        string = "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n"
66        string += "\t<xsd:element name=\"a\" type=\"AType\"/>\n"
67        string += "\t<xsd:complexType name=\"AType\">\n"
68        string += "\t\t<xsd:sequence>\n"
69        string += "\t\t\t<xsd:element name=\"b\" type=\"xsd:string\" />\n"
70        string += "\t\t</xsd:sequence>\n"
71        string += "\t</xsd:complexType>\n"
72        string += "</xsd:schema>"
73        f = StringIO(string)
74        xmlschema_doc = etree.parse(f)
75        xmlschema = etree.XMLSchema(xmlschema_doc)
76        valid = etree.parse(StringIO('<a><b></b></a>'))
77        invalid = etree.parse(StringIO('<a><c></c></a>'))
78        self.assertTrue(xmlschema.validate(valid))
79        self.assertFalse(xmlschema.validate(invalid))
80
81    def test_real_xml(self):
82        reader = XMLreader(self.xml_valid, self.schema_1_0)
83        valid = reader.validate_xml()
84        if valid:
85            self.assertTrue(valid)
86        else:
87            self.assertFalse(valid)
88
89    def _check_data(self, data):
90        self.assertTrue(data.title == "TK49 c10_SANS")
91        self.assertTrue(data.x.size == 138)
92        self.assertTrue(len(data.meta_data) == 3)
93        self.assertTrue(data.detector[0].distance_unit == "mm")
94        self.assertTrue(data.detector[1].distance_unit == "mm")
95        self.assertTrue(data.detector[0].name == "HAB")
96        self.assertTrue(data.detector[1].name == "main-detector-bank")
97        self.assertTrue(data.detector[0].distance == 575.0)
98        self.assertAlmostEqual(data.detector[1].distance, 4145.02)
99        self.assertTrue(data.process[0].name == "Mantid generated CanSAS1D XML")
100        self.assertTrue(data.meta_data["xmlpreprocess"] is not None)
101
102    def _check_data_1_1(self, data):
103        spectrum = data.trans_spectrum[0]
104        self.assertTrue(len(spectrum.wavelength) == 138)
105
106    def test_cansas_xml(self):
107        xmlreader = XMLreader(self.isis_1_1, self.schema_1_1)
108        valid = xmlreader.validate_xml()
109        xmlreader.set_processing_instructions()
110        self.assertTrue(valid)
111        reader_generic = Loader()
112        dataloader = reader_generic.load(self.isis_1_1)
113        reader_cansas = Reader()
114        cansasreader = reader_cansas.read(self.isis_1_1)
115        for i in range(len(dataloader)):
116            self._check_data(dataloader[i])
117            self._check_data_1_1(dataloader[i])
118            self._check_data(cansasreader[i])
119            self._check_data_1_1(cansasreader[i])
120            reader_generic.save(self.write_1_1_filename, dataloader[i], None)
121            reader2 = Loader()
122            self.assertTrue(os.path.isfile(self.write_1_1_filename))
123            return_data = reader2.load(self.write_1_1_filename)
124            written_data = return_data[0]
125            self._check_data(written_data)
126        if os.path.isfile(self.write_1_1_filename):
127            os.remove(self.write_1_1_filename)
128
129    def test_double_trans_spectra(self):
130        xmlreader = XMLreader(self.isis_1_1_doubletrans, self.schema_1_1)
131        self.assertTrue(xmlreader.validate_xml())
132        reader = Loader()
133        data = reader.load(self.isis_1_1_doubletrans)
134        for item in data:
135            self._check_data(item)
136
137    def test_entry_name_recurse(self):
138        test_values = [1,2,3,4,5,6]
139        base_key = "key"
140        d = {}
141        for value in test_values:
142            new_key = self.get_number_of_entries(d, base_key, i = 0)
143            d[new_key] = value
144        self.assertTrue(len(d) == 6)
145
146    def test_load_cansas_file(self):
147        reader1 = XMLreader(self.xml_valid, self.schema_1_0)
148        self.assertTrue(reader1.validate_xml())
149        reader2 = XMLreader(self.xml_invalid, self.schema_1_0)
150        self.assertFalse(reader2.validate_xml())
151        reader3 = XMLreader(self.xml_valid, self.schema_1_1)
152        self.assertFalse(reader3.validate_xml())
153        reader4 = XMLreader(self.xml_invalid, self.schema_1_1)
154        self.assertFalse(reader4.validate_xml())
155        reader5 = XMLreader(self.isis_1_0, self.schema_1_0)
156        self.assertTrue(reader5.validate_xml())
157        reader6 = XMLreader(self.isis_1_1, self.schema_1_1)
158        self.assertTrue(reader6.validate_xml())
159        reader7 = XMLreader(self.isis_1_1, self.schema_1_0)
160        self.assertFalse(reader7.validate_xml())
161
162    def test_invalid_cansas(self):
163        list = self.loader.load(self.cansas1d_notitle)
164        data = list[0]
165        self.assertTrue(data.x.size == 2)
166        self.assertTrue(len(data.meta_data) == 2)
167        self.assertTrue(len(data.errors) == 1)
168        self.assertTrue(data.detector[0].distance_unit == "mm")
169        self.assertTrue(data.detector[0].name == "fictional hybrid")
170        self.assertTrue(data.detector[0].distance == 4150)
171
172    def test_old_cansas_files(self):
173        reader1 = XMLreader(self.cansas1d, self.schema_1_0)
174        self.assertTrue(reader1.validate_xml())
175        file_loader = Loader()
176        file_loader.load(self.cansas1d)
177        reader2 = XMLreader(self.cansas1d_units, self.schema_1_0)
178        self.assertTrue(reader2.validate_xml())
179        reader3 = XMLreader(self.cansas1d_badunits, self.schema_1_0)
180        self.assertTrue(reader3.validate_xml())
181        reader4 = XMLreader(self.cansas1d_slit, self.schema_1_0)
182        self.assertTrue(reader4.validate_xml())
183
184    def test_save_cansas_v1_0(self):
185        xmlreader = XMLreader(self.isis_1_0, self.schema_1_0)
186        valid = xmlreader.validate_xml()
187        self.assertTrue(valid)
188        reader_generic = Loader()
189        dataloader = reader_generic.load(self.isis_1_0)
190        reader_cansas = Reader()
191        cansasreader = reader_cansas.read(self.isis_1_0)
192        for i in range(len(dataloader)):
193            self._check_data(dataloader[i])
194            self._check_data(cansasreader[i])
195            reader_generic.save(self.write_1_0_filename, dataloader[i], None)
196            reader2 = Reader()
197            self.assertTrue(os.path.isfile(self.write_1_0_filename))
198            return_data = reader2.read(self.write_1_0_filename)
199            written_data = return_data[0]
200            XMLreader(self.write_1_0_filename, self.schema_1_0)
201            valid = xmlreader.validate_xml()
202            self.assertTrue(valid)
203            self._check_data(written_data)
204        if os.path.isfile(self.write_1_0_filename):
205            os.remove(self.write_1_0_filename)
206
207    def test_processing_instructions(self):
208        reader = XMLreader(self.isis_1_1, self.schema_1_1)
209        valid = reader.validate_xml()
210        if valid:
211            # find the processing instructions and make into a dictionary
212            dic = self.get_processing_instructions(reader)
213            self.assertEqual(dic, {'xml-stylesheet':
214                                   'type="text/xsl" href="cansas1d.xsl" '})
215
216            xml = "<test><a><b><c></c></b></a></test>"
217            xmldoc = minidom.parseString(xml)
218
219            # take the processing instructions and put them back in
220            xmldoc = self.set_processing_instructions(xmldoc, dic)
221            xmldoc.toprettyxml()
222
223    def set_processing_instructions(self, minidom_object, dic):
224        xmlroot = minidom_object.firstChild
225        for item in dic:
226            pi = minidom_object.createProcessingInstruction(item, dic[item])
227            minidom_object.insertBefore(pi, xmlroot)
228        return minidom_object
229
230    def get_processing_instructions(self, xml_reader_object):
231        dict = {}
232        pi = xml_reader_object.xmlroot.getprevious()
233        i = 0
234        while pi is not None:
235            attr = {}
236            pi_name = ""
237            pi_string = etree.tostring(pi)
238            if isinstance(pi_string, str):
239                pi_string = pi_string.replace("<?", "").replace("?>", "")
240                split = pi_string.split(" ", 1)
241                pi_name = split[0]
242                attr = split[1]
243            dict[pi_name] = attr
244            pi = pi.getprevious()
245        return dict
246
247
248class cansas_reader_hdf5(unittest.TestCase):
249
250    def setUp(self):
251        self.loader = Loader()
252        self.datafile_basic = "simpleexamplefile.h5"
253        self.datafile_multiplesasentry = "cansas_1Dand2D_samedatafile.h5"
254        self.datafile_multiplesasdata = "cansas_1Dand2D_samesasentry.h5"
255        self.datafile_multiplesasdata_multiplesasentry = "cansas_1Dand2D_multiplesasentry_multiplesasdata.h5"
256
257    def test_real_data(self):
258        self.data = self.loader.load(self.datafile_basic)
259        self._check_example_data(self.data[0])
260
261    def test_multiple_sasentries(self):
262        self.data = self.loader.load(self.datafile_multiplesasentry)
263        self.assertTrue(len(self.data) == 2)
264        self._check_multiple_data(self.data[0])
265        self._check_multiple_data(self.data[1])
266        self._check_1d_data(self.data[0])
267
268    def _check_multiple_data(self, data):
269        self.assertTrue(data.title == "MH4_5deg_16T_SLOW")
270        self.assertTrue(data.run[0] == '33837')
271        self.assertTrue(len(data.run) == 1)
272        self.assertTrue(data.instrument == "SANS2D")
273        self.assertTrue(data.source.radiation == "Spallation Neutron Source")
274        self.assertTrue(len(data.detector) == 1)
275        self.assertTrue(data.detector[0].name == "rear-detector")
276        self.assertTrue(data.detector[0].distance == 4.385281)
277        self.assertTrue(data.detector[0].distance_unit == 'm')
278        self.assertTrue(len(data.trans_spectrum) == 1)
279
280    def _check_1d_data(self, data):
281        self.assertTrue(isinstance(data, Data1D))
282        self.assertTrue(len(data.x) == 66)
283        self.assertTrue(len(data.x) == len(data.y))
284        self.assertTrue(data.dy[10] == 0.20721350111248701)
285        self.assertTrue(data.y[10] == 24.193889608153476)
286        self.assertTrue(data.x[10] == 0.008981127988654792)
287
288    def _check_2d_data(self, data):
289        self.assertTrue(isinstance(data, Data2D))
290        self.assertTrue(len(data.x) == 66)
291        self.assertTrue(len(data.x) == len(data.y))
292        self.assertTrue(data.dy[10] == 0.20721350111248701)
293        self.assertTrue(data.y[10] == 24.193889608153476)
294        self.assertTrue(data.x[10] == 0.008981127988654792)
295
296    def _check_example_data(self, data):
297        self.assertTrue(data.title == "")
298        self.assertTrue(data.x.size == 100)
299        self.assertTrue(data._xunit == "A^{-1}")
300        self.assertTrue(data._yunit == "cm^{-1}")
301        self.assertTrue(data.y.size == 100)
302        self.assertAlmostEqual(data.y[40], 0.952749011516985)
303        self.assertAlmostEqual(data.x[40], 0.3834415188257777)
304        self.assertAlmostEqual(len(data.meta_data), 0)
305
306
307if __name__ == '__main__':
308    unittest.main()
Note: See TracBrowser for help on using the repository browser.