diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c320dd..fe7e062 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- **:warning: `use_whole_cell_only` now defaults to `true`.** Nuclei are no + longer segmented or measured unless `--use_whole_cell_only false` is set. + Runs that relied on nuclear masks or nuclear measurements must set it + explicitly. + +- The **Mask smoothing options** and **Cellpose preprocessing options** + parameters are hidden in the Seqera Platform launch form and in `--help`. + They are shown with `--show_hidden` and can still be set on the command line + or in a params file. Their defaults are unchanged. + ## v0.5.0 - 2026-09-07 ### Changed diff --git a/docs/usage.md b/docs/usage.md index 80679e9..0ffe878 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -122,9 +122,9 @@ You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-c ### Cell processing parameters -| Parameter Name | Description | -| ------------------- | ---------------------------------------------------------------------------------- | -| use_whole_cell_only | Use only the whole-cell segmentation to process cells (skip nuclear segmentation). | +| Parameter Name | Description | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| use_whole_cell_only | Use only the whole-cell segmentation to process cells (skip nuclear segmentation). Default: `true`. Set to `false` to also segment and measure nuclei. | ### Combine channel parameters @@ -304,7 +304,7 @@ were trained on: | `equalize_adapthist(clip_limit, kernel)` | sopa | **off** (`0`) | | percentile (1, 99) rescale | Cellpose | on (unchanged) | -These four parameters form the **Cellpose preprocessing options** group: +These four parameters form the **Cellpose preprocessing options** group. They are hidden in the Seqera Platform launch form and in `--help` (shown with `--show_hidden`). They can still be set on the command line or in a params file: | Parameter Name | Default | Description | | ---------------------------- | ------- | -------------------------------------------------------------------------------------- | @@ -725,6 +725,8 @@ Two things to watch: ### Mask smoothing options +These parameters are hidden in the Seqera Platform launch form and in `--help` (shown with `--show_hidden`). They can still be set on the command line or in a params file. + | Parameter Name | Description | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | smooth_masks | Enable mask smoothing before cell measurement to reduce polygon complexity (default: `false`). Prevents StackOverflowError in QuPath's GeoJSON export for images with complex cell boundaries. | diff --git a/modules/local/cellmeasurement/tests/main.nf.test b/modules/local/cellmeasurement/tests/main.nf.test index d71a7a6..81484d0 100644 --- a/modules/local/cellmeasurement/tests/main.nf.test +++ b/modules/local/cellmeasurement/tests/main.nf.test @@ -11,6 +11,9 @@ nextflow_process { test("cellmeasurement - basic functionality") { when { + params { + use_whole_cell_only = false + } process { """ input[0] = [ diff --git a/nextflow.config b/nextflow.config index 8313a8a..100459c 100644 --- a/nextflow.config +++ b/nextflow.config @@ -30,7 +30,7 @@ params { remove_markers = 'TRITC,Cy5' // cell processing options - use_whole_cell_only = false + use_whole_cell_only = true // combine channels options combine_method = 'max' diff --git a/nextflow_schema.json b/nextflow_schema.json index 588ec19..9517cd8 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -59,9 +59,10 @@ "properties": { "use_whole_cell_only": { "type": "boolean", + "default": true, "description": "Use only the whole-cell segmentation to process cells (skip nuclear segmentation).", "fa_icon": "fas fa-stopwatch", - "help_text": "Set this to `true` to use only the whole-cell segmentation to process cells. This will skip segmentation of nuclei and associated measurements but retains cell, erosion, and expansion measurements." + "help_text": "Defaults to `true`: only the whole-cell segmentation is used to process cells. Nuclei are not segmented and nuclear measurements are not produced; cell, erosion, and expansion measurements are kept. Set to `false` to also segment nuclei and measure them." } } }, @@ -164,6 +165,7 @@ "properties": { "cellpose_tile_norm_blocksize": { "type": "integer", + "hidden": true, "minimum": 0, "description": "Block size in pixels for Cellpose's tile-local intensity normalisation. 0 uses Cellpose's whole-patch default.", "help_text": "Segmentation always runs on patches, and normalisation is computed from the patch, so without this a cell's segmentation depends on what else landed in its patch and changing `--patch_width_pixel` changes results. Patch overlap does not help: it resolves cells straddling a boundary, not differing normalisation.\n\nThis is forwarded as `--method-kwargs '{\"normalize\": {\"tile_norm_blocksize\": N, \"percentile\": [1.0, 99.0]}}'`, which sopa passes into `model.eval`, making the percentile statistics local to each block rather than global to the patch.\n\nChoose a block that comfortably contains many nuclei. At COMET's 0.28 um/px with `--cellpose_diameter 30` (8.4 um cells), 512 px is 143 um, about 17 nuclear diameters. Small blocks are actively harmful: a 128 px (36 um) block spans roughly 4 cell diameters, so in sparse tissue it can contain no nuclei at all and its noise is stretched to the full range. Cellpose only guards a flat block when its 1-99 percentile range falls below 1e-3, which such blocks exceed.\n\nNote this does not normalise across the whole image -- nothing in the patch-parallel design ever sees it.", @@ -171,6 +173,7 @@ }, "cellpose_clip_limit": { "type": "number", + "hidden": true, "minimum": 0, "description": "sopa's CLAHE clip limit, applied before Cellpose. Defaults to 0 in this pipeline, disabling CLAHE; null restores sopa's default of 0.2.", "help_text": "sopa runs `skimage.exposure.equalize_adapthist` on each patch before Cellpose sees it. This is sopa's addition, not part of Cellpose -- Cellpose contains no CLAHE code, and its released weights were trained on percentile-normalised input, so this preprocessing is off that contract.\n\nSetting 0 disables CLAHE. Worth testing: CLAHE is the largest single source of patch-dependence in this stack, and on an all-zero patch it expands the image to the full range, which defeats Cellpose's own empty-patch guard.", @@ -178,6 +181,7 @@ }, "cellpose_clahe_kernel_size": { "type": "integer", + "hidden": true, "minimum": 1, "description": "Kernel size in pixels for sopa's CLAHE. Unset uses skimage's default of patch.shape // 8, which scales with patch_width_pixel.", "help_text": "Left unset, skimage derives the kernel from the patch: 1/8 of its height and width. The contrast-enhancement length scale therefore moves with `--patch_width_pixel` -- 187 px (52 um) at 1500, 375 px (105 um) at 3000, 750 px (210 um) at 6000 -- so the same tissue is enhanced differently purely because of a patching knob.\n\nPinning an absolute value removes that coupling. cellSAM, which also CLAHEs each block, fixes its kernel at 128 px rather than deriving it from the block size.\n\nHas no effect while `--cellpose_clip_limit` is 0.", @@ -185,6 +189,7 @@ }, "cellpose_gaussian_sigma": { "type": "number", + "hidden": true, "minimum": 0, "description": "Sigma for sopa's gaussian smoothing, applied before Cellpose. Defaults to 0 in this pipeline, disabling it; null restores sopa's default of 1.", "help_text": "Like CLAHE, this is sopa's addition rather than Cellpose's: Cellpose's own smoothing and sharpening parameters (`smooth_radius`, `sharpen_radius`) both default to 0, and it applies neither unless asked.\n\nUnlike CLAHE this is not a source of patch dependence, since a small-sigma convolution is local and only edge reflection differs between patch layouts. Disabling it is therefore about matching Cellpose's preprocessing contract, not about stability. Raise it if your data is noisy enough to need denoising before segmentation.", @@ -556,12 +561,14 @@ "properties": { "smooth_masks": { "type": "boolean", + "hidden": true, "description": "Enable mask smoothing before cell measurement.", "fa_icon": "fas fa-wave-square", "help_text": "When enabled, segmentation masks are smoothed to reduce polygon complexity before being passed to cellmeasurement. Choose the method with smooth_method." }, "smooth_method": { "type": "string", + "hidden": true, "default": "morphological", "description": "Smoothing algorithm: 'morphological' (disk close+open) or 'shapely' (Douglas-Peucker polygon simplification).", "fa_icon": "fas fa-cogs", @@ -570,6 +577,7 @@ }, "smooth_kernel_size": { "type": "integer", + "hidden": true, "default": 2, "minimum": 1, "maximum": 10, @@ -579,6 +587,7 @@ }, "smooth_n_workers": { "type": "integer", + "hidden": true, "default": 8, "minimum": 1, "maximum": 64, @@ -588,6 +597,7 @@ }, "smooth_chunksize": { "type": "integer", + "hidden": true, "default": 200, "minimum": 1, "maximum": 10000, @@ -597,6 +607,7 @@ }, "smooth_tolerance": { "type": "number", + "hidden": true, "default": 1, "minimum": 0.01, "description": "[shapely] Douglas-Peucker simplification tolerance in pixels.", @@ -605,6 +616,7 @@ }, "smooth_min_area": { "type": "number", + "hidden": true, "default": 0, "minimum": 0, "description": "[shapely] Minimum polygon area in pixels\u00b2 to retain after simplification.",