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

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 f00072f was f00072f, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

update cansas reader tests for python 3

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