source: sasview/test/sasdataloader/test/utest_cansas.py @ f53d684

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

Make tests work from any directory and functional without special runner script (#124)

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