From dc53eada4a4271462669bf82cfa0d88194b2b130 Mon Sep 17 00:00:00 2001 From: Sebastian Gonzalez Tirado Date: Thu, 20 Oct 2022 13:29:18 +0200 Subject: [PATCH 01/18] Add python script files to format and decode data. Create nextflow script --- starfish/bin/decoding.py | 73 +++++++++++++++++++++ starfish/bin/format_to_spacetx.py | 56 ++++++++++++++++ starfish/nf-issdecoder.nf | 105 ++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 starfish/bin/decoding.py create mode 100644 starfish/bin/format_to_spacetx.py create mode 100755 starfish/nf-issdecoder.nf diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py new file mode 100644 index 00000000..71bd7084 --- /dev/null +++ b/starfish/bin/decoding.py @@ -0,0 +1,73 @@ +import os +import numpy as np +import starfish +from skimage.io import imread +import napari + +from starfish.image import ApplyTransform, LearnTransform, Filter +from starfish.types import Axes +from starfish import data, FieldOfView +from starfish.spots import FindSpots, DecodeSpots, AssignTargets +from starfish.util.plot import imshow_plane + +# Load minimal example from starfish: +#experiment = data.ISS(use_test_data=False) +#fov = experiment.fov() +#imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) +#dots = fov.get_image("dots") + +def iss_pipeline(fov, codebook): + #fov = experiment.fov() + primary_image = fov.get_image(FieldOfView.PRIMARY_IMAGES) + anchor = primary_image.sel({Axes.ROUND: 0}) + anchor_dots = anchor.reduce({Axes.CH, Axes.ZPLANE}, func="max") + + learn_translation = LearnTransform.Translation(reference_stack=anchor_dots, + axes=Axes.ROUND, upsampling=100) + + transforms_list = learn_translation.run( + primary_image.reduce({Axes.CH, Axes.ZPLANE}, func="max")) + + warp = ApplyTransform.Warp() + registered = warp.run(primary_image, transforms_list=transforms_list, in_place=False, verbose=True) + + # Filter raw data + masking_radius = 15 + filt = Filter.WhiteTophat(masking_radius, is_volume=False) + filtered = filt.run(registered, verbose=True, in_place=False) + print(filtered) + + bd = FindSpots.BlobDetector( + min_sigma=1, + max_sigma=3, + num_sigma=30, + threshold=0.01, + measurement_type='mean' + ) + + # Check if experiment has anchor or not + # Locate spots in a reference image: + # Old one: spots = bd.run(reference_image=fov.get_image("anchor_dots"), image_stack=filtered) + spots = bd.run(reference_image=anchor_dots, image_stack=filtered) + + # decode the pixel traces using the codebook + decoder = DecodeSpots.PerRoundMaxChannel(codebook=codebook) + decoded = decoder.run(spots=spots) + + return decoded +#imshow_plane(dots) + +# process all the fields of view: +def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): + decoded_intensities = {} + for i, (name_, fov) in enumerate(experiment.items()): + print(name_) + decoded = iss_pipeline(fov, codebook=cb) + decoded_intensities[name_] = decoded + + return decoded_intensities + +#process_experiment(starfish.Experiment.from_json('/Volumes/exchange/SebastianGonzalez/iss_testing/2bCartana_08_Test/SpaceTx/primary/experiment.json')) + +#viewer = napari.Viewer() +#viewer.add_layer diff --git a/starfish/bin/format_to_spacetx.py b/starfish/bin/format_to_spacetx.py new file mode 100644 index 00000000..54a5c4e1 --- /dev/null +++ b/starfish/bin/format_to_spacetx.py @@ -0,0 +1,56 @@ +from slicedimage import ImageFormat +from starfish.experiment.builder import format_structured_dataset +import argparse +import os + +# -------------------------------------------------- +def get_args(): + """Get command-line arguments""" + + parser = argparse.ArgumentParser( + description='Input/output directories for data formatting', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('-i', + '--input_dir', + default='Tiled', + type=str, + help='Input root directory') + + parser.add_argument('-o', + '--output_dir', + default='SpaceTx', + type=str, + help='Output root directory') + + return parser.parse_args() + +#-------------------------------------------------- +def format_structured_experiment( + in_dir: str = 'Tiled', + out_dir: str = 'SpaceTx', + subdirs: list = ['primary', 'nuclei', 'anchor_dots', 'anchor_nuclei'], + coordinates_filename: str = 'coordinates.csv' +): + for subdir in subdirs: + in_d = os.path.join(in_dir, subdir) + out_d = os.path.join(out_dir, subdir) + os.makedirs(out_d) + + format_structured_dataset( + in_d, + os.path.join(in_d, "coordinates.csv"), + out_d, + ImageFormat.TIFF, + ) + +#-------------------------------------------------- +def main(): + args = get_args() + format_structured_dataset( + in_dir = args.input_dir, + out_dir = args.output_dir + ) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/starfish/nf-issdecoder.nf b/starfish/nf-issdecoder.nf new file mode 100755 index 00000000..5c9627c7 --- /dev/null +++ b/starfish/nf-issdecoder.nf @@ -0,0 +1,105 @@ +/* + * pipeline input parameters +*/ +// params.datadir = "$projectDir/data/input/" +params.input_dir = "$projectDir" +params.register_dir = "/Registered" +params.codebook = "$projectDir/data/codebook.json" +// params.output = "$projectDir/data/output" +// params.script_Python_Registration = './code/python/registration.py' +log.info """\ + SPATIAL TRANSCRIPTOMICS PIPELINE + ================================ + test : ${params.test} +// input datadir: ${params.datadir} +// sample name : ${params.sample_name} +// outdir : ${params.output} +// project dir : ${projectDir} + """ + .stripIndent() + +// nextflow.enable.dsl=2 + +process image_registration { + publishDir "$params.output", mode: 'copy', overwrite: true + + input: + val x +// val y +// path y +// path x +// val datadir_in +// val sample_in + + output: +// stdout + path 'Registered' + + script: + """ + python $projectDir/bin/python_draft.py -t ${x} -o 'Registered' + """ +} + + +process TILING_TEST { + + input: +// path prev_img + + output: + path 'Tiled' +// path '*_results' + + script: + """ + python $projectDir/bin/to_spacetx_print_results.py + """ +} + +process TILING { + + input: + path x + + output: + path Tiled +// path '*_results' + + script: + """ + python $projectDir/bin/tiling_test.py -s data -d $projectDir -p ${x} + """ +} + +process TO_SPACETX { + + input: + path x + + output: +// path 'SpaceTx' +// path 'data_results' + + script: + """ + python $projectDir/bin/to_spacetx.py -i $projectDir -c ${x} + """ +} + + +workflow { + tiling_ch = TILING(params.register_dir) + tiling_ch.view() +// tiling_ch.view() +// result_spacetx = TO_SPACETX(params.codebook) +// final_process = RESULT(result_spacetx.out) +// result_spacetx.view{} +// result_ch = image_registration(params.test) +// result_ch.view() +// test_name = Channel.from(params.test) +// sample_in = Channel.from(params.sample_name) +// script_file = Channel.fromPath(params.script_Python_Registration) +// last_channel = Channel.from(image_registration(test_name)) +// TILING(result_ch) +} From f2468a705c8054a675617f701ec21de675f17042 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 14:36:13 +0200 Subject: [PATCH 02/18] Added code to defaults and added iss_decoding.nf to modules --- config/defaults.yml | 7 ++++ modules/iss_decoding.nf | 82 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 modules/iss_decoding.nf diff --git a/config/defaults.yml b/config/defaults.yml index 778c7bd6..2255d815 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -9,12 +9,14 @@ workflow: segmentation: unmicst segmentation-recyze: false downstream: scimap + iss_decoding: false options: ashlar: -m 30 cypository: --model zeisscyto ilastik: --num_channels 1 mcquant: --masks cell*.tif naivestates: -p png + starfish: --tile-size 2000 modules: illumination: name: basic @@ -114,3 +116,8 @@ modules: name: autominerva container: labsyspharm/auto-minerva version: '2022-06-06' + iss_decoding: + name: starfish + container: spacetx/starfish + version: 0.2.2 + diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf new file mode 100644 index 00000000..4b68240d --- /dev/null +++ b/modules/iss_decoding.nf @@ -0,0 +1,82 @@ +// Import utility functions from lib/mcmicro/*.groovy +import mcmicro.* + +// Process name will appear in the the nextflow execution log +// While not strictly required, it's a good idea to make the +// process name match your tool name to avoid user confusion +process tiling { + + // Use the container specification from the parameter file + // No change to this line is required + container "${params.contPfx}${module.container}:${module.version}" + + // Specify the project subdirectory for writing the outputs to + // The pattern: specification must match the output: files below + // TODO: replace report with the desired output directory + // TODO: replace the pattern to match the output: clause below + publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.tif" + + // Stores .command.sh and .command.log from the work directory + // to the project provenance + // No change to this line is required + publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', + pattern: '.command.{sh,log}', + saveAs: {fn -> fn.replace('.command', "${module.name}-${task.index}")} + + // Inputs for the process + // mcp - MCMICRO parameters (workflow, options, etc.) + // module - module specifications (name, container, options, etc.) + // img/sft - pairs of images and their matching spatial feature tables + input: + val mcp + val module + tuple path(img), path(sft) + + // Process outputs that should be captured and + // a) returned as results + // b) published to the project directory + // TODO: replace *.html with the pattern of the tool output files + output: + path("*.html"), emit: results + + // Provenance files -- no change is needed here + tuple path('.command.sh'), path('.command.log') + + // Specifies whether to run the process + // Here, we simply take the flag from the workflow parameters + // TODO: change snr to match the true/false workflow parameter in defaults.yml + when: mcp.workflow["report"] + + // The command to be executed inside the tool container + // The command must write all outputs to the current working directory (.) + // Opts.moduleOpts() will identify and return the appropriate module options + """ + python /app/mytool.py --image $img --features $sft ${Opts.moduleOpts(module, mcp)} + """ +} + +workflow report { + + // Inputs: + // mcp - MCMICRO parameters (workflow, options, etc.) + // imgs - images + // sfts - spatial feature tables + take: + mcp + imgs + sfts + + main: + + // Match images against feature tables + id_imgs = imgs.map{ it -> tuple(Util.getImageID(it), it) } + id_sfts = sfts.map{ it -> tuple(Util.getFileID(it, '--'), it) } + + // Apply the process to each (image, sft) pair + id_imgs.combine(id_sfts, by:0) + .map{ tag, img, sft -> tuple(img, sft) } | snr + + // Return the outputs produced by the tool + emit: + snr.out.results +} \ No newline at end of file From 7dbbde785ac71bd697a273216a1a6dd5e6162748 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 15:05:17 +0200 Subject: [PATCH 03/18] Added include statements for iss_decoding --- main.nf | 4 ++++ modules/iss_decoding.nf | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/main.nf b/main.nf index db48221a..b6211b9b 100755 --- a/main.nf +++ b/main.nf @@ -98,6 +98,7 @@ include {illumination} from "$projectDir/modules/illumination" include {registration} from "$projectDir/modules/registration" include {dearray} from "$projectDir/modules/dearray" include {segmentation} from "$projectDir/modules/segmentation" +include {iss_decoding} from "$projectDir/modules/iss_decoding" include {quantification} from "$projectDir/modules/quantification" include {downstream} from "$projectDir/modules/downstream" include {viz} from "$projectDir/modules/viz" @@ -124,6 +125,9 @@ workflow { tmacores = dearray.out.cores.mix(pre_cores) tmamasks = dearray.out.masks.mix(pre_masks) + // Is the data type ISS? + tiling(mcp, ) + // Reconcile WSI and TMA processing for downstream segmentation allimg = img.wsi.mix(tmacores) segmentation(mcp, allimg, tmamasks, pre_pmap) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index 4b68240d..f2906aad 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -30,14 +30,14 @@ process tiling { input: val mcp val module - tuple path(img), path(sft) + tuple path(registration) // Process outputs that should be captured and // a) returned as results // b) published to the project directory // TODO: replace *.html with the pattern of the tool output files output: - path("*.html"), emit: results + path("*.json"), emit: results // Provenance files -- no change is needed here tuple path('.command.sh'), path('.command.log') @@ -55,16 +55,16 @@ process tiling { """ } -workflow report { +workflow run_starfish { // Inputs: // mcp - MCMICRO parameters (workflow, options, etc.) // imgs - images - // sfts - spatial feature tables + // cbk - Codebook take: mcp - imgs - sfts + img + cbk main: From cdc986dd6889ffd1129622528211c2bfbe580d17 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 16:27:52 +0200 Subject: [PATCH 04/18] Updated iss_decoding.nf and main --- main.nf | 2 +- modules/iss_decoding.nf | 11 +++-------- starfish/bin/decoding.py | 7 ++++--- starfish/test_iss_decoding.yml | 4 ++++ 4 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 starfish/test_iss_decoding.yml diff --git a/main.nf b/main.nf index b6211b9b..d3bc4571 100755 --- a/main.nf +++ b/main.nf @@ -126,7 +126,7 @@ workflow { tmamasks = dearray.out.masks.mix(pre_masks) // Is the data type ISS? - tiling(mcp, ) + run_starfish(mcp) // Reconcile WSI and TMA processing for downstream segmentation allimg = img.wsi.mix(tmacores) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index f2906aad..b87b75ef 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -30,7 +30,6 @@ process tiling { input: val mcp val module - tuple path(registration) // Process outputs that should be captured and // a) returned as results @@ -45,13 +44,13 @@ process tiling { // Specifies whether to run the process // Here, we simply take the flag from the workflow parameters // TODO: change snr to match the true/false workflow parameter in defaults.yml - when: mcp.workflow["report"] + when: mcp.workflow["iss_decoding"] // The command to be executed inside the tool container // The command must write all outputs to the current working directory (.) // Opts.moduleOpts() will identify and return the appropriate module options """ - python /app/mytool.py --image $img --features $sft ${Opts.moduleOpts(module, mcp)} + python $projectDir/starfish/bin/decoding.py ${Opts.moduleOpts(module, mcp)} """ } @@ -63,18 +62,14 @@ workflow run_starfish { // cbk - Codebook take: mcp - img - cbk main: // Match images against feature tables id_imgs = imgs.map{ it -> tuple(Util.getImageID(it), it) } - id_sfts = sfts.map{ it -> tuple(Util.getFileID(it, '--'), it) } // Apply the process to each (image, sft) pair - id_imgs.combine(id_sfts, by:0) - .map{ tag, img, sft -> tuple(img, sft) } | snr + tiling(mcp,mcp.modules) // Return the outputs produced by the tool emit: diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 71bd7084..b0c332d0 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -2,7 +2,7 @@ import numpy as np import starfish from skimage.io import imread -import napari +#import napari from starfish.image import ApplyTransform, LearnTransform, Filter from starfish.types import Axes @@ -67,7 +67,8 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities -#process_experiment(starfish.Experiment.from_json('/Volumes/exchange/SebastianGonzalez/iss_testing/2bCartana_08_Test/SpaceTx/primary/experiment.json')) - +experiment = data.ISS(use_test_data=False) +test = process_experiment(experiment, experiment.codebook) +print(test) #viewer = napari.Viewer() #viewer.add_layer diff --git a/starfish/test_iss_decoding.yml b/starfish/test_iss_decoding.yml new file mode 100644 index 00000000..eb2289e1 --- /dev/null +++ b/starfish/test_iss_decoding.yml @@ -0,0 +1,4 @@ +workflow: + start-at: iss_decoding + stop-at: iss_decoding + iss_decoding: true \ No newline at end of file From cd480ce6c1b52981ce13e0078cd06b6a86018f58 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 17:05:10 +0200 Subject: [PATCH 05/18] First hopefully functioning decoding test --- config/defaults.yml | 3 +-- config/schema.yml | 1 + main.nf | 2 +- modules/iss_decoding.nf | 15 +++++++-------- starfish/test_iss_decoding.yml | 11 ++++++++--- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/config/defaults.yml b/config/defaults.yml index 2255d815..61ebdf7d 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -119,5 +119,4 @@ modules: iss_decoding: name: starfish container: spacetx/starfish - version: 0.2.2 - + version: 0.2.2 \ No newline at end of file diff --git a/config/schema.yml b/config/schema.yml index afed0c3d..9f4f88a7 100644 --- a/config/schema.yml +++ b/config/schema.yml @@ -13,6 +13,7 @@ workflow: - downstream - ilastik-model - mesmer-model + - iss_decoding deprecated: quantification-mask: "--quant-opts '--masks ...'" illum: --start-at illumination diff --git a/main.nf b/main.nf index d3bc4571..509066ff 100755 --- a/main.nf +++ b/main.nf @@ -98,7 +98,7 @@ include {illumination} from "$projectDir/modules/illumination" include {registration} from "$projectDir/modules/registration" include {dearray} from "$projectDir/modules/dearray" include {segmentation} from "$projectDir/modules/segmentation" -include {iss_decoding} from "$projectDir/modules/iss_decoding" +include {run_starfish} from "$projectDir/modules/iss_decoding" include {quantification} from "$projectDir/modules/quantification" include {downstream} from "$projectDir/modules/downstream" include {viz} from "$projectDir/modules/viz" diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index b87b75ef..7133feb7 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -4,12 +4,12 @@ import mcmicro.* // Process name will appear in the the nextflow execution log // While not strictly required, it's a good idea to make the // process name match your tool name to avoid user confusion -process tiling { +process starfish { // Use the container specification from the parameter file // No change to this line is required container "${params.contPfx}${module.container}:${module.version}" - + // Specify the project subdirectory for writing the outputs to // The pattern: specification must match the output: files below // TODO: replace report with the desired output directory @@ -30,6 +30,7 @@ process tiling { input: val mcp val module + path code // Process outputs that should be captured and // a) returned as results @@ -50,7 +51,7 @@ process tiling { // The command must write all outputs to the current working directory (.) // Opts.moduleOpts() will identify and return the appropriate module options """ - python $projectDir/starfish/bin/decoding.py ${Opts.moduleOpts(module, mcp)} + python $code ${Opts.moduleOpts(module, mcp)} """ } @@ -65,13 +66,11 @@ workflow run_starfish { main: - // Match images against feature tables - id_imgs = imgs.map{ it -> tuple(Util.getImageID(it), it) } - // Apply the process to each (image, sft) pair - tiling(mcp,mcp.modules) + code = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + starfish(mcp,mcp.modules['iss_decoding'],code) // Return the outputs produced by the tool emit: - snr.out.results + starfish.out.results } \ No newline at end of file diff --git a/starfish/test_iss_decoding.yml b/starfish/test_iss_decoding.yml index eb2289e1..924f84fc 100644 --- a/starfish/test_iss_decoding.yml +++ b/starfish/test_iss_decoding.yml @@ -1,4 +1,9 @@ workflow: - start-at: iss_decoding - stop-at: iss_decoding - iss_decoding: true \ No newline at end of file + start-at: registration + stop-at: segmentation + iss_decoding: true +modules: + iss_decoding: + name: starfish + container: spacetx/starfish + version: 0.2.2 \ No newline at end of file From faacc114660cf7c772bd9c9d411cfdeeb211b9a0 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 17:48:35 +0200 Subject: [PATCH 06/18] Fixed start-at option in Flow.groovy --- lib/mcmicro/Flow.groovy | 8 ++++++-- main.nf | 4 ++-- modules/iss_decoding.nf | 8 ++++---- starfish/bin/decoding.py | 5 +++-- starfish/test_iss_decoding.yml | 14 +++++++------- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/mcmicro/Flow.groovy b/lib/mcmicro/Flow.groovy index 8e91322b..720d572c 100644 --- a/lib/mcmicro/Flow.groovy +++ b/lib/mcmicro/Flow.groovy @@ -32,7 +32,8 @@ static def flowSegment(wfp) { "segmentation", // Step 4 "watershed", // Step 5 "quantification", // Step 6 - "downstream"] // Step 7 + "downstream", // Step 7 + "iss_decoding"] // Step 8 // Identify starting and stopping indices int idxStart = mcsteps.indexOf( wfp['start-at'] ) @@ -65,7 +66,8 @@ static def precomputed(wfp) { dearray: idxStart > 3 && wfp.tma, 'probability-maps': idxStart == 5, segmentation: idxStart == 6, - quantification: idxStart == 7 + quantification: idxStart == 7, + iss_decoding: idxStart == 8 ] } @@ -94,6 +96,8 @@ static def doirun(step, wfp) { return(idxStart <= 6 && idxStop >= 6) case 'downstream': return(idxStart <= 7 && idxStop >= 7) + case 'iss_decoding': + return(idxStart <= 8 && idxStop >= 8) case 'viz': return(wfp.viz) default: diff --git a/main.nf b/main.nf index 509066ff..3b80f9e2 100755 --- a/main.nf +++ b/main.nf @@ -98,7 +98,7 @@ include {illumination} from "$projectDir/modules/illumination" include {registration} from "$projectDir/modules/registration" include {dearray} from "$projectDir/modules/dearray" include {segmentation} from "$projectDir/modules/segmentation" -include {run_starfish} from "$projectDir/modules/iss_decoding" +include {starfish} from "$projectDir/modules/iss_decoding" include {quantification} from "$projectDir/modules/quantification" include {downstream} from "$projectDir/modules/downstream" include {viz} from "$projectDir/modules/viz" @@ -126,7 +126,7 @@ workflow { tmamasks = dearray.out.masks.mix(pre_masks) // Is the data type ISS? - run_starfish(mcp) + starfish(mcp) // Reconcile WSI and TMA processing for downstream segmentation allimg = img.wsi.mix(tmacores) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index 7133feb7..894c0069 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -4,7 +4,7 @@ import mcmicro.* // Process name will appear in the the nextflow execution log // While not strictly required, it's a good idea to make the // process name match your tool name to avoid user confusion -process starfish { +process tile { // Use the container specification from the parameter file // No change to this line is required @@ -55,7 +55,7 @@ process starfish { """ } -workflow run_starfish { +workflow starfish { // Inputs: // mcp - MCMICRO parameters (workflow, options, etc.) @@ -68,9 +68,9 @@ workflow run_starfish { // Apply the process to each (image, sft) pair code = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - starfish(mcp,mcp.modules['iss_decoding'],code) + tile(mcp,mcp.modules['iss_decoding'],code) // Return the outputs produced by the tool emit: - starfish.out.results + tile.out.results } \ No newline at end of file diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index b0c332d0..2deb8f58 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -67,8 +67,9 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities -experiment = data.ISS(use_test_data=False) -test = process_experiment(experiment, experiment.codebook) print(test) +experiment = data.ISS(use_test_data=True) +test = process_experiment(experiment, experiment.codebook) + #viewer = napari.Viewer() #viewer.add_layer diff --git a/starfish/test_iss_decoding.yml b/starfish/test_iss_decoding.yml index 924f84fc..15c7a526 100644 --- a/starfish/test_iss_decoding.yml +++ b/starfish/test_iss_decoding.yml @@ -1,9 +1,9 @@ workflow: - start-at: registration - stop-at: segmentation + start-at: iss_decoding + stop-at: iss_decoding iss_decoding: true -modules: - iss_decoding: - name: starfish - container: spacetx/starfish - version: 0.2.2 \ No newline at end of file +# modules: +# iss_decoding: +# name: starfish +# container: spacetx/starfish +# version: 0.2.2 \ No newline at end of file From 1fd4b2d3f3f58a9bb1a91085420a654f1cb8ffae Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Thu, 20 Oct 2022 18:20:18 +0200 Subject: [PATCH 07/18] Fixed testing error in python script. --- starfish/bin/decoding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 2deb8f58..9f5fbe6d 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -67,8 +67,8 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities -print(test) experiment = data.ISS(use_test_data=True) +print(experiment) test = process_experiment(experiment, experiment.codebook) #viewer = napari.Viewer() From 5791bc6c75588a78e25d5ce700a2f5271ad88b62 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Fri, 21 Oct 2022 00:39:55 +0200 Subject: [PATCH 08/18] Updated processes in iss_decoding.nf --- modules/iss_decoding.nf | 70 ++++++++++++++++++++++++++++++++++------ starfish/bin/decoding.py | 2 +- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index 894c0069..9410bd21 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -1,10 +1,59 @@ // Import utility functions from lib/mcmicro/*.groovy import mcmicro.* -// Process name will appear in the the nextflow execution log -// While not strictly required, it's a good idea to make the -// process name match your tool name to avoid user confusion -process tile { +process starfish_tile { + + container "${params.contPfx}${module.container}:${module.version}" + publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.tif" + + publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', + pattern: '.command.{sh,log}', + saveAs: {fn -> fn.replace('.command', "${module.name}-${task.index}")} + + input: + val mcp + val module + path code_tile + + output: + path("*.json"), emit: results + + tuple path('.command.sh'), path('.command.log') + + when: mcp.workflow["iss_decoding"] + + """ + python $code_tile ${Opts.moduleOpts(module, mcp)} + """ +} + +process starfish_convert { + + container "${params.contPfx}${module.container}:${module.version}" + publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.tif" + + publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', + pattern: '.command.{sh,log}', + saveAs: {fn -> fn.replace('.command', "${module.name}-${task.index}")} + + input: + val mcp + val module + path code_convert + + output: + path("*.json"), emit: results + + tuple path('.command.sh'), path('.command.log') + + when: mcp.workflow["iss_decoding"] + + """ + python $code_convert ${Opts.moduleOpts(module, mcp)} + """ +} + +process starfish_decode { // Use the container specification from the parameter file // No change to this line is required @@ -30,7 +79,7 @@ process tile { input: val mcp val module - path code + path code_decode // Process outputs that should be captured and // a) returned as results @@ -51,7 +100,7 @@ process tile { // The command must write all outputs to the current working directory (.) // Opts.moduleOpts() will identify and return the appropriate module options """ - python $code ${Opts.moduleOpts(module, mcp)} + python $code_decode ${Opts.moduleOpts(module, mcp)} """ } @@ -67,10 +116,13 @@ workflow starfish { main: // Apply the process to each (image, sft) pair - code = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - tile(mcp,mcp.modules['iss_decoding'],code) + + // code_tile = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + ///code_convert = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + code_decode = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + starfish_decode(mcp,mcp.modules['iss_decoding'],code) // Return the outputs produced by the tool emit: - tile.out.results + starfish_decode.out.results } \ No newline at end of file diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 9f5fbe6d..88eda31c 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -68,8 +68,8 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities experiment = data.ISS(use_test_data=True) -print(experiment) test = process_experiment(experiment, experiment.codebook) +print(test) #viewer = napari.Viewer() #viewer.add_layer From 84f1b99bca4c12c6c7e28b2623777c27059b36bc Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Fri, 21 Oct 2022 00:42:06 +0200 Subject: [PATCH 09/18] Small fixe of code not being renamed in one space --- modules/iss_decoding.nf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index 9410bd21..f214f9ed 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -119,8 +119,9 @@ workflow starfish { // code_tile = Channel.fromPath("$projectDir/starfish/bin/decoding.py") ///code_convert = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + code_decode = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - starfish_decode(mcp,mcp.modules['iss_decoding'],code) + starfish_decode(mcp,mcp.modules['iss_decoding'],code_decode) // Return the outputs produced by the tool emit: From 099287e7037f290bc9bb40f0d4d016702cc392ab Mon Sep 17 00:00:00 2001 From: Sebastian Gonzalez Tirado Date: Fri, 21 Oct 2022 10:14:41 +0200 Subject: [PATCH 10/18] Add data-generating script and tiling python script --- starfish/bin/decoding.py | 15 +++-- starfish/bin/format_to_spacetx.py | 7 +- starfish/bin/generate_dataset.py | 106 ++++++++++++++++++++++++++++++ starfish/nf-issdecoder.nf | 25 +++++-- 4 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 starfish/bin/generate_dataset.py diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 71bd7084..0e8a83e3 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -10,8 +10,9 @@ from starfish.spots import FindSpots, DecodeSpots, AssignTargets from starfish.util.plot import imshow_plane -# Load minimal example from starfish: -#experiment = data.ISS(use_test_data=False) + + + #fov = experiment.fov() #imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) #dots = fov.get_image("dots") @@ -67,7 +68,11 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities -#process_experiment(starfish.Experiment.from_json('/Volumes/exchange/SebastianGonzalez/iss_testing/2bCartana_08_Test/SpaceTx/primary/experiment.json')) +# Load minimal example from starfish: +experiment = data.ISS(use_test_data=True) +codebook = experiment.codebook + +#if __name__ == '__main__': +# process_experiment(experiment = experiment, cb = codebook) +process_experiment(experiment = experiment, cb = codebook) -#viewer = napari.Viewer() -#viewer.add_layer diff --git a/starfish/bin/format_to_spacetx.py b/starfish/bin/format_to_spacetx.py index 54a5c4e1..74cff3b1 100644 --- a/starfish/bin/format_to_spacetx.py +++ b/starfish/bin/format_to_spacetx.py @@ -26,7 +26,7 @@ def get_args(): return parser.parse_args() #-------------------------------------------------- -def format_structured_experiment( +def format_experiment( in_dir: str = 'Tiled', out_dir: str = 'SpaceTx', subdirs: list = ['primary', 'nuclei', 'anchor_dots', 'anchor_nuclei'], @@ -52,5 +52,6 @@ def main(): out_dir = args.output_dir ) -if __name__ == '__main__': - main() \ No newline at end of file +#if __name__ == '__main__': +# main() +format_experiment('/Users/segonzal/Documents/iss_nextflow/2bCartana_08_Test/Tiled', 'SpaceTx', ['primary']) diff --git a/starfish/bin/generate_dataset.py b/starfish/bin/generate_dataset.py new file mode 100644 index 00000000..24d92af2 --- /dev/null +++ b/starfish/bin/generate_dataset.py @@ -0,0 +1,106 @@ +# Tile images and generate 'coordinates.csv' file +import os +import csv +from skimage.io import imread, imsave +from collections import namedtuple +import pandas as pd +import numpy as np + +input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' +img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) +tile_size = 500 +tile_overlap = 0 +channel_map = {'CH0': '0', 'CH1': '1', 'CH2': '2', 'CH3': '3'} + +def get_tile_coordinates(tile_size: int, tile_overlap: int) -> None: + """Compute tile coordinates.""" + tile_coordinates = {} + + RoI = namedtuple('RoI', ['row', 'col', 'nrows', 'ncols']) + tile_n = 0 + + tile_size = tile_size + tile_overlap + + def _get_size(position, tile_size, total_size): + dist_to_end = total_size - position + size = tile_size + size = size if dist_to_end > size else dist_to_end + + return size + + for r in range(0, img_input.shape[0], tile_size): + nrows = _get_size(r, tile_size, img_input.shape[0]) + + for c in range(0, img_input.shape[1], tile_size): + ncols = _get_size(c, tile_size, img_input.shape[1]) + + tile_coordinates[tile_n] = RoI(r, c, nrows, ncols) + tile_n += 1 + + return tile_coordinates + +def select_roi(image, roi): + return image[roi.row:roi.row + roi.nrows, + roi.col:roi.col + roi.ncols] + +def needs_padding(image_tile, tile_size): + return any([image_tile.shape[i] < tile_size for i in [0, 1]]) + +def pad_to_size( + image, + tile_size + ) -> np.ndarray: + """Pad smaller tiles to match standard tile size.""" + # Images must be same size + # Pad with zeros to default size + if needs_padding(image, tile_size): + pad_width = tuple((0, tile_size - image.shape[i]) for i in [0, 1]) + image = np.pad(image, pad_width, 'constant') + + return image + + +def tile_image_set(in_dir, tile_size, tile_overlap, img_type, + coordinates, output_dir): + # File names and coordinates table according to + # SpaceTx Structured Data + tile_coordinates = get_tile_coordinates(tile_size, tile_overlap) + coordinates = [] + for image_name in os.listdir(in_dir): + image = imread(os.path.join(in_dir, image_name)) + for tile_id in tile_coordinates: + coords = tile_coordinates[tile_id] + tile = select_roi( + image, roi=coords) + #tile = self._pad_to_size(tile, tile_size) + + r = image_name.split('_')[0][1:] + + c = channel_map[image_name.split('_')[1].split('.')[0]] + + file_name = f'primary-f{tile_id}-r{r}-c{c}-z0.tiff' + imsave(os.path.join(output_dir, file_name), pad_to_size(tile, tile_size)) + + coordinates.append([ + tile_id, r, c, 0, + coords.col, coords.row, 0, + coords.col + tile_size, coords.row + tile_size, 0.0001]) + + return coordinates + +def write_coords_file(coordinates, file_path) -> None: + coords_df = pd.DataFrame( + coordinates, + columns=('fov', 'round', 'ch', 'zplane', + 'xc_min', 'yc_min', 'zc_min', + 'xc_max', 'yc_max', 'zc_max')) + coords_df.to_csv(file_path, index=False) + +coords = tile_image_set('/Users/segonzal/Documents/Repositories/imbast/data/primary', + 500, + 0, + 'primary', + get_tile_coordinates(tile_size=500, tile_overlap=0), + '/Users/segonzal/Downloads') + +write_coords_file(coords, '/Users/segonzal/Downloads/coordinates.csv') diff --git a/starfish/nf-issdecoder.nf b/starfish/nf-issdecoder.nf index 5c9627c7..bba80fa7 100755 --- a/starfish/nf-issdecoder.nf +++ b/starfish/nf-issdecoder.nf @@ -75,22 +75,37 @@ process TILING { process TO_SPACETX { input: - path x +// path x output: -// path 'SpaceTx' + path 'SpaceTx' // path 'data_results' script: """ - python $projectDir/bin/to_spacetx.py -i $projectDir -c ${x} + python $projectDir/bin/format_to_spacetx.py """ } +process DECODE { + input: + path SpaceTx + + output: + stdout +// path 'SpaceTx' +// path 'data_results' + + script: + """ + python $projectDir/bin/decoding.py + """ +} workflow { - tiling_ch = TILING(params.register_dir) - tiling_ch.view() + tiling_ch = TO_SPACETX() + decoding_ch = DECODE() + decoding_ch.view() // tiling_ch.view() // result_spacetx = TO_SPACETX(params.codebook) // final_process = RESULT(result_spacetx.out) From ec96640ea9317fdf9986cf2391e0e30225e48eb5 Mon Sep 17 00:00:00 2001 From: Sebastian Gonzalez Tirado Date: Fri, 21 Oct 2022 10:21:50 +0200 Subject: [PATCH 11/18] Upload python script files again --- starfish/bin/generate_dataset.py | 125 +++++-------------------------- starfish/bin/tiling.py | 106 ++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 105 deletions(-) create mode 100644 starfish/bin/tiling.py diff --git a/starfish/bin/generate_dataset.py b/starfish/bin/generate_dataset.py index 24d92af2..15fa196d 100644 --- a/starfish/bin/generate_dataset.py +++ b/starfish/bin/generate_dataset.py @@ -1,106 +1,21 @@ -# Tile images and generate 'coordinates.csv' file import os -import csv -from skimage.io import imread, imsave -from collections import namedtuple -import pandas as pd -import numpy as np - -input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' -img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) -tile_size = 500 -tile_overlap = 0 -channel_map = {'CH0': '0', 'CH1': '1', 'CH2': '2', 'CH3': '3'} - -def get_tile_coordinates(tile_size: int, tile_overlap: int) -> None: - """Compute tile coordinates.""" - tile_coordinates = {} - - RoI = namedtuple('RoI', ['row', 'col', 'nrows', 'ncols']) - tile_n = 0 - - tile_size = tile_size + tile_overlap - - def _get_size(position, tile_size, total_size): - dist_to_end = total_size - position - size = tile_size - size = size if dist_to_end > size else dist_to_end - - return size - - for r in range(0, img_input.shape[0], tile_size): - nrows = _get_size(r, tile_size, img_input.shape[0]) - - for c in range(0, img_input.shape[1], tile_size): - ncols = _get_size(c, tile_size, img_input.shape[1]) - - tile_coordinates[tile_n] = RoI(r, c, nrows, ncols) - tile_n += 1 - - return tile_coordinates - -def select_roi(image, roi): - return image[roi.row:roi.row + roi.nrows, - roi.col:roi.col + roi.ncols] - -def needs_padding(image_tile, tile_size): - return any([image_tile.shape[i] < tile_size for i in [0, 1]]) - -def pad_to_size( - image, - tile_size - ) -> np.ndarray: - """Pad smaller tiles to match standard tile size.""" - # Images must be same size - # Pad with zeros to default size - if needs_padding(image, tile_size): - pad_width = tuple((0, tile_size - image.shape[i]) for i in [0, 1]) - image = np.pad(image, pad_width, 'constant') - - return image - - -def tile_image_set(in_dir, tile_size, tile_overlap, img_type, - coordinates, output_dir): - # File names and coordinates table according to - # SpaceTx Structured Data - tile_coordinates = get_tile_coordinates(tile_size, tile_overlap) - coordinates = [] - for image_name in os.listdir(in_dir): - image = imread(os.path.join(in_dir, image_name)) - for tile_id in tile_coordinates: - coords = tile_coordinates[tile_id] - tile = select_roi( - image, roi=coords) - #tile = self._pad_to_size(tile, tile_size) - - r = image_name.split('_')[0][1:] - - c = channel_map[image_name.split('_')[1].split('.')[0]] - - file_name = f'primary-f{tile_id}-r{r}-c{c}-z0.tiff' - imsave(os.path.join(output_dir, file_name), pad_to_size(tile, tile_size)) - - coordinates.append([ - tile_id, r, c, 0, - coords.col, coords.row, 0, - coords.col + tile_size, coords.row + tile_size, 0.0001]) - - return coordinates - -def write_coords_file(coordinates, file_path) -> None: - coords_df = pd.DataFrame( - coordinates, - columns=('fov', 'round', 'ch', 'zplane', - 'xc_min', 'yc_min', 'zc_min', - 'xc_max', 'yc_max', 'zc_max')) - coords_df.to_csv(file_path, index=False) - -coords = tile_image_set('/Users/segonzal/Documents/Repositories/imbast/data/primary', - 500, - 0, - 'primary', - get_tile_coordinates(tile_size=500, tile_overlap=0), - '/Users/segonzal/Downloads') - -write_coords_file(coords, '/Users/segonzal/Downloads/coordinates.csv') +from starfish import data, FieldOfView +import tifffile as tiff +from starfish import Experiment +from starfish.types import Axes +import napari + +# Create sample raw dataset for tiling: +exp = data.ISS(use_test_data=False) +fov = exp['fov_000'] +primary = fov.get_image(FieldOfView.PRIMARY_IMAGES) + +save_dir = '/Users/segonzal/Documents/Repositories/imbast/data/primary' +# Loop through data and save it: +# Save nuclei (will focus for now only on primary images +#tiff.imwrite(os.path.join(save_dir, '') ,fov.get_image('nuclei') + +for ch in range(4): + for r in range(4): + img = primary.sel({Axes.ROUND: r, Axes.CH: ch}).xarray.squeeze() + tiff.imwrite(os.path.join(save_dir, 'r' + str(r) + '_' + 'CH' + str(ch) + '.tiff'), img) diff --git a/starfish/bin/tiling.py b/starfish/bin/tiling.py new file mode 100644 index 00000000..24d92af2 --- /dev/null +++ b/starfish/bin/tiling.py @@ -0,0 +1,106 @@ +# Tile images and generate 'coordinates.csv' file +import os +import csv +from skimage.io import imread, imsave +from collections import namedtuple +import pandas as pd +import numpy as np + +input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' +img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) +tile_size = 500 +tile_overlap = 0 +channel_map = {'CH0': '0', 'CH1': '1', 'CH2': '2', 'CH3': '3'} + +def get_tile_coordinates(tile_size: int, tile_overlap: int) -> None: + """Compute tile coordinates.""" + tile_coordinates = {} + + RoI = namedtuple('RoI', ['row', 'col', 'nrows', 'ncols']) + tile_n = 0 + + tile_size = tile_size + tile_overlap + + def _get_size(position, tile_size, total_size): + dist_to_end = total_size - position + size = tile_size + size = size if dist_to_end > size else dist_to_end + + return size + + for r in range(0, img_input.shape[0], tile_size): + nrows = _get_size(r, tile_size, img_input.shape[0]) + + for c in range(0, img_input.shape[1], tile_size): + ncols = _get_size(c, tile_size, img_input.shape[1]) + + tile_coordinates[tile_n] = RoI(r, c, nrows, ncols) + tile_n += 1 + + return tile_coordinates + +def select_roi(image, roi): + return image[roi.row:roi.row + roi.nrows, + roi.col:roi.col + roi.ncols] + +def needs_padding(image_tile, tile_size): + return any([image_tile.shape[i] < tile_size for i in [0, 1]]) + +def pad_to_size( + image, + tile_size + ) -> np.ndarray: + """Pad smaller tiles to match standard tile size.""" + # Images must be same size + # Pad with zeros to default size + if needs_padding(image, tile_size): + pad_width = tuple((0, tile_size - image.shape[i]) for i in [0, 1]) + image = np.pad(image, pad_width, 'constant') + + return image + + +def tile_image_set(in_dir, tile_size, tile_overlap, img_type, + coordinates, output_dir): + # File names and coordinates table according to + # SpaceTx Structured Data + tile_coordinates = get_tile_coordinates(tile_size, tile_overlap) + coordinates = [] + for image_name in os.listdir(in_dir): + image = imread(os.path.join(in_dir, image_name)) + for tile_id in tile_coordinates: + coords = tile_coordinates[tile_id] + tile = select_roi( + image, roi=coords) + #tile = self._pad_to_size(tile, tile_size) + + r = image_name.split('_')[0][1:] + + c = channel_map[image_name.split('_')[1].split('.')[0]] + + file_name = f'primary-f{tile_id}-r{r}-c{c}-z0.tiff' + imsave(os.path.join(output_dir, file_name), pad_to_size(tile, tile_size)) + + coordinates.append([ + tile_id, r, c, 0, + coords.col, coords.row, 0, + coords.col + tile_size, coords.row + tile_size, 0.0001]) + + return coordinates + +def write_coords_file(coordinates, file_path) -> None: + coords_df = pd.DataFrame( + coordinates, + columns=('fov', 'round', 'ch', 'zplane', + 'xc_min', 'yc_min', 'zc_min', + 'xc_max', 'yc_max', 'zc_max')) + coords_df.to_csv(file_path, index=False) + +coords = tile_image_set('/Users/segonzal/Documents/Repositories/imbast/data/primary', + 500, + 0, + 'primary', + get_tile_coordinates(tile_size=500, tile_overlap=0), + '/Users/segonzal/Downloads') + +write_coords_file(coords, '/Users/segonzal/Downloads/coordinates.csv') From 02f72d761a400d546955626c0f25b5a831aa04f1 Mon Sep 17 00:00:00 2001 From: Gleb Rukhovich Date: Fri, 21 Oct 2022 10:51:44 +0200 Subject: [PATCH 12/18] Updated dataset generation --- starfish/bin/generate_dataset.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/starfish/bin/generate_dataset.py b/starfish/bin/generate_dataset.py index 15fa196d..8cb093e8 100644 --- a/starfish/bin/generate_dataset.py +++ b/starfish/bin/generate_dataset.py @@ -1,21 +1,27 @@ import os from starfish import data, FieldOfView import tifffile as tiff -from starfish import Experiment from starfish.types import Axes -import napari +from pathlib import Path +from typing import Union + # Create sample raw dataset for tiling: exp = data.ISS(use_test_data=False) fov = exp['fov_000'] primary = fov.get_image(FieldOfView.PRIMARY_IMAGES) -save_dir = '/Users/segonzal/Documents/Repositories/imbast/data/primary' -# Loop through data and save it: -# Save nuclei (will focus for now only on primary images -#tiff.imwrite(os.path.join(save_dir, '') ,fov.get_image('nuclei') +# save_dir = '/Users/segonzal/Documents/Repositories/imbast/data/primary' +save_dir = Path(os.getcwd()) / "sample_dataset" + + +def generate_dataset(save_dir: Union[str, Path]): + save_dir = Path(save_dir) + for ch in range(4): + for r in range(4): + img = primary.sel({Axes.ROUND: r, Axes.CH: ch}).xarray.squeeze() + tiff.imwrite(save_dir / f"r{r}_CH{ch}.tiff", img) + -for ch in range(4): - for r in range(4): - img = primary.sel({Axes.ROUND: r, Axes.CH: ch}).xarray.squeeze() - tiff.imwrite(os.path.join(save_dir, 'r' + str(r) + '_' + 'CH' + str(ch) + '.tiff'), img) +if __name__ == '__main__': + generate_dataset(save_dir) From 58f50b873e933cb03c04b14db600dd2d432eb659 Mon Sep 17 00:00:00 2001 From: Gleb Rukhovich Date: Fri, 21 Oct 2022 11:49:24 +0200 Subject: [PATCH 13/18] Added argparse to tiling --- starfish/bin/tiling.py | 60 +++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/starfish/bin/tiling.py b/starfish/bin/tiling.py index 24d92af2..a86593a8 100644 --- a/starfish/bin/tiling.py +++ b/starfish/bin/tiling.py @@ -5,15 +5,19 @@ from collections import namedtuple import pandas as pd import numpy as np +import argparse +from pathlib import Path -input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' -img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) -tile_size = 500 -tile_overlap = 0 +# input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' +# img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) +# tile_size = 500 +# tile_overlap = 0 channel_map = {'CH0': '0', 'CH1': '1', 'CH2': '2', 'CH3': '3'} -def get_tile_coordinates(tile_size: int, tile_overlap: int) -> None: + +def get_tile_coordinates(img_input, tile_size: int, tile_overlap: int) -> None: """Compute tile coordinates.""" + tile_coordinates = {} RoI = namedtuple('RoI', ['row', 'col', 'nrows', 'ncols']) @@ -39,13 +43,16 @@ def _get_size(position, tile_size, total_size): return tile_coordinates + def select_roi(image, roi): return image[roi.row:roi.row + roi.nrows, roi.col:roi.col + roi.ncols] + def needs_padding(image_tile, tile_size): return any([image_tile.shape[i] < tile_size for i in [0, 1]]) + def pad_to_size( image, tile_size @@ -64,7 +71,7 @@ def tile_image_set(in_dir, tile_size, tile_overlap, img_type, coordinates, output_dir): # File names and coordinates table according to # SpaceTx Structured Data - tile_coordinates = get_tile_coordinates(tile_size, tile_overlap) + tile_coordinates = get_tile_coordinates(imread(Path(in_dir) / os.listdir(in_dir)[0]), tile_size, tile_overlap) coordinates = [] for image_name in os.listdir(in_dir): image = imread(os.path.join(in_dir, image_name)) @@ -88,6 +95,7 @@ def tile_image_set(in_dir, tile_size, tile_overlap, img_type, return coordinates + def write_coords_file(coordinates, file_path) -> None: coords_df = pd.DataFrame( coordinates, @@ -96,11 +104,37 @@ def write_coords_file(coordinates, file_path) -> None: 'xc_max', 'yc_max', 'zc_max')) coords_df.to_csv(file_path, index=False) -coords = tile_image_set('/Users/segonzal/Documents/Repositories/imbast/data/primary', - 500, - 0, - 'primary', - get_tile_coordinates(tile_size=500, tile_overlap=0), - '/Users/segonzal/Downloads') -write_coords_file(coords, '/Users/segonzal/Downloads/coordinates.csv') +def main(input_path, output_path, tile_size=500, tile_overlap=0): + input_path = Path(input_path) + output_path = Path(output_path) + # coords = tile_image_set( + # '/Users/segonzal/Documents/Repositories/imbast/data/primary', + # tile_size, + # tile_overlap, + # 'primary', + # get_tile_coordinates(tile_size=tile_size, tile_overlap=tile_overlap), + # '/Users/segonzal/Downloads' + # ) + + input_path = Path(input_path) + output_path = Path(output_path) + output_path.mkdir(exist_ok=True) + + coords = tile_image_set( + input_path, tile_size, tile_overlap, "primary", + get_tile_coordinates(imread(input_path / os.listdir(input_path)[0]), tile_size=tile_size, tile_overlap=tile_overlap), output_path + ) + write_coords_file(coords, output_path / 'coordinates.csv') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-i", "--input", help="input path for images", type=str) + parser.add_argument("-o", "--output", help="output folder for tiled images", type=str) + + parser.add_argument("-ts", "--tile-size", type=int, help="the size of tiles", default=500) + parser.add_argument("-to", "--tile-overlap", type=int, help="the overlay for tiles", default=0) + args = parser.parse_args() + + main(args.input, args.output, args.tile_size, args.tile_overlap) From 3c413fe15e603ccf0931b4538bac45729750fe6a Mon Sep 17 00:00:00 2001 From: Sebastian Gonzalez Tirado Date: Fri, 21 Oct 2022 13:25:27 +0200 Subject: [PATCH 14/18] Change nextflow file --- starfish/nf-issdecoder.nf | 73 ++++++++------------------------------- 1 file changed, 15 insertions(+), 58 deletions(-) diff --git a/starfish/nf-issdecoder.nf b/starfish/nf-issdecoder.nf index bba80fa7..e04c4b8d 100755 --- a/starfish/nf-issdecoder.nf +++ b/starfish/nf-issdecoder.nf @@ -2,88 +2,48 @@ * pipeline input parameters */ // params.datadir = "$projectDir/data/input/" -params.input_dir = "$projectDir" +params.input_dir = "$projectDir/data/Registered" params.register_dir = "/Registered" params.codebook = "$projectDir/data/codebook.json" -// params.output = "$projectDir/data/output" -// params.script_Python_Registration = './code/python/registration.py' + + log.info """\ SPATIAL TRANSCRIPTOMICS PIPELINE ================================ test : ${params.test} -// input datadir: ${params.datadir} -// sample name : ${params.sample_name} -// outdir : ${params.output} -// project dir : ${projectDir} + input datadir: ${params.input_dir} """ .stripIndent() // nextflow.enable.dsl=2 -process image_registration { - publishDir "$params.output", mode: 'copy', overwrite: true - - input: - val x -// val y -// path y -// path x -// val datadir_in -// val sample_in - - output: -// stdout - path 'Registered' - - script: - """ - python $projectDir/bin/python_draft.py -t ${x} -o 'Registered' - """ -} - - -process TILING_TEST { - - input: -// path prev_img - - output: - path 'Tiled' -// path '*_results' - - script: - """ - python $projectDir/bin/to_spacetx_print_results.py - """ -} - process TILING { input: path x output: - path Tiled + path 'Tiled' // path '*_results' script: """ - python $projectDir/bin/tiling_test.py -s data -d $projectDir -p ${x} + python $projectDir/bin/tiling.py -i ${x} """ } process TO_SPACETX { input: -// path x + path TILED output: - path 'SpaceTx' + path SpaceTx // path 'data_results' script: """ - python $projectDir/bin/format_to_spacetx.py + python $projectDir/bin/format_to_spacetx.py -i $TILED """ } @@ -103,15 +63,12 @@ process DECODE { """ } workflow { - tiling_ch = TO_SPACETX() - decoding_ch = DECODE() - decoding_ch.view() -// tiling_ch.view() -// result_spacetx = TO_SPACETX(params.codebook) -// final_process = RESULT(result_spacetx.out) -// result_spacetx.view{} -// result_ch = image_registration(params.test) -// result_ch.view() + tiling_ch = TILING(params.input_dir) + tiling_ch.view() + spacetx_ch = TO_SPACETX(tiling_ch) +// tiling_ch = TO_SPACETX() +// decoding_ch = DECODE() +// decoding_ch.view() // test_name = Channel.from(params.test) // sample_in = Channel.from(params.sample_name) // script_file = Channel.fromPath(params.script_Python_Registration) From c6a148b0fd7a80d2e24c06305075902404536795 Mon Sep 17 00:00:00 2001 From: Sebastian Gonzalez Tirado Date: Fri, 21 Oct 2022 14:31:40 +0200 Subject: [PATCH 15/18] Make final decoding.py --- starfish/bin/decoding.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 6d1b361e..99b6ed4b 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -2,20 +2,30 @@ import numpy as np import starfish from skimage.io import imread -#import napari - +import argparse from starfish.image import ApplyTransform, LearnTransform, Filter from starfish.types import Axes from starfish import data, FieldOfView from starfish.spots import FindSpots, DecodeSpots, AssignTargets from starfish.util.plot import imshow_plane +codebook = data.ISS(use_test_data=True).codebook + +def get_args(): + """Get command-line arguments""" + parser = argparse.ArgumentParser( + description='Input/output directories for data formatting', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-i', + '--input_dir', + default='Tiled', + type=str, + help='Input root directory') + + return parser.parse_args() -#fov = experiment.fov() -#imgs = fov.get_image(FieldOfView.PRIMARY_IMAGES) -#dots = fov.get_image("dots") def iss_pipeline(fov, codebook): #fov = experiment.fov() @@ -68,8 +78,17 @@ def process_experiment(experiment: starfish.Experiment, cb: starfish.Codebook): return decoded_intensities -experiment = data.ISS(use_test_data=True) -test = process_experiment(experiment, experiment.codebook) -print(test) +def save_fov(fov, dataframe): + fov_df = dataframe.to_features_dataframe() + fov_df.to_csv(f'fov_{fov}.csv', index=False) + +def main(): + args = get_args() + exp = starfish.Experiment.from_json(os.path.join(args.input_dir, 'primary', 'experiment.json')) + results = process_experiment(exp, codebook) + for fov, data in results.items(): + save_fov(fov, data) +if __name__ == '__main__': + main() From d9b54ab915dfb010c912e7ac19b06733f7f1a568 Mon Sep 17 00:00:00 2001 From: Gleb Rukhovich Date: Fri, 21 Oct 2022 15:01:53 +0200 Subject: [PATCH 16/18] Implemented and tested all 3 process --- main.nf | 5 ++- modules/iss_decoding.nf | 51 ++++++++++++++++++------------- starfish/bin/format_to_spacetx.py | 16 +++++----- starfish/bin/generate_dataset.py | 1 + starfish/bin/tiling.py | 3 +- starfish/nf-issdecoder.nf | 2 +- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/main.nf b/main.nf index 3b80f9e2..bbb34425 100755 --- a/main.nf +++ b/main.nf @@ -49,6 +49,9 @@ findFiles = { key, pattern, ife -> pre[key] ? Channel.fromPath("${params.in}/$key/$pattern").ifEmpty(ife) : Channel.empty() } +// Find spot images in starfish_input +starimgs = Channel.fromPath( "${params.in}/primary", checkIfExists: true ) + // Some image formats store multiple fields of view in a single file. Other // formats store each field separately, typically in .tif files, with a separate // index file to tie them together. We will look for the index files from @@ -126,7 +129,7 @@ workflow { tmamasks = dearray.out.masks.mix(pre_masks) // Is the data type ISS? - starfish(mcp) + starfish(mcp, starimgs) // Reconcile WSI and TMA processing for downstream segmentation allimg = img.wsi.mix(tmacores) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index f214f9ed..b25d8685 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -14,16 +14,16 @@ process starfish_tile { val mcp val module path code_tile + path img_dir output: - path("*.json"), emit: results - + path 'TILED' tuple path('.command.sh'), path('.command.log') when: mcp.workflow["iss_decoding"] - """ - python $code_tile ${Opts.moduleOpts(module, mcp)} + """ + python $code_tile --input ${img_dir} --output TILED """ } @@ -32,24 +32,24 @@ process starfish_convert { container "${params.contPfx}${module.container}:${module.version}" publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.tif" - publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', + publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', pattern: '.command.{sh,log}', saveAs: {fn -> fn.replace('.command', "${module.name}-${task.index}")} input: val mcp val module - path code_convert + path code + path TILED output: - path("*.json"), emit: results - + path 'SpaceTx' tuple path('.command.sh'), path('.command.log') when: mcp.workflow["iss_decoding"] - """ - python $code_convert ${Opts.moduleOpts(module, mcp)} + """ + python $code -i $TILED -o SpaceTx """ } @@ -58,17 +58,17 @@ process starfish_decode { // Use the container specification from the parameter file // No change to this line is required container "${params.contPfx}${module.container}:${module.version}" - + // Specify the project subdirectory for writing the outputs to // The pattern: specification must match the output: files below // TODO: replace report with the desired output directory // TODO: replace the pattern to match the output: clause below - publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.tif" + publishDir "${params.in}/iss_processing", mode: 'copy', pattern: "*.csv" // Stores .command.sh and .command.log from the work directory // to the project provenance // No change to this line is required - publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', + publishDir "${Flow.QC(params.in, 'provenance')}", mode: 'copy', pattern: '.command.{sh,log}', saveAs: {fn -> fn.replace('.command', "${module.name}-${task.index}")} @@ -79,14 +79,15 @@ process starfish_decode { input: val mcp val module - path code_decode + path code + path SpaceTx - // Process outputs that should be captured and + // Process outputs that should be captured and // a) returned as results // b) published to the project directory // TODO: replace *.html with the pattern of the tool output files output: - path("*.json"), emit: results + path("*.csv"), emit: results // Provenance files -- no change is needed here tuple path('.command.sh'), path('.command.log') @@ -99,8 +100,8 @@ process starfish_decode { // The command to be executed inside the tool container // The command must write all outputs to the current working directory (.) // Opts.moduleOpts() will identify and return the appropriate module options - """ - python $code_decode ${Opts.moduleOpts(module, mcp)} + """ + python $code -i SpaceTx """ } @@ -112,6 +113,7 @@ workflow starfish { // cbk - Codebook take: mcp + img_dir main: @@ -120,10 +122,17 @@ workflow starfish { // code_tile = Channel.fromPath("$projectDir/starfish/bin/decoding.py") ///code_convert = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - code_decode = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - starfish_decode(mcp,mcp.modules['iss_decoding'],code_decode) + code_decode = Channel.fromPath("$projectDir/starfish/bin/tiling.py") + TILED = starfish_tile(mcp, mcp.modules['iss_decoding'], code_decode, img_dir) + println TILED + code_convert = Channel.fromPath("$projectDir/starfish/bin/format_to_spacetx.py") + SpaceTx = starfish_convert(mcp, mcp.modules['iss_decoding'], code_convert, TILED[0]) + + code_decode = Channel.fromPath("$projectDir/starfish/bin/decoding.py") + results = starfish_decode(mcp, mcp.modules['iss_decoding'], code_decode, SpaceTx[0]) // Return the outputs produced by the tool + emit: - starfish_decode.out.results + results[0] } \ No newline at end of file diff --git a/starfish/bin/format_to_spacetx.py b/starfish/bin/format_to_spacetx.py index 74cff3b1..ea129caa 100644 --- a/starfish/bin/format_to_spacetx.py +++ b/starfish/bin/format_to_spacetx.py @@ -33,7 +33,8 @@ def format_experiment( coordinates_filename: str = 'coordinates.csv' ): for subdir in subdirs: - in_d = os.path.join(in_dir, subdir) + # in_d = os.path.join(in_dir, subdir) + in_d = in_dir out_d = os.path.join(out_dir, subdir) os.makedirs(out_d) @@ -47,11 +48,12 @@ def format_experiment( #-------------------------------------------------- def main(): args = get_args() - format_structured_dataset( - in_dir = args.input_dir, - out_dir = args.output_dir + format_experiment( + in_dir=args.input_dir, + out_dir=args.output_dir ) -#if __name__ == '__main__': -# main() -format_experiment('/Users/segonzal/Documents/iss_nextflow/2bCartana_08_Test/Tiled', 'SpaceTx', ['primary']) + +if __name__ == '__main__': + main() +# format_experiment('/Users/segonzal/Documents/iss_nextflow/2bCartana_08_Test/Tiled', 'SpaceTx', ['primary']) diff --git a/starfish/bin/generate_dataset.py b/starfish/bin/generate_dataset.py index 8cb093e8..9fd0e57c 100644 --- a/starfish/bin/generate_dataset.py +++ b/starfish/bin/generate_dataset.py @@ -13,6 +13,7 @@ # save_dir = '/Users/segonzal/Documents/Repositories/imbast/data/primary' save_dir = Path(os.getcwd()) / "sample_dataset" +print(save_dir) def generate_dataset(save_dir: Union[str, Path]): diff --git a/starfish/bin/tiling.py b/starfish/bin/tiling.py index a86593a8..a12f81c0 100644 --- a/starfish/bin/tiling.py +++ b/starfish/bin/tiling.py @@ -7,6 +7,7 @@ import numpy as np import argparse from pathlib import Path +import logging # input_path = '/Users/segonzal/Documents/Repositories/imbast/data/primary' # img_input = imread(os.path.join(input_path, os.listdir(input_path)[0])) @@ -116,7 +117,7 @@ def main(input_path, output_path, tile_size=500, tile_overlap=0): # get_tile_coordinates(tile_size=tile_size, tile_overlap=tile_overlap), # '/Users/segonzal/Downloads' # ) - + print(input_path, output_path) input_path = Path(input_path) output_path = Path(output_path) output_path.mkdir(exist_ok=True) diff --git a/starfish/nf-issdecoder.nf b/starfish/nf-issdecoder.nf index e04c4b8d..8e2b0f73 100755 --- a/starfish/nf-issdecoder.nf +++ b/starfish/nf-issdecoder.nf @@ -28,7 +28,7 @@ process TILING { script: """ - python $projectDir/bin/tiling.py -i ${x} + python $projectDir/bin/tiling.py --input ${x} --output TILED """ } From 55bdff82796d27d38a57b048f80c2f50e69fc7f2 Mon Sep 17 00:00:00 2001 From: Gleb Rukhovich Date: Fri, 21 Oct 2022 16:03:02 +0200 Subject: [PATCH 17/18] Cleaning --- modules/iss_decoding.nf | 4 ++-- starfish/bin/decoding.py | 5 ++--- starfish/bin/format_to_spacetx.py | 33 +++++++++++-------------------- starfish/bin/tiling.py | 12 +---------- 4 files changed, 16 insertions(+), 38 deletions(-) diff --git a/modules/iss_decoding.nf b/modules/iss_decoding.nf index b25d8685..663fd79c 100644 --- a/modules/iss_decoding.nf +++ b/modules/iss_decoding.nf @@ -122,8 +122,8 @@ workflow starfish { // code_tile = Channel.fromPath("$projectDir/starfish/bin/decoding.py") ///code_convert = Channel.fromPath("$projectDir/starfish/bin/decoding.py") - code_decode = Channel.fromPath("$projectDir/starfish/bin/tiling.py") - TILED = starfish_tile(mcp, mcp.modules['iss_decoding'], code_decode, img_dir) + code_tile = Channel.fromPath("$projectDir/starfish/bin/tiling.py") + TILED = starfish_tile(mcp, mcp.modules['iss_decoding'], code_tile, img_dir) println TILED code_convert = Channel.fromPath("$projectDir/starfish/bin/format_to_spacetx.py") diff --git a/starfish/bin/decoding.py b/starfish/bin/decoding.py index 99b6ed4b..c5714f35 100644 --- a/starfish/bin/decoding.py +++ b/starfish/bin/decoding.py @@ -1,16 +1,14 @@ import os -import numpy as np import starfish -from skimage.io import imread import argparse from starfish.image import ApplyTransform, LearnTransform, Filter from starfish.types import Axes from starfish import data, FieldOfView from starfish.spots import FindSpots, DecodeSpots, AssignTargets -from starfish.util.plot import imshow_plane codebook = data.ISS(use_test_data=True).codebook + def get_args(): """Get command-line arguments""" @@ -82,6 +80,7 @@ def save_fov(fov, dataframe): fov_df = dataframe.to_features_dataframe() fov_df.to_csv(f'fov_{fov}.csv', index=False) + def main(): args = get_args() exp = starfish.Experiment.from_json(os.path.join(args.input_dir, 'primary', 'experiment.json')) diff --git a/starfish/bin/format_to_spacetx.py b/starfish/bin/format_to_spacetx.py index ea129caa..1af4c5f7 100644 --- a/starfish/bin/format_to_spacetx.py +++ b/starfish/bin/format_to_spacetx.py @@ -3,49 +3,39 @@ import argparse import os -# -------------------------------------------------- + def get_args(): """Get command-line arguments""" parser = argparse.ArgumentParser( description='Input/output directories for data formatting', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument('-i', - '--input_dir', - default='Tiled', - type=str, - help='Input root directory') + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) - parser.add_argument('-o', - '--output_dir', - default='SpaceTx', - type=str, - help='Output root directory') + parser.add_argument('-i', '--input_dir', default='Tiled', type=str, help='Input root directory') + parser.add_argument('-o', '--output_dir', default='SpaceTx', type=str, help='Output root directory') return parser.parse_args() -#-------------------------------------------------- + def format_experiment( in_dir: str = 'Tiled', out_dir: str = 'SpaceTx', subdirs: list = ['primary', 'nuclei', 'anchor_dots', 'anchor_nuclei'], coordinates_filename: str = 'coordinates.csv' -): +) -> None: for subdir in subdirs: - # in_d = os.path.join(in_dir, subdir) - in_d = in_dir out_d = os.path.join(out_dir, subdir) os.makedirs(out_d) format_structured_dataset( - in_d, - os.path.join(in_d, "coordinates.csv"), + in_dir, + os.path.join(in_dir, "coordinates.csv"), out_d, ImageFormat.TIFF, ) -#-------------------------------------------------- + def main(): args = get_args() format_experiment( @@ -55,5 +45,4 @@ def main(): if __name__ == '__main__': - main() -# format_experiment('/Users/segonzal/Documents/iss_nextflow/2bCartana_08_Test/Tiled', 'SpaceTx', ['primary']) + main() diff --git a/starfish/bin/tiling.py b/starfish/bin/tiling.py index a12f81c0..5647b47b 100644 --- a/starfish/bin/tiling.py +++ b/starfish/bin/tiling.py @@ -109,17 +109,7 @@ def write_coords_file(coordinates, file_path) -> None: def main(input_path, output_path, tile_size=500, tile_overlap=0): input_path = Path(input_path) output_path = Path(output_path) - # coords = tile_image_set( - # '/Users/segonzal/Documents/Repositories/imbast/data/primary', - # tile_size, - # tile_overlap, - # 'primary', - # get_tile_coordinates(tile_size=tile_size, tile_overlap=tile_overlap), - # '/Users/segonzal/Downloads' - # ) - print(input_path, output_path) - input_path = Path(input_path) - output_path = Path(output_path) + output_path.mkdir(exist_ok=True) coords = tile_image_set( From cab737d5272add20c3e184a19312e3043dc0d8f4 Mon Sep 17 00:00:00 2001 From: FloWuenne Date: Fri, 21 Oct 2022 16:20:18 +0200 Subject: [PATCH 18/18] Update docs --- docs/parameters/other.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/parameters/other.md b/docs/parameters/other.md index 0851dbee..15f88dcd 100755 --- a/docs/parameters/other.md +++ b/docs/parameters/other.md @@ -14,10 +14,14 @@ Segmentation 1. [Cypository](./other.html#cypository) 1. [Mesmer](./other.html#mesmer) -Clsutering and cell type inference +Clustering and cell type inference 1. [Clustering](./other.html#clustering) 1. [naivestates](./other.html#naivestates) +In-situ sequencing spot deconvolution +1. [Starfish](./other.html#starfish) + +
[Back to main modules](./){: .btn .btn-outline} @@ -258,3 +262,30 @@ Nextflow will write all outputs to the `cell-states/naivestates/` subdirectory w |`--mct ` | |The tool has a basic marker -> cell type (mct) mapping in `typemap.csv`. More sophisticated mct mappings can be defined by creating a `custom-map.csv` file with two columns: `Marker` and `State`. | [Back to top](./other.html#other-modules){: .btn .btn-purple} [Back to main modules](./){: .btn .btn-outline} + +## Starfish + +### Description +starfish is a Python library for processing images of image-based spatial transcriptomics. We implemented part of the starfish pipeline to process ISS images starting from ... until the final result, a table with locations of all called spots. +### Usage +Add a `iss_decoding:` field to [workflow parameters]({{site.baseurl}}/parameters/) to select starfish. + +* Example `params.yml`: + +``` yaml +workflow: + stop-at: iss_decoding + downstream: naivestates + naivestates-model: /full/path/to/mct.csv +options: + naivestates: --log no +``` +* Default naivestates options: `-p png` +* Running outside of MCMICRO: [Instructions](https://github.com/labsyspharm/mcmicro-ilastik){:target="_blank"}. +### Inputs + + +### Outputs + + +### Optional arguments