[docs]classMetricsService:def__init__(self)->None:""" This object lists and calculates metrics that can be plotted in the Simularium Viewer. """self._create_metrics_registry()def_create_metrics_registry(self)->None:""" Get a dict mapping metric index (as per-session unique ID) to info about each available metric. """self.metrics_registry={}forindex,metric_infoinenumerate(metrics_list):self.metrics_registry[index]=metric_info
[docs]defmetric_info_for_id(self,metric_id:int)->MetricInfo:""" Get a MetricInfo for a given metric's session id. Raise an error if the metric_id is not found in the registry. Parameters ---------- metric_id: int The session ID for the requested metric. Returns ------- MetricInfo Info about the requested metric. """ifmetric_idnotinself.metrics_registry:raiseMetricNotFoundError(metric_id)returnself.metrics_registry[metric_id]
[docs]defavailable_metrics(self)->List[Dict[str,Any]]:""" Get the IDs and display names for the metrics that are compatible with the given type of data. Returns ------- List[Dict[str, Any]] A list of info about each available metric, including session ID, display name, metric type, and excluded axes. """result=[]foruid,metric_infoinself.metrics_registry.items():info=metric_info.to_dict()info["uid"]=uidresult.append(info)returnresult
[docs]defplot_data(self,traj_data:TrajectoryData,plots:List[PlotInfo])->str:""" Add plots with the given configuration. Parameters ---------- traj_data : TrajectoryData, A Simularium trajectory. plots: List[PlotInfo] A list of PlotInfo configuration for each plot. Returns ------- str A JSON string of the plot(s) in simularium format. """plot_dicts=self._plot_dicts(traj_data,plots)returnjson.dumps({"version":CURRENT_VERSION.PLOT_DATA,"data":plot_dicts,})
def_plot_dicts(self,traj_data:TrajectoryData,plots:List[PlotInfo])->List[Dict[str,Any]]:""" Calculate each plot and get a dict for each. """result=[]forplot_infoinplots:result.append(self._calculate_plot(traj_data,plot_info))returnresultdef_calculate_plot(self,traj_data:TrajectoryData,plot_info:PlotInfo)->Dict[str,Any]:""" Calculate a plot with the given configuration. """# get metric infox_metric_info=self.metric_info_for_id(plot_info.metric_id_x)y_metric_info=Noneifplot_info.metric_id_y>=0:y_metric_info=self.metric_info_for_id(plot_info.metric_id_y)# validate and setup titleplot_info.validate_plot_configuration(x_metric_info,y_metric_info)plot_info.set_display_title(x_metric_info,y_metric_info)# X axis metricx_calculator=x_metric_info.calculator()x_traces,x_units=x_calculator.calculate(traj_data)x_metric_title=x_metric_info.display_name# create and add plotsify_metric_infoisNone:# HISTOGRAMplot_data=HistogramPlotData(title=plot_info.display_title,xaxis_title=f"{x_metric_title}{x_units}",traces=x_traces,)returnHistogramPlotReader().read(plot_data)else:# SCATTER PLOT# only use the first trace for X axis since there can only be onex_trace=x_traces[list(x_traces.keys())[0]]# Y axis metricy_calculator=y_metric_info.calculator()y_traces,y_units=y_calculator.calculate(traj_data)y_metric_title=y_metric_info.display_name# create and add scatter plotplot_data=ScatterPlotData(title=plot_info.display_title,xaxis_title=f"{x_metric_title}{x_units}",yaxis_title=f"{y_metric_title}{y_units}",xtrace=x_trace,ytraces=y_traces,render_mode=plot_info.scatter_plot_mode.value,)returnScatterPlotReader().read(plot_data)