1 | from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader |
---|
2 | from sas.sascalc.dataloader.data_info import Data1D |
---|
3 | |
---|
4 | import inspect |
---|
5 | |
---|
6 | class CansasWriter(CansasReader): |
---|
7 | |
---|
8 | def write(self, filename, frame_data, sasentry_attrs=None): |
---|
9 | """ |
---|
10 | Write the content of a Data1D as a CanSAS XML file |
---|
11 | |
---|
12 | :param filename: name of the file to write |
---|
13 | :param datainfo: Data1D object |
---|
14 | """ |
---|
15 | # Create XML document |
---|
16 | doc, _ = self._to_xml_doc(frame_data, sasentry_attrs) |
---|
17 | # Write the file |
---|
18 | file_ref = open(filename, 'w') |
---|
19 | if self.encoding is None: |
---|
20 | self.encoding = "UTF-8" |
---|
21 | doc.write(file_ref, encoding=self.encoding, |
---|
22 | pretty_print=True, xml_declaration=True) |
---|
23 | file_ref.close() |
---|
24 | |
---|
25 | |
---|
26 | def _to_xml_doc(self, frame_data, sasentry_attrs=None): |
---|
27 | """ |
---|
28 | Create an XML document to contain the content of an array of Data1Ds |
---|
29 | |
---|
30 | :param frame_data: An array of Data1D objects |
---|
31 | """ |
---|
32 | valid_class = all([issubclass(data.__class__, Data1D) for data in frame_data]) |
---|
33 | if not valid_class: |
---|
34 | raise RuntimeError("The cansas writer expects an array of " |
---|
35 | "Data1D instances") |
---|
36 | |
---|
37 | # Get PIs and create root element |
---|
38 | pi_string = self._get_pi_string() |
---|
39 | # Define namespaces and create SASroot object |
---|
40 | main_node = self._create_main_node() |
---|
41 | # Create ElementTree, append SASroot and apply processing instructions |
---|
42 | base_string = pi_string + self.to_string(main_node) |
---|
43 | base_element = self.create_element_from_string(base_string) |
---|
44 | doc = self.create_tree(base_element) |
---|
45 | # Create SASentry Element |
---|
46 | entry_node = self.create_element("SASentry", sasentry_attrs) |
---|
47 | root = doc.getroot() |
---|
48 | root.append(entry_node) |
---|
49 | |
---|
50 | # Use the first element in the array for writing metadata |
---|
51 | datainfo = frame_data[0] |
---|
52 | # Add Title to SASentry |
---|
53 | self.write_node(entry_node, "Title", datainfo.title) |
---|
54 | # Add Run to SASentry |
---|
55 | self._write_run_names(datainfo, entry_node) |
---|
56 | # Add Data info to SASEntry |
---|
57 | for data_info in frame_data: |
---|
58 | self._write_data(data_info, entry_node) |
---|
59 | # Transmission Spectrum Info |
---|
60 | self._write_trans_spectrum(datainfo, entry_node) |
---|
61 | # Sample info |
---|
62 | self._write_sample_info(datainfo, entry_node) |
---|
63 | # Instrument info |
---|
64 | instr = self._write_instrument(datainfo, entry_node) |
---|
65 | # Source |
---|
66 | self._write_source(datainfo, instr) |
---|
67 | # Collimation |
---|
68 | self._write_collimation(datainfo, instr) |
---|
69 | # Detectors |
---|
70 | self._write_detectors(datainfo, instr) |
---|
71 | # Processes info |
---|
72 | self._write_process_notes(datainfo, entry_node) |
---|
73 | # Note info |
---|
74 | self._write_notes(datainfo, entry_node) |
---|
75 | # Return the document, and the SASentry node associated with |
---|
76 | # the data we just wrote |
---|
77 | |
---|
78 | return doc, entry_node |
---|
79 | |
---|
80 | def _write_data(self, datainfo, entry_node): |
---|
81 | """ |
---|
82 | Writes the I and Q data to the XML file |
---|
83 | |
---|
84 | :param datainfo: The Data1D object the information is coming from |
---|
85 | :param entry_node: lxml node ElementTree object to be appended to |
---|
86 | """ |
---|
87 | node = self.create_element("SASdata") |
---|
88 | self.append(node, entry_node) |
---|
89 | |
---|
90 | for i in range(len(datainfo.x)): |
---|
91 | point = self.create_element("Idata") |
---|
92 | node.append(point) |
---|
93 | self.write_node(point, "Q", datainfo.x[i], |
---|
94 | {'unit': datainfo.x_unit}) |
---|
95 | if len(datainfo.y) >= i: |
---|
96 | self.write_node(point, "I", datainfo.y[i], |
---|
97 | {'unit': datainfo.y_unit}) |
---|
98 | if datainfo.dy is not None and len(datainfo.dy) > i: |
---|
99 | self.write_node(point, "Idev", datainfo.dy[i], |
---|
100 | {'unit': datainfo.y_unit}) |
---|
101 | if datainfo.dx is not None and len(datainfo.dx) > i: |
---|
102 | self.write_node(point, "Qdev", datainfo.dx[i], |
---|
103 | {'unit': datainfo.x_unit}) |
---|
104 | if datainfo.dxw is not None and len(datainfo.dxw) > i: |
---|
105 | self.write_node(point, "dQw", datainfo.dxw[i], |
---|
106 | {'unit': datainfo.x_unit}) |
---|
107 | if datainfo.dxl is not None and len(datainfo.dxl) > i: |
---|
108 | self.write_node(point, "dQl", datainfo.dxl[i], |
---|
109 | {'unit': datainfo.x_unit}) |
---|