"""Compute subpixel bias in localization data.Subpixel bias in localization coordinates may arise depending on thelocalization algorithm [1]_.References----------.. [1] Gould, T. J., Verkhusha, V. V. & Hess, S. T., Imaging biological structures with fluorescence photoactivation localization microscopy. Nat. Protoc. 4 (2009), 291–308."""from__future__importannotationsimportloggingimportsysfromcollections.abcimportSequencefromtypingimportTYPE_CHECKING,Any,castifsys.version_info>=(3,11):fromtypingimportSelfelse:fromtyping_extensionsimportSelfifTYPE_CHECKING:importmatplotlibasmplfromlocan.data.locdataimportLocDataimportmatplotlib.pyplotaspltimportnumpyasnpimportpandasaspdfromlocan.analysisimportmetadata_analysis_pb2fromlocan.analysis.analysis_baseimport_Analysis__all__:list[str]=["SubpixelBias"]logger=logging.getLogger(__name__)# The algorithmsdef_subpixel_bias(locdata:LocData,pixel_size:int|float|Sequence[int|float])->pd.DataFrame:coordinate_labels=locdata.coordinate_keyscoordinates=locdata.coordinates.Tifnp.ndim(pixel_size)==0:pixel_size=cast("int | float",pixel_size)pixel_sizes:Sequence[int|float]=[pixel_size]*len(coordinate_labels)else:pixel_size=cast("Sequence[int | float]",pixel_size)iflen(pixel_size)!=len(coordinate_labels):raiseTypeError("There must be given a pixel_size for each coordinate.")else:pixel_sizes=pixel_sizecoordinates_modulo=[np.remainder(coordinates_,pixel_size_)forcoordinates_,pixel_size_inzip(coordinates,pixel_sizes)]results={label_+"_modulo":values_forlabel_,values_inzip(coordinate_labels,coordinates_modulo)}returnpd.DataFrame(results)# The specific analysis classes
[docs]classSubpixelBias(_Analysis):""" Check for subpixel bias by computing the modulo of localization coordinates for each localization's spatial coordinate in locdata. Parameters ---------- meta : locan.analysis.metadata_analysis_pb2.AMetadata | None Metadata about the current analysis routine. pixel_size : int | float | Sequence[int | float] Camera pixel size in coordinate units. Attributes ---------- count : int A counter for counting instantiations. parameter : dict A dictionary with all settings for the current computation. meta : locan.analysis.metadata_analysis_pb2.AMetadata Metadata about the current analysis routine. results : pandas.DataFrame A dataframe with localization coordinates. """count=0def__init__(self,meta:metadata_analysis_pb2.AMetadata|None=None,pixel_size:int|float|Sequence[int|float]|None=None,)->None:parameters=self._get_parameters(locals())super().__init__(**parameters)self.results=None
[docs]defcompute(self,locdata:LocData)->Self:""" Run the computation. Parameters ---------- locdata Localization data. Returns ------- Self """ifnotlen(locdata):logger.warning("Locdata is empty.")returnselfself.results=_subpixel_bias(locdata=locdata,**self.parameter)returnself
[docs]defhist(self,ax:mpl.axes.Axes|None=None,bins:int|Sequence[int|float]|str="auto",log:bool=True,**kwargs:Any,)->mpl.axes.Axes:""" Provide histogram as :class:`matplotlib.axes.Axes` object showing hist(results). Nan entries are ignored. Parameters ---------- ax The axes on which to show the image bins Bin specifications (passed to :func:`matplotlib.hist`). log Flag for plotting on a log scale. kwargs Other parameters passed to :func:`matplotlib.pyplot.hist`. Returns ------- matplotlib.axes.Axes Axes object with the plot. """ifaxisNone:ax=plt.gca()ifself.resultsisNone:returnaxax.hist(self.results.dropna(axis=0).to_numpy(),bins=bins,**dict(dict(density=True,log=log),**kwargs),histtype="step",label=self.results.columns,)ax.set(title="Subpixel Bias",xlabel="position_modulo_pixel_size",ylabel="PDF",)returnax