All notable changes to pycellin since version 0.5.1 are documented in this file. The format is based on Keep a Changelog.
Model merging and splitting, a lot of new properties, branch plots, and many fixes around time handling. This release contains breaking changes, listed first below.
- Properties:
pycellin.graph.propertiesmoved topycellin.properties. Thepycellin.graphpackage no longer exists - Properties: rename the
branch_*properties tocycle_*, along with theiradd_*()methods, factories and calculators:branch_total_displacement→cycle_total_displacementbranch_mean_displacement→cycle_mean_displacementbranch_mean_speed→cycle_mean_speed
- Properties: rename the
angleproperty toturning_angle(add_angle()→add_turning_angle()) - Properties: rename the
ROI_coordsnode property tocell_contour(TrackMate and CTC loaders, all exporters, sample GEFF data) - Properties:
cycle_durationvalues change: it is now the time elapsed between the first and last cells of the cycle, in the reference time unit. It was previously off by one frame and scaled by the time step a second time - Properties:
Propertysetters raiseTypeErrorinstead ofValueErrorwhen given a non-string value - Model: remove the
Model.recompute_property()andModel.export()stubs, which did nothing. Use thepycellin.export_*()functions - Plotting: rename
node_color_scaletonode_colormapinCellLineageandCycleLineageplot()andget_tree_figure() - CTC: the loader now uses a new
timeproperty as the reference time property, instead oftimepoint - trackpy: the loader now uses a new
timeproperty (frame × time step) as the reference time property, instead offrame, and renames the trackpy coordinatesx,y,ztocell_x,cell_y,cell_z - Exceptions: pycellin exceptions now subclass the matching built-in exception:
LineageStructureError(soFusionErrorandTimeFlowError) is aValueError,UpdateRequiredErroraRuntimeError,ProtectedPropertyErroranAttributeError - Logging: pycellin no longer adds a
NullHandlerto its logger, so warnings logged by pycellin are shown on stderr by default - Dependencies: matplotlib is no longer installed with pycellin: install it yourself if your code uses it. pycellin only needs it for the debug plots of the
RodWidthandRodLengthcalculators (debug=True)
- Model:
merge()to merge two models, andsplit()to split a model into several models from groups of lineage IDs- lineage ID collisions are resolved, and single-cell lineages keep the lineage ID = -cell ID convention
- critical metadata (reference time property, time step and unit, pixel size, space unit) must match; other differing metadata values are stored as lineage properties
- property declarations are checked for compatibility (property type, lineage type, unit, dtype)
- calculators that rely on external data (e.g. a label image) are not kept
- cycle data is handled when only one of the models has some
- Model:
rescale_time()andrescale_space()to convert time or space values into another unit (e.g. frames to minutes, pixels to µm) - Model:
remove_lineages() - Model:
relabel_cells()to give cells consecutive IDs, optionally unique across the whole model - Model:
remove_intercycle_links()to remove the outgoing links of division cells - Model:
get_cell_lineages_from_IDs()andget_cycle_lineages_from_IDs() - Model:
overwrite_lidargument toadd_lineage() - Model:
lineage_propsargument toto_cell_dataframe(),to_link_dataframe()andto_cycle_dataframe()to include lineage properties in the DataFrame - Metadata:
label_imgandlabel_img_pathstandard metadata fields - Metadata:
ModelMetadata.diff()to list the metadata fields that differ between two models - Properties:
Property.get_incompatibilities()to compare two property declarations - Properties:
pycellin.propertiesnow exposes the 13 core property factories (create_cell_id_property(),create_time_property(), ...), to declare properties when building a model from scratch or writing a loader - Properties:
timecore property with its calculator - Properties: morphology properties
cell_polygon(computed from a label image),cell_contour,cell_areaandcell_perimeter - Properties: morphology properties
cycle_mean_area,birth_areaanddivision_area - Properties: topology lineage properties
num_cells,num_cycles,num_divs,num_gapsandnum_leaves - Properties: topology lineage properties
lineage_cell_depth,lineage_cycle_depthandlineage_duration - Properties:
location_tag, a cell property read from a mask image.mask_path_metadata_fieldreads the mask path from the model metadata, and atag_namesdict maps pixel values to region names - Properties:
uses_external_data()class method on calculators - Exceptions:
MissingPropertyError(aKeyError), raised when a required property is missing from a node, an edge or the model - Lineages:
Lineage.get_depth(),CellLineage.get_gaps()andCellLineage.get_duration() - Plotting:
pycellin.stylingmodule with pycellin colors and two Plotly templates,pycellin_white(the new default) andpycellin_dark - Plotting:
Model.plot_mean_cell_prop_over_time()andModel.get_mean_cell_prop_over_time_fig()to plot the mean and std of a cell property over time - Plotting:
CellLineage.plot_branch_profile()andCellLineage.get_branch_profile_figure()to plot a cell property along one or several branches, with per-branch styling of markers and lines - Plotting:
CellLineage.get_branch_lineage()andCellLineage.get_branch_lineage_highlight()to extract or highlight the branch leading to a cell - Plotting: branch highlights in
CellLineage.plot()andget_tree_figure(), withtarget_cells,source_cells,generationsandhighlight_proparguments - Plotting: support for single-cell lineages
- Plotting:
node_colormapalso accepts a dict for discrete color maps - Plotting: nodes can be styled individually through
node_marker_style - TrackMate:
ref_time_propargument toload_TrackMate_XML() - TrackMate: default tracker in the exported XML, so the TrackMate wizard can be navigated back
- TrackMate: dimension mappings for the new properties
- trackpy:
computed_time_propargument toload_trackpy_dataframe() - Dependencies:
notebooksextra with what the example notebooks need: JupyterLab, ipykernel, and nbformat, without which Plotly can't show figures in notebooks. Install it withpip install "pycellin[notebooks]"
- Model: core properties (
cell_ID,lineage_ID,timepointand the reference time property) are protected whenever they are declared - Model: timepoint handling is centralized in the updater: the
timepointcalculator is always present and up to date - Model: enforce the single-cell lineage convention (lineage ID = -cell ID)
- Properties: data types are compared after normalizing their spelling (e.g.
floatandfloat64) - TrackMate: one-node lineages are identified by their size instead of by their lineage ID sign
- TrackMate: document that only numeric properties are exported
- GEFF: stricter coordinate arguments in
load_GEFF(): they must describe a complete 2D or 3D system, and inferred coordinates are each assigned at most once - Dependencies: declare numpy, pillow, tifffile and geff-spec, which pycellin imports directly but only got through other packages
- Dependencies: raise the minimum versions of pandas (2.2.2), scikit-image (0.24), shapely (2.0.4) and plotly (5.12) to the first ones that work with NumPy 2. The previous minimums allowed installs that failed at
import pycellin - Dependencies: the test dependencies moved from the
testextra to atestdependency group, installed from a clone of the repository withpip install -e . --group test(pip >= 25.1)
- Model: changing the time step with
set_time_step()corrupted thetimepointvalues - Model:
add_lineage()failed withwith_CycleLineage=Trueor with a lineage that had no lineage ID, and ignored itslidargument when given a lineage - Model:
add_lineage()silently replaced a lineage that already had the same ID. It now raisesValueError - Properties:
turning_angle(anglein 0.5.1) was recomputed for every lineage at each update, as its calculator was global instead of local - Properties:
turning_angle(anglein 0.5.1) was declared as an edge property although its values are on cells - TrackMate:
turning_angle(anglein 0.5.1) in degrees was exported as a TrackMate angle, which TrackMate reads as radians - GEFF: the exporter didn't write the metadata of properties with several types (
LINEAGE | NODE,LINEAGE | EDGE) - CTC: the loader gave cells no
timepoint, although it was the reference time property, and nolineage_ID. Reading the pixel size from label images (labels_path) failed - trackpy: the loader failed when given a
time_step, which it applied to frames, and gave cells nolineage_ID
- Tests: new tests for model merging and splitting, the new properties, plotting, exceptions and utils
- Docs: use the
pcalias consistently in the README and notebooks, update and re-run the notebooks - Packaging: find packages automatically in
pyproject.toml - Packaging: declare the license as an SPDX expression (
BSD-3-Clause) instead of the deprecated classifier. Building pycellin now needs setuptools >= 77 - Packaging: between releases, the version on
devends with.dev0(e.g.0.6.0.dev0), so models made with development code say so in theirpycellin_versionmetadata - CI: bump
actions/setup-pythonfrom 6 to 7 - CI: the deploy workflow stops before building if the release tag doesn't match the package version
- CI: fix releases starting the deploy workflow twice, which made one of the two runs fail at the PyPI upload
- fix typos, type hints, docstrings and formatting
- @marcelaxrivera made their first contribution in #50
Versions up to 0.5.1 are documented in the GitHub releases.