def generate_field_report(data, run_dir, args=None): grid = data.models.simulationGrid axes, slice_axis, phi_slice, show3d = _field_input(args) slice_text = ' ({} = {}µm)'.format(slice_axis, round(phi_slice, 3)) \ if _SIM_DATA.warpvnd_is_3d(data) else '' f = str(py.path.local(run_dir).join(_POTENTIAL_FILE)) with h5py.File(f, 'r') as hf: potential = np.array(template_common.h5_to_dict(hf, path='potential')) # if 2d potential, asking for 2d vs 3d doesn't matter if len(potential.shape) == 2: values = potential[:grid.num_x + 1, :grid.num_z + 1] else: values = _field_values(potential, axes, phi_slice, grid) vals_equal = np.isclose(np.std(values), 0., atol=1e-9) if np.isnan(values).any(): raise sirepo.util.UserAlert( 'Results could not be calculated.\n\nThe Simulation Grid may' ' require adjustments to the Grid Points and Channel Width.') res = _field_plot(values, axes, grid, _SIM_DATA.warpvnd_is_3d(data)) res.title = 'ϕ Across Whole Domain' + slice_text res.global_min = np.min(potential) if vals_equal else None res.global_max = np.max(potential) if vals_equal else None res.frequency_title = 'Volts' return res
def _read_data(sim_id, view_type, field_type): try: with h5py.File(_geom_file(sim_id), 'r') as hf: g = template_common.h5_to_dict(hf, path=_geom_h5_path( view_type, field_type)) return g except IOError: return {}
def _read_h5_path(sim_id, h5path): try: with h5py.File(_geom_file(sim_id), 'r') as hf: return template_common.h5_to_dict(hf, path=h5path) except IOError as e: if pkio.exception_is_not_found(e): # need to generate file return None except KeyError: # no such path in file return None
def _read_h5_path(sim_id, filename, h5path, run_dir=_GEOM_DIR): try: with h5py.File(_get_res_file(sim_id, filename, run_dir=run_dir), 'r') as hf: return template_common.h5_to_dict(hf, path=h5path) except IOError as e: if pkio.exception_is_not_found(e): pkdc(f'{filename} not found in {run_dir}') # need to generate file return None except KeyError: # no such path in file pkdc(f'path {h5path} not found in {run_dir}/{filename}') return None
def _extract_particle(run_dir, model_name, data, args): limit = int(args.renderCount) hf = h5py.File(str(run_dir.join(_PARTICLE_FILE)), 'r') d = template_common.h5_to_dict(hf, 'particle') kept_electrons = d['kept'] lost_electrons = d['lost'] hf.close() grid = data['models']['simulationGrid'] plate_spacing = _meters(grid['plate_spacing']) radius = _meters(grid['channel_width'] / 2.) half_height = grid['channel_height'] if 'channel_height' in grid else 5. half_height = _meters(half_height / 2.) x_points = [] y_points = [] z_points = [] _add_particle_paths(kept_electrons, x_points, y_points, z_points, half_height, limit) lost_x = [] lost_y = [] lost_z = [] _add_particle_paths(lost_electrons, lost_x, lost_y, lost_z, half_height, limit) data_file = open_data_file(run_dir, model_name, None) with h5py.File(data_file.filename, 'r') as f: field = np.array(f['data/{}/meshes/{}'.format(data_file.iteration, 'phi')]) return { 'title': 'Particle Trace', 'x_range': [0, plate_spacing], 'y_label': 'x [m]', 'x_label': 'z [m]', 'z_label': 'y [m]', 'points': y_points, 'x_points': x_points, 'z_points': z_points, 'y_range': [-radius, radius], 'z_range': [-half_height, half_height], 'lost_x': lost_x, 'lost_y': lost_y, 'lost_z': lost_z, 'field': field.tolist() }
def _extract_impact_density_3d(run_dir, data): try: with h5py.File(str(run_dir.join(_DENSITY_FILE)), 'r') as hf: plot_info = template_common.h5_to_dict(hf, path='density') except IOError: plot_info = {'error': 'Cannot load density file'} if 'error' in plot_info: if not _SIM_DATA.warpvnd_is_3d(data): return plot_info # for 3D, continue on so particle trace is still rendered plot_info = { 'dx': 0, 'dz': 0, 'min': 0, 'max': 0, } #TODO(pjm): consolidate these parameters into one routine used by all reports grid = data.models.simulationGrid plate_spacing = _meters(grid.plate_spacing) radius = _meters(grid.channel_width / 2.) width = 0 dx = plot_info['dx'] dy = 0 dz = plot_info['dz'] if _SIM_DATA.warpvnd_is_3d(data): dy = 0 #plot_info['dy'] width = _meters(grid.channel_width) return { 'title': 'Impact Density', 'x_range': [0, plate_spacing], 'y_range': [-radius, radius], 'z_range': [-width / 2., width / 2.], 'y_label': 'x [m]', 'x_label': 'z [m]', 'z_label': 'y [m]', 'density': plot_info['density'] if 'density' in plot_info else [], 'v_min': plot_info['min'], 'v_max': plot_info['max'], }
def _extract_impact_density(run_dir, data): try: with h5py.File(str(run_dir.join(_DENSITY_FILE)), 'r') as hf: plot_info = template_common.h5_to_dict(hf, path='density') except IOError: plot_info = { 'error': 'Cannot load density file' } if 'error' in plot_info: if not _SIM_DATA.warpvnd_is_3d(data): return plot_info # for 3D, continue on so particle trace is still rendered plot_info = { 'dx': 0, 'dz': 0, 'min': 0, 'max': 0, } #TODO(pjm): consolidate these parameters into one routine used by all reports grid = data.models.simulationGrid plate_spacing = _meters(grid.plate_spacing) radius = _meters(grid.channel_width / 2.) width = 0 dx = plot_info['dx'] dy = 0 dz = plot_info['dz'] if _SIM_DATA.warpvnd_is_3d(data): dy = 0 #plot_info['dy'] width = _meters(grid.channel_width) gated_ids = plot_info['gated_ids'] if 'gated_ids' in plot_info else [] lines = [] for i in gated_ids: v = gated_ids[i] for pos in ('bottom', 'left', 'right', 'top'): if pos in v: zmin, zmax, xmin, xmax = v[pos]['limits'] row = { 'density': v[pos]['density'].tolist(), } if pos in ('bottom', 'top'): row['align'] = 'horizontal' row['points'] = [zmin, zmax, xmin + dx / 2.] else: row['align'] = 'vertical' row['points'] = [xmin, xmax, zmin + dz / 2.] lines.append(row) return { 'title': 'Impact Density', 'x_range': [0, plate_spacing], 'y_range': [-radius, radius], 'z_range': [-width / 2., width / 2.], 'y_label': 'x [m]', 'x_label': 'z [m]', 'z_label': 'y [m]', 'density': plot_info['density'] if 'density' in plot_info else [], 'density_lines': lines, 'v_min': plot_info['min'], 'v_max': plot_info['max'], }