source: sasview/test/sasdataloader/test/utest_cansas.py @ 1686a333

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 1686a333 was 1686a333, checked in by krzywon, 8 years ago

Added compatibility with save/load projects and analysis.

  • Property mode set to 100644
File size: 12.5 KB
Line 
1"""
2    Unit tests for the new recursive cansas reader
3"""
4import sas.sascalc.dataloader.readers.cansas_reader as cansas
5from sas.sascalc.dataloader.loader import Loader
6from sas.sascalc.dataloader.data_info import Data1D, Data2D
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
10
11import os
12import sys
13import urllib2
14import StringIO
15import pylint as pylint
16import unittest
17import numpy
18import logging
19import warnings
20
21from lxml import etree
22from xml.dom import minidom
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
47
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
55
56
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)
63
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))
81
82
83    def test_real_xml(self):
84        reader = XMLreader(self.xml_valid, self.schema_1_0)
85        valid = reader.validate_xml()
86        if valid:
87            self.assertTrue(valid)
88        else:
89            self.assertFalse(valid)
90
91
92    def _check_data(self, data):
93        self.assertTrue(data.title == "TK49 c10_SANS")
94        self.assertTrue(data.x.size == 138)
95        self.assertTrue(len(data.meta_data) == 3)
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.assertAlmostEqual(data.detector[1].distance, 4145.02)
102        self.assertTrue(data.process[0].name == "Mantid generated CanSAS1D XML")
103        self.assertTrue(data.meta_data["xmlpreprocess"] != None)
104
105
106    def _check_data_1_1(self, data):
107        spectrum = data.trans_spectrum[0]
108        self.assertTrue(len(spectrum.wavelength) == 138)
109
110
111    def test_cansas_xml(self):
112        filename = "isis_1_1_write_test.xml"
113        xmlreader = XMLreader(self.isis_1_1, self.schema_1_1)
114        valid = xmlreader.validate_xml()
115        xmlreader.set_processing_instructions()
116        self.assertTrue(valid)
117        fo = open(self.isis_1_1)
118        str = fo.read()
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])
125            self._check_data_1_1(dataloader[i])
126            self._check_data(cansasreader[i])
127            self._check_data_1_1(cansasreader[i])
128            reader_generic.save(filename, dataloader[i], None)
129            fo = open(filename)
130            str = fo.read()
131            reader2 = Loader()
132            return_data = reader2.load(filename)
133            written_data = return_data[0]
134            self._check_data(written_data)
135
136
137    def test_double_trans_spectra(self):
138        xmlreader = XMLreader(self.isis_1_1_doubletrans, self.schema_1_1)
139        self.assertTrue(xmlreader.validate_xml())
140        reader = Loader()
141        data = reader.load(self.isis_1_1_doubletrans)
142        for item in data:
143            self._check_data(item)
144
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
156    def test_load_cansas_file(self):
157        valid = []
158        reader1 = XMLreader(self.xml_valid, self.schema_1_0)
159        self.assertTrue(reader1.validate_xml())
160        reader2 = XMLreader(self.xml_invalid, self.schema_1_0)
161        self.assertFalse(reader2.validate_xml())
162        reader3 = XMLreader(self.xml_valid, self.schema_1_1)
163        self.assertFalse(reader3.validate_xml())
164        reader4 = XMLreader(self.xml_invalid, self.schema_1_1)
165        self.assertFalse(reader4.validate_xml())
166        reader5 = XMLreader(self.isis_1_0, self.schema_1_0)
167        self.assertTrue(reader5.validate_xml())
168        reader6 = XMLreader(self.isis_1_1, self.schema_1_1)
169        self.assertTrue(reader6.validate_xml())
170        reader7 = XMLreader(self.isis_1_1, self.schema_1_0)
171        self.assertFalse(reader7.validate_xml())
172
173
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) == 2)
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
185    def test_old_cansas_files(self):
186        reader1 = XMLreader(self.cansas1d, self.schema_1_0)
187        self.assertTrue(reader1.validate_xml())
188        file_loader = Loader()
189        file1 = file_loader.load(self.cansas1d)
190        reader2 = XMLreader(self.cansas1d_units, self.schema_1_0)
191        self.assertTrue(reader2.validate_xml())
192        reader3 = XMLreader(self.cansas1d_badunits, self.schema_1_0)
193        self.assertTrue(reader3.validate_xml())
194        reader4 = XMLreader(self.cansas1d_slit, self.schema_1_0)
195        self.assertTrue(reader4.validate_xml())
196
197
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)
201        valid = xmlreader.validate_xml()
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]
214            xmlwrite = XMLreader(filename, self.schema_1_0)
215            valid = xmlreader.validate_xml()
216            self.assertTrue(valid)
217            self._check_data(written_data)
218
219
220    def test_processing_instructions(self):
221        reader = XMLreader(self.isis_1_1, self.schema_1_1)
222        valid = reader.validate_xml()
223        if valid:
224            ## find the processing instructions and make into a dictionary
225            dic = self.get_processing_instructions(reader)
226            self.assertTrue(dic == {'xml-stylesheet': \
227                                    'type="text/xsl" href="cansas1d.xsl" '})
228
229            xml = "<test><a><b><c></c></b></a></test>"
230            xmldoc = minidom.parseString(xml)
231
232            ## take the processing instructions and put them back in
233            xmldoc = self.set_processing_instructions(xmldoc, dic)
234            xml_output = xmldoc.toprettyxml()
235
236
237    def set_processing_instructions(self, minidom_object, dic):
238        xmlroot = minidom_object.firstChild
239        for item in dic:
240            pi = minidom_object.createProcessingInstruction(item, dic[item])
241            minidom_object.insertBefore(pi, xmlroot)
242        return minidom_object
243
244
245    def get_processing_instructions(self, xml_reader_object):
246        dict = {}
247        pi = xml_reader_object.xmlroot.getprevious()
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
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
321
322if __name__ == '__main__':
323    unittest.main()   
Note: See TracBrowser for help on using the repository browser.