4.1. lib#
- class lmd.lib.Collection(calibration_points: ndarray | None = None, orientation_transform: ndarray | None = None)#
Class which is used for creating shape collections for the Leica LMD6 & 7. Contains a coordinate system defined by calibration points and a collection of various shapes.
- Parameters:
calibration_points – Calibration coordinates in the form of \((3, 2)\).
orientation_transform – defines transformations performed on the provided coordinate system prior to export as XML. Defaults to the identity matrix.
- calibration_points#
Calibration coordinates in the form of \((3, 2)\).
- Type:
Optional[np.ndarray]
- orientation_transform#
defines transformations performed on the provided coordinate system prior to export as XML. This orientation_transform is always applied to shapes when there is no individual orientation_transform provided.
- Type:
np.ndarray
- add_shape(shape: Shape)#
Add a new shape to the collection.
- Parameters:
shape – Shape which should be added.
- join(collection: Collection, update_orientation_transform: bool = True)#
Join the collection with the shapes of a different collection. The calibration markers of the current collection are kept. Please keep in mind that coordinate systems and calibration points must be compatible for correct joining of collections.
- Parameters:
collection – Collection which should be joined with the current collection object.
orientation_transform – If set to True, the orientation transform of the joined collection will be updated to the current collection. If set to False, the orientation transform of the joined collection will not be updated.
- Returns:
returns self
- load(file_location: str)#
Can be used to load a shape file from XML. Both, XMLs generated with py-lmd and the Leica software can be used. :param file_location: File path pointing to the XML file.
- load_geopandas(gdf: GeoDataFrame, geometry_column: str = 'geometry', name_column: str | None = None, well_column: str | None = None, calibration_points: ndarray | None = None, global_coordinates: int | None = None) None #
Create collection from a geopandas dataframe
- Parameters:
gdf (geopandas.GeoDataFrame) – Collection of shapes and optional metadata
(str (geometry_column) – geometry): Name of column storing Shapes as shapely.Polygon, defaults to geometry
default – geometry): Name of column storing Shapes as shapely.Polygon, defaults to geometry
well_column (str, optional) – Column storing of well id as additional metadata
calibration_points (np.ndarray, optional) – Calibration points of collection
global_coordinates (int, optional) – Number of global coordinates
Example:
from lmd.lib import Collection import geopandas as gpd import shapely gdf = gpd.GeoDataFrame( data={"well": ["A1"], "name": ["test"]}, geometry=[shapely.Polygon([[0, 0], [0, 1], [1, 0], [0, 0]])] ) # Create collection c = Collection() # Export well metadata c.load_geopandas(gdf, well_column="well") assert c.to_geopandas("well").equals(gdf) # Do not export well metadata c.load_geopandas(gdf) assert c.to_geopandas().equals(gdf.drop(columns="well"))
- new_shape(points: ndarray, well: str | None = None, name: str | None = None)#
Directly create a new Shape in the current collection.
- Parameters:
points – Array or list of lists in the shape of (N,2). Contains the points of the polygon forming a shape.
well – Well in which to sort the shape after cutting. For example A1, A2 or B3.
name – Name of the shape.
- plot(calibration: bool = True, mode: str = 'line', fig_size: tuple = (5, 5), apply_orientation_transform: bool = True, apply_scale: bool = False, save_name: str | None = None, return_fig: bool = False, **kwargs)#
This function can be used to plot all shapes of the corresponding shape collection.
- Parameters:
calibration – Controls wether the calibration points should be plotted as crosshairs. Deactivating the crosshairs will result in the size of the canvas adapting to the shapes. Can be especially usefull for small shapes or debugging.
fig_size – Defaults to \((10, 10)\) Controls the size of the matplotlib figure. See matplotlib documentation for more information.
apply_orientation_transform – Define wether the orientation transform should be applied before plotting.
(Optional[str] (save_name) – None): Specify a filename for saving the generated figure. By default None is provided which will not save a figure.
default – None): Specify a filename for saving the generated figure. By default None is provided which will not save a figure.
- save(file_location: str, encoding: str = 'utf-8')#
Can be used to save the shape collection as XML file.
file_location: File path pointing to the XML file.
- stats()#
Print statistics about the Collection in the form of:
===== Collection Stats ===== Number of shapes: 208 Number of vertices: 126,812 ============================ Mean vertices: 609.67 Min vertices: 220.00 5% percentile vertices: 380.20 Median vertices: 594.00 95% percentile vertices: 893.20 Max vertices: 1,300.00
- svg_to_lmd(file_location, offset=[0, 0], divisor=3, multiplier=60, rotation_matrix=array([[1., 0.], [0., 1.]]), orientation_transform=None)#
Can be used to save the shape collection as XML file.
- Parameters:
file_location – File path pointing to the SVG file.
orientation_transform – Will superseed the global transform of the Collection.
rotation_matrix
- to_geopandas(*attrs: str) GeoDataFrame #
Return geopandas dataframe of collection
- Parameters:
*attrs (str) – Optional attributes of the shapes in the collection to be added as metadata columns
- Returns:
Representation of all shapes and optional metadata
- Return type:
geopandas.GeoDataFrame
Example: .. code-block:: python
# Generate collection collection = pylmd.Collection() shape = pylmd.Shape(np.array([[ 0, 0], [ 0, -1], [ 1, 0], [ 0, 0]]), well=”A1”, name=”Shape_1”, orientation_transform=None) collection.add_shape(shape)
# Get geopandas object collection.to_geopandas() > geometry
0 POLYGON ((0 0, 0 -1, 1 0, 0 0))
collection.to_geopandas(“well”, “name”) > well name geometry
0 A1 Shape_1 POLYGON ((0 0, 0 -1, 1 0, 0 0))
- class lmd.lib.SegmentationLoader(config={}, verbose=False, processes=1)#
Select single cells from a segmentation and generate cutting data
- Args:
config (dict): Dict containing configuration parameters. See Note for further explanation. processes (int): Number of processes used for parallel processing of cell sets. Total processes can be calculated as processes * threads. threads (int): Number of threads used for parallel processing of shapes within a cell set. Total processes can be calculated as processes * threads.
cell_sets (list(dict)): List of dictionaries containing the sets of cells which should be sorted into a single well.
calibration_marker (np.array): Array of size ‘(3,2)’ containing the calibration marker coordinates in the ‘(row, column)’ format.
coords_lookup (None, dict): precalculated lookup table for coordinates of individual cell ids. If not provided will be calculated.
classes (np.array): Array of classes found in the provided segmentation mask. If not provided will be calculated based on the assumption that cell_ids are assigned in ascending order.
Example:
import numpy as np from PIL import Image from lmd.lib import SegmentationLoader
- Parameters:
config (dict) – Dict containing configuration parameters. See Note for further explanation.
cell_sets (list(dict)) – List of dictionaries containing the sets of cells which should be sorted into a single well.
calibration_marker (np.array) – Array of size ‘(3,2)’ containing the calibration marker coordinates in the ‘(row, column)’ format.
Example
import numpy as np from PIL import Image from lmd.lib import SegmentationLoader im = Image.open('segmentation_cytosol.tiff') segmentation = np.array(im).astype(np.uint32) all_classes = np.unique(segmentation) cell_sets = [{"classes": all_classes, "well": "A1"}] calibration_points = np.array([[0,0],[0,1000],[1000,1000]]) loader_config = { 'orientation_transform': np.array([[0, -1],[1, 0]]) } sl = SegmentationLoader(config = loader_config) shape_collection = sl(segmentation, cell_sets, calibration_points) shape_collection.plot(fig_size = (10, 10))
Note
Basic explanation of the parameters in the config dict:
# dilation of the cutting mask in pixel before intersecting shapes in a selection group are merged shape_dilation: 0 # erosion of the cutting mask in pixel before intersecting shapes in a selection group are merged shape_erosion: 0 # Cutting masks are transformed by binary dilation and erosion binary_smoothing: 3 # number of datapoints which are averaged for smoothing # the resoltion of datapoints is twice as high as the resolution of pixel convolution_smoothing: 15 # strength of coordinate reduction through the Ramer-Douglas-Peucker algorithm 0 is small 1 is very high rdp_epsilon: 0.1 # Optimization of the cutting path inbetween shapes # optimized paths improve the cutting time and the microscopes focus # valid options are ["none", "hilbert", "greedy"] path_optimization: "hilbert" # Paramter required for hilbert curve based path optimization. # Defines the order of the hilbert curve used, which needs to be tuned with the total cutting area. # For areas of 1 x 1 mm we recommend at least p = 4, for whole slides we recommend p = 7. hilbert_p: 7 # Parameter required for greedy path optimization. # Instead of a global distance matrix, the k nearest neighbours are approximated. # The optimization problem is then greedily solved for the known set of nearest neighbours until the first set of neighbours is exhausted. # Established edges are then removed and the nearest neighbour approximation is recursivly repeated. greedy_k: 20 # Overlapping shapes are merged based on a nearest neighbour heuristic. # All selected shapes closer than distance_heuristic pixel are checked for overlap. distance_heuristic: 300
- DEFAULT_SEGMENTATION_DTYPE#
alias of
uint64
- check_cell_set_sanity(cell_set)#
Check if cell_set dictionary contains the right keys
- load_classes(cell_set)#
Identify cell class definition and load classes
Identify if cell classes are provided as list of integers or as path pointing to a csv file. Depending on the type of the cell set, the classes are loaded and returned for selection.
- class lmd.lib.Shape(points: ndarray = array([[0., 1.]]), well: str | None = None, name: str | None = None, orientation_transform=None)#
Class for creating a single shape object.
- from_xml(root)#
Load a shape from an XML shape node. Used internally for reading LMD generated XML files.
- Parameters:
root – XML input node.
- to_xml(id: int, orientation_transform: ndarray, scale: int)#
Generate XML shape node needed internally for export.
- Parameters:
id – Sequential identifier of the shape as used in the LMD XML format.
orientation_transform (np.array) – Pass orientation_transform which is used if no local orientation transform is set.
scale (int) – Scalling factor used to enable higher decimal precision.
Note
If the Shape has a custom orientation_transform defined, the custom orientation_transform is applied at this point. If not, the oritenation_transform passed by the parent Collection is used. This highlights an important difference between the Shape and Collection class. The Collection will always has an orientation transform defined and will use np.eye(2) by default. The Shape object can have a orientation_transform but can also be set to None to use the Collection value.