def run(cfg_dir): """Run shadow in ``cfg_dir`` Args: cfg_dir (str): directory to run shadow in """ with pkio.save_chdir(cfg_dir): beam = _run_shadow() data = simulation_db.read_json(template_common.INPUT_BASE_NAME) model = data['models'][data['report']] column_values = _SCHEMA['enum']['ColumnValue'] if 'y' in model: x_range = None y_range = None if model['overrideSize'] == '1': x_range = (np.array([ model['horizontalOffset'] - model['horizontalSize'] / 2, model['horizontalOffset'] + model['horizontalSize'] / 2, ]) * _MM_TO_CM).tolist() y_range = (np.array([ model['verticalOffset'] - model['verticalSize'] / 2, model['verticalOffset'] + model['verticalSize'] / 2, ]) * _MM_TO_CM).tolist() ticket = beam.histo2(int(model['x']), int(model['y']), nbins=template_common.histogram_bins(model['histogramBins']), ref=int(model['weight']), nolost=1, calculate_widths=0, xrange=x_range, yrange=y_range) _scale_ticket(ticket) res = { 'x_range': [ticket['xrange'][0], ticket['xrange'][1], ticket['nbins_h']], 'y_range': [ticket['yrange'][0], ticket['yrange'][1], ticket['nbins_v']], 'x_label': _label_with_units(model['x'], column_values), 'y_label': _label_with_units(model['y'], column_values), 'z_label': 'Frequency', 'title': u'{}, {}'.format(_label(model['x'], column_values), _label(model['y'], column_values)), 'z_matrix': ticket['histogram'].T.tolist(), 'frameCount': 1, } else: weight = int(model['weight']) ticket = beam.histo1(int(model['column']), nbins=template_common.histogram_bins(model['histogramBins']), ref=weight, nolost=1, calculate_widths=0) _scale_ticket(ticket) res = { 'title': _label(model['column'], column_values), 'x_range': [ticket['xrange'][0], ticket['xrange'][1], ticket['nbins']], 'y_label': u'{}{}'.format( 'Number of Rays', u' weighted by {}'.format(_label_for_weight(model['weight'], column_values)) if weight else ''), 'x_label': _label_with_units(model['column'], column_values), 'points': ticket['histogram'].T.tolist(), 'frameCount': 1, } #pkdp('range amount: {}', res['x_range'][1] - res['x_range'][0]) #1.55431223448e-15 dist = res['x_range'][1] - res['x_range'][0] #TODO(pjm): only rebalance range if outside of 0 if dist < 1e-14: #TODO(pjm): include offset range for client res['x_range'][0] = 0 res['x_range'][1] = dist simulation_db.write_result(res)
def _run_bunch_report(data, bunch, twiss): twiss0 = twiss[0] report = data.models[data['report']] particles = bunch.get_local_particles() x = particles[:, getattr(bunch, report['x'])] y = particles[:, getattr(bunch, report['y'])] hist, edges = np.histogramdd([x, y], template_common.histogram_bins( report['histogramBins'])) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': template.label(report['x']), 'y_label': template.label(report['y']), 'title': '{}-{}'.format(report['x'], report['y']), 'z_matrix': hist.T.tolist(), 'summaryData': { 'bunchTwiss': { 'alpha_x': template.format_float(twiss0['alpha_x']), 'alpha_y': template.format_float(twiss0['alpha_y']), 'beta_x': template.format_float(twiss0['beta_x']), 'beta_y': template.format_float(twiss0['beta_y']), }, }, }
def extract_report_data(xFilename, data, page_index, page_count=0): xfield = data['x'] if 'x' in data else data[_X_FIELD] # x, column_names, x_def, err x_col = sdds_util.extract_sdds_column(xFilename, xfield, page_index) if x_col['err']: return x_col['err'] x = x_col['values'] if not _is_histogram_file(xFilename, x_col['column_names']): # parameter plot plots = [] filename = { 'y1': xFilename, #TODO(pjm): y2Filename, y3Filename are not currently used. Would require rescaling x value across files. 'y2': xFilename, 'y3': xFilename, } for f in ('y1', 'y2', 'y3'): if re.search(r'^none$', data[f], re.IGNORECASE) or data[f] == ' ': continue yfield = data[f] y_col = sdds_util.extract_sdds_column(filename[f], yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] plots.append({ 'points': y, 'label': _field_label(yfield, y_col['column_def'][1]), }) title = '' if page_count > 1: title = 'Plot {} of {}'.format(page_index + 1, page_count) return { 'title': title, 'x_range': [min(x), max(x)], 'y_label': '', 'x_label': _field_label(xfield, x_col['column_def'][1]), 'x_points': x, 'plots': plots, 'y_range': template_common.compute_plot_color_and_range(plots), } yfield = data['y1'] if 'y1' in data else data['y'] y_col = sdds_util.extract_sdds_column(xFilename, yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] bins = data['histogramBins'] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(bins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': _field_label(xfield, x_col['column_def'][1]), 'y_label': _field_label(yfield, y_col['column_def'][1]), 'title': _plot_title(xfield, yfield, page_index, page_count), 'z_matrix': hist.T.tolist(), }
def _extract_bunch_plot(report, frame_index, run_dir): filename = _particle_file_list(run_dir)[frame_index] with h5py.File(str(filename), 'r') as f: x = f['particles'][:, _COORD6.index(report['x'])].tolist() y = f['particles'][:, _COORD6.index(report['y'])].tolist() data = simulation_db.read_json(run_dir.join(template_common.INPUT_BASE_NAME)) if 'bunchAnimation' not in data.models: # In case the simulation was run before the bunchAnimation was added return { 'error': 'Report not generated', } bunch_animation = data.models.bunchAnimation range = None if report['plotRangeType'] == 'fixed': range = [_plot_range(report, 'horizontal'), _plot_range(report, 'vertical')] elif report['plotRangeType'] == 'fit' and 'fieldRange' in bunch_animation: range = [bunch_animation.fieldRange[report['x']], bunch_animation.fieldRange[report['y']]] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(report['histogramBins']), range=range) tlen = f['tlen'][()] s_n = f['s_n'][()] rep = 0 if s_n == 0 else int(round(tlen / s_n)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': label(report['x']), 'y_label': label(report['y']), 'title': '{}-{} at {:.1f}m, turn {}'.format(report['x'], report['y'], tlen, rep), 'z_matrix': hist.T.tolist(), }
def _extract_particle_plot(report, run_dir, page_index): xfield = _map_field_name(report['x']) yfield = _map_field_name(report['y']) bins = report['histogramBins'] filename = _ion_files(run_dir)[page_index] data = simulation_db.read_json(run_dir.join(template_common.INPUT_BASE_NAME)) settings = data.models.simulationSettings time = settings.time / settings.step_number * settings.save_particle_interval * page_index if time > settings.time: time = settings.time x_col = sdds_util.extract_sdds_column(filename, xfield, 0) if x_col['err']: return x_col['err'] x = x_col['values'] y_col = sdds_util.extract_sdds_column(filename, yfield, 0) if y_col['err']: return y_col['err'] y = y_col['values'] particle_animation = data.models.particleAnimation range = None if report['plotRangeType'] == 'fixed': range = [_plot_range(report, 'horizontal'), _plot_range(report, 'vertical')] elif report['plotRangeType'] == 'fit' and 'fieldRange' in particle_animation: range = [particle_animation.fieldRange[xfield], particle_animation.fieldRange[yfield]] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(bins), range=range) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': _field_label(xfield, x_col['column_def']), 'y_label': _field_label(yfield, y_col['column_def']), 'title': 'Ions at time {:.2f} [s]'.format(time), 'z_matrix': hist.T.tolist(), }
def save_report_data(data, run_dir): if 'bunchReport' in data['report']: import synergia.bunch with h5py.File(str(run_dir.join(OUTPUT_FILE['twissReport'])), 'r') as f: twiss0 = dict(map( lambda k: (k, format_float(f[k][0])), ('alpha_x', 'alpha_y', 'beta_x', 'beta_y'), )) report = data.models[data['report']] bunch = data.models.bunch if bunch.distribution == 'file': bunch_file = template_common.lib_file_name('bunch', 'particleFile', bunch.particleFile) else: bunch_file = OUTPUT_FILE['bunchReport'] if not run_dir.join(bunch_file).exists(): return with h5py.File(str(run_dir.join(bunch_file)), 'r') as f: x = f['particles'][:, getattr(synergia.bunch.Bunch, report['x'])] y = f['particles'][:, getattr(synergia.bunch.Bunch, report['y'])] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(report['histogramBins'])) res = { 'title': '', 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': label(report['x'], _SCHEMA['enum']['PhaseSpaceCoordinate8']), 'y_label': label(report['y'], _SCHEMA['enum']['PhaseSpaceCoordinate8']), 'z_matrix': hist.T.tolist(), 'summaryData': { 'bunchTwiss': twiss0, }, } else: report_name = data['report'] x = None plots = [] report = data['models'][report_name] with h5py.File(str(run_dir.join(OUTPUT_FILE[report_name])), 'r') as f: x = f['s'][:].tolist() for yfield in ('y1', 'y2', 'y3'): if report[yfield] == 'none': continue name = report[yfield] plots.append({ 'name': name, 'label': label(report[yfield], _SCHEMA['enum']['TwissParameter']), 'points': f[name][:].tolist(), }) res = { 'title': '', 'x_range': [min(x), max(x)], 'y_range': template_common.compute_plot_color_and_range(plots), 'x_label': 's [m]', 'y_label': '', 'x_points': x, 'plots': plots, } simulation_db.write_result(res, run_dir=run_dir)
def extract_report_data(xFilename, data, page_index, page_count=0): xfield = data['x'] if 'x' in data else data[_X_FIELD] # x, column_names, x_def, err x_col = sdds_util.extract_sdds_column(xFilename, xfield, page_index) if x_col['err']: return x_col['err'] x = x_col['values'] if not _is_histogram_file(xFilename, x_col['column_names']): # parameter plot plots = [] filename = { 'y1': xFilename, #TODO(pjm): y2Filename, y3Filename are not currently used. Would require rescaling x value across files. 'y2': xFilename, 'y3': xFilename, } for f in ('y1', 'y2', 'y3'): if re.search(r'^none$', data[f], re.IGNORECASE) or data[f] == ' ': continue yfield = data[f] y_col = sdds_util.extract_sdds_column(filename[f], yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] plots.append({ 'points': y, 'label': _field_label(yfield, y_col['column_def'][1]), }) title = '' if page_count > 1: title = 'Plot {} of {}'.format(page_index + 1, page_count) return { 'title': title, 'x_range': [min(x), max(x)], 'y_label': '', 'x_label': _field_label(xfield, x_col['column_def'][1]), 'x_points': x, 'plots': plots, 'y_range': template_common.compute_plot_color_and_range(plots), } yfield = data['y1'] if 'y1' in data else data['y'] y_col = sdds_util.extract_sdds_column(xFilename, yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] bins = data['histogramBins'] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(bins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': _field_label(xfield, x_col['column_def'][1]), 'y_label': _field_label(yfield, y_col['column_def'][1]), 'title': _plot_title(xfield, yfield, page_index, page_count), 'z_matrix': hist.T.tolist(), }
def extract_beam_histrogram(report, run_dir, frame): beam_info = hellweg_dump_reader.beam_info(_dump_file(run_dir), frame) points = hellweg_dump_reader.get_points(beam_info, report.reportType) hist, edges = np.histogram(points, template_common.histogram_bins(report.histogramBins)) return { 'title': _report_title(report.reportType, 'BeamHistogramReportType', beam_info), 'x_range': [edges[0], edges[-1]], 'y_label': 'Number of Particles', 'x_label': hellweg_dump_reader.get_label(report.reportType), 'points': hist.T.tolist(), }
def extract_particle_report(frame_args, particle_type): data_file = open_data_file(frame_args.run_dir, frame_args.frameIndex) xarg = frame_args.x yarg = frame_args.y nbins = frame_args.histogramBins opmd = _opmd_time_series(data_file) data_list = opmd.get_particle( var_list=[xarg, yarg], species=particle_type, iteration=numpy.array([data_file.iteration]), select=None, output=True, plot=False, ) with h5py.File(data_file.filename) as f: data_list.append(main.read_species_data(f, particle_type, 'w', ())) select = _particle_selection_args(frame_args) if select: with h5py.File(data_file.filename) as f: main.apply_selection(f, data_list, select, particle_type, ()) xunits = ' [m]' if len(xarg) == 1 else '' yunits = ' [m]' if len(yarg) == 1 else '' if len(xarg) == 1: data_list[0] /= 1e6 if len(yarg) == 1: data_list[1] /= 1e6 if xarg == 'z': data_list = _adjust_z_width(data_list, data_file) hist, edges = numpy.histogramdd( [data_list[0], data_list[1]], template_common.histogram_bins(nbins), weights=data_list[2], range=[ _select_range(data_list[0], xarg, select), _select_range(data_list[1], yarg, select) ], ) return PKDict( x_range=[float(edges[0][0]), float(edges[0][-1]), len(hist)], y_range=[float(edges[1][0]), float(edges[1][-1]), len(hist[0])], x_label='{}{}'.format(xarg, xunits), y_label='{}{}'.format(yarg, yunits), title='t = {}'.format(_iteration_title(opmd, data_file)), z_matrix=hist.T.tolist(), frameCount=data_file.num_frames, )
def _extract_bunch_data(report, col_names, rows, title): x_info = _PHASE_SPACE_FIELD_INFO[report['x']] y_info = _PHASE_SPACE_FIELD_INFO[report['y']] x = np.array(column_data(report['x'], col_names, rows)) * x_info[1] y = np.array(column_data(report['y'], col_names, rows)) * y_info[1] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(report.histogramBins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': x_info[0], 'y_label': y_info[0], 'title': title, 'z_matrix': hist.T.tolist(), 'z_label': 'Number of Particles', }
def sim_frame_beamHistogramAnimation(frame_args): beam_info = hellweg_dump_reader.beam_info(_dump_file(run_dir)) points = hellweg_dump_reader.get_points(beam_info, frame_args.reportType) hist, edges = np.histogram( points, template_common.histogram_bins(frame_args.histogramBins)) return { 'title': _report_title(frame_args.reportType, 'BeamHistogramReportType', beam_info), 'x_range': [edges[0], edges[-1]], 'y_label': 'Number of Particles', 'x_label': hellweg_dump_reader.get_label(frame_args.reportType), 'points': hist.T.tolist(), }
def extract_particle_report(args, particle_type, run_dir, data_file): xarg = args.x yarg = args.y nbins = args.histogramBins opmd = _opmd_time_series(data_file) data_list = opmd.get_particle( var_list=[xarg, yarg], species=particle_type, iteration=numpy.array([data_file.iteration]), select=None, output=True, plot=False, ) with h5py.File(data_file.filename) as f: data_list.append(main.read_species_data(f, particle_type, 'w', ())) select = _particle_selection_args(args) if select: with h5py.File(data_file.filename) as f: main.apply_selection(f, data_list, select, particle_type, ()) xunits = ' [m]' if len(xarg) == 1 else '' yunits = ' [m]' if len(yarg) == 1 else '' if len(xarg) == 1: data_list[0] /= 1e6 if len(yarg) == 1: data_list[1] /= 1e6 if xarg == 'z': data_list = _adjust_z_width(data_list, data_file) hist, edges = numpy.histogramdd( [data_list[0], data_list[1]], template_common.histogram_bins(nbins), weights=data_list[2], range=[_select_range(data_list[0], xarg, select), _select_range(data_list[1], yarg, select)], ) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': '{}{}'.format(xarg, xunits), 'y_label': '{}{}'.format(yarg, yunits), 'title': 't = {}'.format(_iteration_title(opmd, data_file)), 'z_matrix': hist.T.tolist(), 'frameCount': data_file.num_frames, }
def _extract_bunch_data(report, col_names, rows, title): x_info = _PHASE_SPACE_FIELD_INFO[report['x']] y_info = _PHASE_SPACE_FIELD_INFO[report['y']] x = np.array(column_data(report['x'], col_names, rows)) * x_info[1] y = np.array(column_data(report['y'], col_names, rows)) * y_info[1] hist, edges = np.histogramdd([x, y], template_common.histogram_bins( report.histogramBins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': x_info[0], 'y_label': y_info[0], 'title': title, 'z_matrix': hist.T.tolist(), 'z_label': 'Number of Particles', }
def extract_beam_report(report, run_dir, frame): beam_info = hellweg_dump_reader.beam_info(_dump_file(run_dir), frame) x, y = report.reportType.split('-') data_list = [ hellweg_dump_reader.get_points(beam_info, x), hellweg_dump_reader.get_points(beam_info, y), ] hist, edges = numpy.histogramdd( data_list, template_common.histogram_bins(report.histogramBins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': hellweg_dump_reader.get_label(x), 'y_label': hellweg_dump_reader.get_label(y), 'title': _report_title(report.reportType, 'BeamReportType', beam_info), 'z_matrix': hist.T.tolist(), 'z_label': 'Number of Particles', 'summaryData': _summary_text(run_dir), }
def _run_bunch_report(data): import synergia.bunch with h5py.File(template.OUTPUT_FILE['twissReport'], 'r') as f: twiss0 = dict( map( lambda k: (k, template.format_float(f[k][0])), ('alpha_x', 'alpha_y', 'beta_x', 'beta_y'), )) report = data.models[data['report']] bunch = data.models.bunch if bunch.distribution == 'file': bunch_file = template_common.lib_file_name('bunch', 'particleFile', bunch.particleFile) else: bunch_file = template.OUTPUT_FILE['bunchReport'] with h5py.File(bunch_file, 'r') as f: x = f['particles'][:, getattr(synergia.bunch.Bunch, report['x'])] y = f['particles'][:, getattr(synergia.bunch.Bunch, report['y'])] hist, edges = np.histogramdd([x, y], template_common.histogram_bins( report['histogramBins'])) return { 'title': '{}-{}'.format(report['x'], report['y']), 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': template.label(report['x']), 'y_label': template.label(report['y']), 'z_matrix': hist.T.tolist(), 'summaryData': { 'bunchTwiss': twiss0, }, }
def extract_report_data(xFilename, yFilename, data, page_index): xfield = data['x'] if 'x' in data else data[_X_FIELD] # x, column_names, x_def, err x_col = sdds_util.extract_sdds_column(xFilename, xfield, page_index) if x_col['err']: return x_col['err'] x = x_col['values'] if 'y1' in data: # parameter plot y_range = None plots = [] for f in ('y1', 'y2', 'y3'): if data[f] == 'none': continue yfield = data[f] y_col = sdds_util.extract_sdds_column(yFilename, yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] if y_range: y_range[0] = min(y_range[0], min(y)) y_range[1] = max(y_range[1], max(y)) else: y_range = [min(y), max(y)] plots.append({ 'points': y, 'label': _field_label(yfield, y_col['column_def'][1]), #TODO(pjm): refactor with template_common.compute_plot_color_and_range() 'color': _PLOT_LINE_COLOR[f], }) return { 'title': '', 'x_range': [min(x), max(x)], 'y_label': '', 'x_label': _field_label(_X_FIELD, x_col['column_def'][1]), 'x_points': x, 'plots': plots, 'y_range': y_range, } yfield = data['y'] y_col = sdds_util.extract_sdds_column(yFilename, yfield, page_index) if y_col['err']: return y_col['err'] y = y_col['values'] if _is_2d_plot(x_col['column_names']): # 2d plot return { 'title': _plot_title(xfield, yfield, page_index), 'x_range': [np.min(x), np.max(x)], 'x_label': _field_label(xfield, x_col['column_def'][1]), 'y_label': _field_label(yfield, y_col['column_def'][1]), 'points': y, 'x_points': x, } bins = data['histogramBins'] hist, edges = np.histogramdd([x, y], template_common.histogram_bins(bins)) return { 'x_range': [float(edges[0][0]), float(edges[0][-1]), len(hist)], 'y_range': [float(edges[1][0]), float(edges[1][-1]), len(hist[0])], 'x_label': _field_label(xfield, x_col['column_def'][1]), 'y_label': _field_label(yfield, y_col['column_def'][1]), 'title': _plot_title(xfield, yfield, page_index), 'z_matrix': hist.T.tolist(), }
def _run_shadow(cfg_dir, data): beam = template_common.exec_parameters().beam model = data['models'][data['report']] column_values = _SCHEMA['enum']['ColumnValue'] if 'y' in model: x_range = None y_range = None if model['overrideSize'] == '1': x_range = (numpy.array([ model['horizontalOffset'] - model['horizontalSize'] / 2, model['horizontalOffset'] + model['horizontalSize'] / 2, ]) * _MM_TO_CM).tolist() y_range = (numpy.array([ model['verticalOffset'] - model['verticalSize'] / 2, model['verticalOffset'] + model['verticalSize'] / 2, ]) * _MM_TO_CM).tolist() ticket = beam.histo2( int(model['x']), int(model['y']), nbins=template_common.histogram_bins(model['histogramBins']), ref=int(model['weight']), nolost=1, calculate_widths=0, xrange=x_range, yrange=y_range, ) _scale_ticket(ticket) values = ticket['histogram'].T assert not numpy.isnan(values).any(), 'nan values found' res = PKDict( x_range=[ ticket['xrange'][0], ticket['xrange'][1], ticket['nbins_h'] ], y_range=[ ticket['yrange'][0], ticket['yrange'][1], ticket['nbins_v'] ], x_label=_label_with_units(model['x'], column_values), y_label=_label_with_units(model['y'], column_values), z_label='Intensity' if int(model['weight']) else 'Rays', title=u'{}, {}'.format(_label(model['x'], column_values), _label(model['y'], column_values)), z_matrix=values.tolist(), frameCount=1, ) else: weight = int(model['weight']) ticket = beam.histo1( int(model['column']), nbins=template_common.histogram_bins(model['histogramBins']), ref=weight, nolost=1, calculate_widths=0, ) _scale_ticket(ticket) res = PKDict( title=_label(model['column'], column_values), x_range=[ ticket['xrange'][0], ticket['xrange'][1], ticket['nbins'] ], y_label=u'{}{}'.format( 'Number of Rays', u' weighted by {}'.format( _label_for_weight(model['weight'], column_values)) if weight else ''), x_label=_label_with_units(model['column'], column_values), points=ticket['histogram'].T.tolist(), frameCount=1, ) #pkdlog('range amount: {}', res['x_range'][1] - res['x_range'][0]) #1.55431223448e-15 dist = res['x_range'][1] - res['x_range'][0] #TODO(pjm): only rebalance range if outside of 0 if dist < 1e-14: #TODO(pjm): include offset range for client res['x_range'][0] = 0 res['x_range'][1] = dist return res