[8976865] | 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 | |
---|
[eb8da5f] | 8 | def write(self, filename, frame_data, sasentry_attrs=None): |
---|
[8976865] | 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 |
---|
[eb8da5f] | 16 | doc, _ = self._to_xml_doc(frame_data, sasentry_attrs) |
---|
[8976865] | 17 | # Write the file |
---|
| 18 | file_ref = open(filename, 'w') |
---|
[235f514] | 19 | if self.encoding is None: |
---|
[8976865] | 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 | |
---|
[eb8da5f] | 26 | def _to_xml_doc(self, frame_data, sasentry_attrs=None): |
---|
[8976865] | 27 | """ |
---|
[eb8da5f] | 28 | Create an XML document to contain the content of an array of Data1Ds |
---|
[8976865] | 29 | |
---|
[eb8da5f] | 30 | :param frame_data: An array of Data1D objects |
---|
[8976865] | 31 | """ |
---|
[eb8da5f] | 32 | valid_class = all([issubclass(data.__class__, Data1D) for data in frame_data]) |
---|
| 33 | if not valid_class: |
---|
[574adc7] | 34 | raise RuntimeError("The cansas writer expects an array of " |
---|
[eb8da5f] | 35 | "Data1D instances") |
---|
[8976865] | 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 | |
---|
[eb8da5f] | 50 | # Use the first element in the array for writing metadata |
---|
| 51 | datainfo = frame_data[0] |
---|
[8976865] | 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 |
---|
[94f4518] | 57 | for data_info in frame_data: |
---|
| 58 | self._write_data(data_info, entry_node) |
---|
[8976865] | 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 |
---|
[eb8da5f] | 77 | |
---|
[8976865] | 78 | return doc, entry_node |
---|
[eb8da5f] | 79 | |
---|
[94f4518] | 80 | def _write_data(self, datainfo, entry_node): |
---|
[eb8da5f] | 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 | """ |
---|
[94f4518] | 87 | node = self.create_element("SASdata") |
---|
| 88 | self.append(node, entry_node) |
---|
[eb8da5f] | 89 | |
---|
[94f4518] | 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}) |
---|
[7432acb] | 98 | if datainfo.dy is not None and len(datainfo.dy) > i: |
---|
[94f4518] | 99 | self.write_node(point, "Idev", datainfo.dy[i], |
---|
| 100 | {'unit': datainfo.y_unit}) |
---|
[7432acb] | 101 | if datainfo.dx is not None and len(datainfo.dx) > i: |
---|
[94f4518] | 102 | self.write_node(point, "Qdev", datainfo.dx[i], |
---|
| 103 | {'unit': datainfo.x_unit}) |
---|
[7432acb] | 104 | if datainfo.dxw is not None and len(datainfo.dxw) > i: |
---|
[94f4518] | 105 | self.write_node(point, "dQw", datainfo.dxw[i], |
---|
| 106 | {'unit': datainfo.x_unit}) |
---|
[7432acb] | 107 | if datainfo.dxl is not None and len(datainfo.dxl) > i: |
---|
[94f4518] | 108 | self.write_node(point, "dQl", datainfo.dxl[i], |
---|
[eb8da5f] | 109 | {'unit': datainfo.x_unit}) |
---|