Changeset b8080e1 in sasview for src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
- Timestamp:
- Aug 29, 2018 10:01:23 AM (6 years ago)
- Branches:
- ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- 9463ca2
- Parents:
- ce30949
- git-author:
- Piotr Rozyczko <rozyczko@…> (08/29/18 09:59:56)
- git-committer:
- Piotr Rozyczko <rozyczko@…> (08/29/18 10:01:23)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
rc416a17 rb8080e1 9 9 import sys 10 10 11 from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D,\11 from ..data_info import plottable_1D, plottable_2D,\ 12 12 Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \ 13 13 TransmissionSpectrum, Detector 14 from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable 15 16 17 class Reader(): 14 from ..data_info import combine_data_info_with_plottable 15 from ..loader_exceptions import FileContentsException, DefaultReaderException 16 from ..file_reader_base_class import FileReader, decode 17 18 def h5attr(node, key, default=None): 19 return decode(node.attrs.get(key, default)) 20 21 class Reader(FileReader): 18 22 """ 19 23 A class for reading in CanSAS v2.0 data files. The existing iteration opens … … 25 29 Any number of SASdata sets may be present in a SASentry and the data within 26 30 can be either 1D I(Q) or 2D I(Qx, Qy). 31 27 32 Also supports reading NXcanSAS formatted HDF5 files 28 33 … … 39 44 # Raw file contents to be processed 40 45 raw_data = None 41 # Data info currently being read in42 current_datainfo = None43 # SASdata set currently being read in44 current_dataset = None45 46 # List of plottable1D objects that should be linked to the current_datainfo 46 47 data1d = None … … 55 56 # Flag to bypass extension check 56 57 allow_all = True 57 # List of files to return 58 output = None 59 60 def read(self, filename): 58 59 def get_file_contents(self): 61 60 """ 62 61 This is the general read method that all SasView data_loaders must have. … … 66 65 """ 67 66 # Reinitialize when loading a new data file to reset all class variables 68 self.reset_class_variables() 67 self.reset_state() 68 69 filename = self.f_open.name 70 self.f_open.close() # IO handled by h5py 71 69 72 # Check that the file exists 70 73 if os.path.isfile(filename): … … 74 77 if extension in self.ext or self.allow_all: 75 78 # Load the data file 76 self.raw_data = h5py.File(filename, 'r') 77 # Read in all child elements of top level SASroot 78 self.read_children(self.raw_data, []) 79 # Add the last data set to the list of outputs 80 self.add_data_set() 81 # Close the data file 82 self.raw_data.close() 83 # Return data set(s) 84 return self.output 85 86 def reset_class_variables(self): 79 try: 80 self.raw_data = h5py.File(filename, 'r') 81 except Exception as e: 82 if extension not in self.ext: 83 msg = "CanSAS2.0 HDF5 Reader could not load file {}".format(basename + extension) 84 raise DefaultReaderException(msg) 85 raise FileContentsException(e.message) 86 try: 87 # Read in all child elements of top level SASroot 88 self.read_children(self.raw_data, []) 89 # Add the last data set to the list of outputs 90 self.add_data_set() 91 except Exception as exc: 92 raise FileContentsException(exc.message) 93 finally: 94 # Close the data file 95 self.raw_data.close() 96 97 for dataset in self.output: 98 if isinstance(dataset, Data1D): 99 if dataset.x.size < 5: 100 self.output = [] 101 raise FileContentsException("Fewer than 5 data points found.") 102 103 def reset_state(self): 87 104 """ 88 105 Create the reader object and define initial states for class variables 89 106 """ 90 self.current_datainfo = None 91 self.current_dataset = None 107 super(Reader, self).reset_state() 92 108 self.data1d = [] 93 109 self.data2d = [] … … 95 111 self.errors = set() 96 112 self.logging = [] 97 self.output = []98 113 self.parent_class = u'' 99 114 self.detector = Detector() … … 115 130 # Get all information for the current key 116 131 value = data.get(key) 117 if value.attrs.get(u'canSAS_class') is not None: 118 class_name = value.attrs.get(u'canSAS_class') 119 else: 120 class_name = value.attrs.get(u'NX_class') 132 class_name = h5attr(value, u'canSAS_class') 133 if class_name is None: 134 class_name = h5attr(value, u'NX_class') 121 135 if class_name is not None: 122 136 class_prog = re.compile(class_name) … … 125 139 126 140 if isinstance(value, h5py.Group): 141 # Set parent class before recursion 127 142 self.parent_class = class_name 128 143 parent_list.append(key) … … 135 150 # Recursion step to access data within the group 136 151 self.read_children(value, parent_list) 152 # Reset parent class when returning from recursive method 153 self.parent_class = class_name 137 154 self.add_intermediate() 138 155 parent_list.remove(key) … … 165 182 self.current_dataset.x = data_set.flatten() 166 183 continue 184 elif key == u'Qdev': 185 self.current_dataset.dx = data_set.flatten() 186 continue 187 elif key == u'dQw': 188 self.current_dataset.dxw = data_set.flatten() 189 continue 190 elif key == u'dQl': 191 self.current_dataset.dxl = data_set.flatten() 192 continue 167 193 elif key == u'Qy': 168 194 self.current_dataset.yaxis("Q_y", unit) … … 198 224 199 225 for data_point in data_set: 226 if isinstance(data_point, np.ndarray): 227 if data_point.dtype.char == 'S': 228 data_point = decode(bytes(data_point)) 229 else: 230 data_point = decode(data_point) 200 231 # Top Level Meta Data 201 232 if key == u'definition': … … 203 234 elif key == u'run': 204 235 self.current_datainfo.run.append(data_point) 236 try: 237 run_name = h5attr(value, 'name') 238 run_dict = {data_point: run_name} 239 self.current_datainfo.run_name = run_dict 240 except Exception: 241 pass 205 242 elif key == u'title': 206 243 self.current_datainfo.title = data_point … … 411 448 Data1D and Data2D objects 412 449 """ 413 414 450 # Type cast data arrays to float64 415 451 if len(self.current_datainfo.trans_spectrum) > 0: … … 435 471 # Type cast data arrays to float64 and find min/max as appropriate 436 472 for dataset in self.data2d: 437 dataset.data = dataset.data.astype(np.float64)438 dataset.err_data = dataset.err_data.astype(np.float64)439 if dataset.qx_data is not None:440 dataset.xmin = np.min(dataset.qx_data)441 dataset.xmax = np.max(dataset.qx_data)442 dataset.qx_data = dataset.qx_data.astype(np.float64)443 if dataset.dqx_data is not None:444 dataset.dqx_data = dataset.dqx_data.astype(np.float64)445 if dataset.qy_data is not None:446 dataset.ymin = np.min(dataset.qy_data)447 dataset.ymax = np.max(dataset.qy_data)448 dataset.qy_data = dataset.qy_data.astype(np.float64)449 if dataset.dqy_data is not None:450 dataset.dqy_data = dataset.dqy_data.astype(np.float64)451 if dataset.q_data is not None:452 dataset.q_data = dataset.q_data.astype(np.float64)453 473 zeros = np.ones(dataset.data.size, dtype=bool) 454 474 try: … … 473 493 dataset.x_bins = dataset.qx_data[:n_cols] 474 494 dataset.data = dataset.data.flatten() 475 476 final_dataset = combine_data_info_with_plottable( 477 dataset, self.current_datainfo) 478 self.output.append(final_dataset) 495 self.current_dataset = dataset 496 self.send_to_output() 479 497 480 498 for dataset in self.data1d: 481 if dataset.x is not None: 482 dataset.x = dataset.x.astype(np.float64) 483 dataset.xmin = np.min(dataset.x) 484 dataset.xmax = np.max(dataset.x) 485 if dataset.y is not None: 486 dataset.y = dataset.y.astype(np.float64) 487 dataset.ymin = np.min(dataset.y) 488 dataset.ymax = np.max(dataset.y) 489 if dataset.dx is not None: 490 dataset.dx = dataset.dx.astype(np.float64) 491 if dataset.dxl is not None: 492 dataset.dxl = dataset.dxl.astype(np.float64) 493 if dataset.dxw is not None: 494 dataset.dxw = dataset.dxw.astype(np.float64) 495 if dataset.dy is not None: 496 dataset.dy = dataset.dy.astype(np.float64) 497 final_dataset = combine_data_info_with_plottable( 498 dataset, self.current_datainfo) 499 self.output.append(final_dataset) 499 self.current_dataset = dataset 500 self.send_to_output() 500 501 501 502 def add_data_set(self, key=""): … … 579 580 :return: unit for the value passed to the method 580 581 """ 581 unit = value.attrs.get(u'units')582 unit = h5attr(value, u'units') 582 583 if unit is None: 583 unit = value.attrs.get(u'unit')584 unit = h5attr(value, u'unit') 584 585 # Convert the unit formats 585 586 if unit == "1/A":
Note: See TracChangeset
for help on using the changeset viewer.