def read_zdf(filename, path=None): """ HDF reader for Osiris/Visxd compatible HDF files. Returns: H5Data object. """ fname = filename if not path else path + '/' + filename data, info = zdf.read(filename) run_attrs, data_attrs = {}, {} nx = list(reversed(info.grid.nx)) axes = [ DataAxis(ax.min, ax.max, nx[i], attrs={ 'LONG_NAME': ax.label, 'NAME': ax.label.replace('_', ''), 'UNITS': OSUnits(ax.units) }) for i, ax in enumerate(reversed(info.grid.axis)) ] timestamp = fn_rule.findall(os.path.basename(filename))[0] run_attrs['NX'] = info.grid.nx run_attrs['TIME UNITS'] = OSUnits(info.iteration.tunits) run_attrs['TIME'] = np.array([info.iteration.t]) run_attrs['TIMESTAMP'] = timestamp data_attrs['LONG_NAME'] = info.grid.label data_attrs['NAME'] = info.grid.label.replace('_', '') data_attrs['UNITS'] = OSUnits(info.grid.units) return H5Data(data, timestamp=timestamp, data_attrs=data_attrs, run_attrs=run_attrs, axes=axes)
def read_raw(filename, path=None): """ Read particle raw data into a numpy sturctured array. See numpy documents for detailed usage examples of the structured array. The only modification is that the meta data of the particles are stored in .attrs attributes. Usage: part = read_raw("raw-electron-000000.h5") # part is a subclass of numpy.ndarray with extra attributes print(part.shape) # should be a 1D array with # of particles print(part.attrs) # print all the meta data print(part.attrs['TIME']) # prints the simulation time associated with the hdf5 file """ fname = filename if not path else path + '/' + filename try: timestamp = fn_rule.findall(os.path.basename(filename))[0] except IndexError: timestamp = '000000' with h5py.File(fname, 'r') as data: quants = [k for k in data.keys()] new_ver = 'SIMULATION' in quants if new_ver: quants.remove('SIMULATION') # read in meta data d = {k: v for k, v in data.attrs.items()} # in the old version label and units are stored inside each quantity dataset if not new_ver: d['LABELS'] = [ data[q].attrs['LONG_NAME'][0].decode() for q in quants ] d['UNITS'] = [data[q].attrs['UNITS'][0].decode() for q in quants] else: d.update({k: v for k, v in data['SIMULATION'].attrs.items()}) d['LABELS'] = [n.decode() for n in d['LABELS']] d['UNITS'] = [n.decode() for n in d['UNITS']] d['QUANTS'] = quants #TODO: TIMESTAMP is not set in HDF5 file as of now (Aug 2019) so we make one up, check back when file format changes d['TIMESTAMP'] = timestamp dtype = [(q, data[q].dtype) for q in quants] r = PartData(data[dtype[0][0]].shape, dtype=dtype, attrs=d) for dt in dtype: r[dt[0]] = data[dt[0]] return r
def read_h5(filename, path=None, axis_name="AXIS/AXIS"): """ HDF reader for Osiris/Visxd compatible HDF files... This will slurp in the data and the attributes that describe the data (e.g. title, units, scale). Usage: diag_data = read_hdf('e1-000006.h5') # diag_data is a subclass of numpy.ndarray with extra attributes print(diag_data) # print the meta data print(diag_data.view(numpy.ndarray)) # print the raw data print(diag_data.shape) # prints the dimension of the raw data print(diag_data.run_attrs['TIME']) # prints the simulation time associated with the hdf5 file diag_data.data_attrs['UNITS'] # print units of the dataset points list(diag_data.data_attrs) # lists all attributes related to the data array list(diag_data.run_attrs) # lists all attributes related to the run print(diag_data.axes[0].attrs['UNITS']) # prints units of X-axis list(diag_data.axes[0].attrs) # lists all variables of the X-axis diag_data[slice(3)] print(rw.view(np.ndarray)) We will convert all byte strings stored in the h5 file to strings which are easier to deal with when writing codes see also write_h5() function in this file """ fname = filename if not path else path + '/' + filename data_file = h5py.File(fname, 'r') n_data = scan_hdf5_file_for_main_data_array(data_file) timestamp, name, run_attrs, data_attrs, axes, data_bundle= '', '', {}, {}, [], [] try: timestamp = fn_rule.findall(os.path.basename(filename))[0] except IndexError: timestamp = '000000' axis_number = 1 while True: try: # try to open up another AXIS object in the HDF's attribute directory # (they are named /AXIS/AXIS1, /AXIS/AXIS2, /AXIS/AXIS3 ...) axis_to_look_for = axis_name + str(axis_number) axis = data_file[axis_to_look_for] # convert byte string attributes to string attrs = {} for k, v in axis.attrs.items(): try: attrs[k] = v[0].decode('utf-8') if isinstance(v[0], bytes) else v except IndexError: attrs[k] = v.decode('utf-8') if isinstance(v, bytes) else v axis_min = axis[0] axis_max = axis[-1] axis_numberpoints = n_data[0].shape[-axis_number] data_axis = DataAxis(axis_min, axis_max, axis_numberpoints, attrs=attrs) axes.insert(0, data_axis) except KeyError: break axis_number += 1 # we need a loop here primarily (I think) for n_ene_bin phasespace data for the_data_hdf_object in n_data: name = the_data_hdf_object.name[1:] # ignore the beginning '/' # now read in attributes of the ROOT of the hdf5.. # there's lots of good info there. strip out the array if value is a string for key, value in data_file.attrs.items(): try: run_attrs[key] = value[0].decode('utf-8') if isinstance( value[0], bytes) else value except IndexError: run_attrs[key] = value.decode('utf-8') if isinstance( value, bytes) else value # attach attributes assigned to the data array to # the H5Data.data_attrs object, remove trivial dimension before assignment for key, value in the_data_hdf_object.attrs.items(): try: data_attrs[key] = value[0].decode('utf-8') if isinstance( value[0], bytes) else value except IndexError: data_attrs[key] = value.decode('utf-8') if isinstance( value, bytes) else value # convert unit string to osunit object try: data_attrs['UNITS'] = OSUnits(data_attrs['UNITS']) except KeyError: data_attrs['UNITS'] = OSUnits('a.u.') data_attrs['NAME'] = name # data_bundle.data = the_data_hdf_object[()] data_bundle.append( H5Data(the_data_hdf_object, timestamp=timestamp, data_attrs=data_attrs, run_attrs=run_attrs, axes=axes)) data_file.close() if len(data_bundle) == 1: return data_bundle[0] else: return data_bundle
def read_h5_openpmd(filename, path=None): """ HDF reader for OpenPMD compatible HDF files... This will slurp in the data and the attributes that describe the data (e.g. title, units, scale). Usage: diag_data = read_hdf_openpmd('EandB000006.h5') # diag_data is a subclass of numpy.ndarray with extra attributes print(diag_data) # print the meta data print(diag_data.view(numpy.ndarray)) # print the raw data print(diag_data.shape) # prints the dimension of the raw data print(diag_data.run_attrs['TIME']) # prints the simulation time associated with the hdf5 file diag_data.data_attrs['UNITS'] # print units of the dataset points list(diag_data.data_attrs) # lists all attributes related to the data array list(diag_data.run_attrs) # lists all attributes related to the run print(diag_data.axes[0].attrs['UNITS']) # prints units of X-axis list(diag_data.axes[0].attrs) # lists all variables of the X-axis diag_data[slice(3)] print(rw.view(np.ndarray)) We will convert all byte strings stored in the h5 file to strings which are easier to deal with when writing codes see also write_h5() function in this file """ fname = filename if not path else path + '/' + filename with h5py.File(fname, 'r') as data_file: try: timestamp = fn_rule.findall(os.path.basename(filename))[0] except IndexError: timestamp = '00000000' basePath = data_file.attrs['basePath'].decode('utf-8').replace( '%T', timestamp) meshPath = basePath + data_file.attrs['meshesPath'].decode('utf-8') run_attrs = { k.upper(): v for k, v in data_file[basePath].attrs.items() } run_attrs.setdefault('TIME UNITS', r'1 / \omega_p') # read field data lname_dict, fldl = { 'E1': 'E_x', 'E2': 'E_y', 'E3': 'E_z', 'B1': 'B_x', 'B2': 'B_y', 'B3': 'B_z', 'jx': 'J_x', 'jy': 'J_y', 'jz': 'J_z', 'rho': r'\roh' }, {} # k is the field label and v is the field dataset for k, v in data_file[meshPath].items(): # openPMD doesn't enforce attrs that are required in OSIRIS dataset data_attrs, dflt_ax_unit = \ {'UNITS': OSUnits(r'm_e c \omega_p e^{-1} '), 'LONG_NAME': lname_dict.get(k, k), 'NAME': k}, r'c \omega_p^{-1}' data_attrs.update({ia: va for ia, va in v.attrs.items()}) ax_label, ax_off, g_spacing, ax_pos, unitsi = \ data_attrs.pop('axisLabels'), data_attrs.pop('gridGlobalOffset'), \ data_attrs.pop('gridSpacing'), data_attrs.pop('position'), data_attrs.pop('unitSI') ax_min = (ax_off + ax_pos * g_spacing) * unitsi ax_max = ax_min + v.shape * g_spacing * unitsi # prepare the axes data axes = [] for aln, an, amax, amin, anp in zip(ax_label, ax_label, ax_max, ax_min, v.shape): ax_attrs = { 'LONG_NAME': aln.decode('utf-8'), 'NAME': an.decode('utf-8'), 'UNITS': dflt_ax_unit } data_axis = DataAxis(amin, amax, anp, attrs=ax_attrs) axes.append(data_axis) fldl[k] = H5Data(v[()], timestamp=timestamp, data_attrs=data_attrs, run_attrs=run_attrs, axes=axes) return fldl