source: sasview/test/sasdataloader/test/utest_cansas.py @ 83b6408

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 83b6408 was 83b6408, checked in by krzywon, 8 years ago

Modified Cansas XML reader to attempt to load data that doesn't fully meet the cansas format.

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