Skip to content

ahnlabb/DDMFramework.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DDMFramework

Stable Dev Build Status Coverage

DDMFramework.jl is a Julia package for building and running data-driven microscopy analyses.

Plugins

A plugin manages updating and querying state for an analysis.

multipoint

The simplest way to create a plugin is to generate a dynamic plugin using multipoint.

multipoint(analysis, name::String, keyfun; keytest=(==))

The first argument, analysis, is a function that receives an acquired image and the plugin configuration and should output a julia Table.

The keyfun argument is a function used to generate a key from the data sent by the client. This key is used to differentiate between different fields-of-view. To test if newly received data belongs to a previously seen field-of-view the function keytest (which defaults to ==) is used.

The name is used when registering the plugin with the server and rendering results.

Example

using Images
using DDMFramework
using RegionProps
using DataFrames
using Chain
using SparseArrays
using StatsBase

otsu_segment(img) = img .> otsu_threshold(img)

function filter_objects_in_image(labeled_image, minsize, maxsize)
    sparse_lb = sparse(labeled_image)
    counts = countmap(nonzeros(sparse_lb))
    for (i, j, v) in zip(findnz(sparse_lb)...)
        if counts[v] < minsize || counts[v] > maxsize
            lb[i, j] = 0
        end
    end
    dropzeros!(labeled_image)
end

function simple_segmentation(img; minsize=150, maxsize=2000)
    labeled_image = @chain img begin
        otsu_segment
        label_components
        filter_objects_in_image(_, minsize, maxsize)
    end
    return labeled_image
end

function keyfun(data)::Tuple{Float64}
    x = data["image"].Pixels[:Plane][1][:PositionX]
    y = data["image"].Pixels[:Plane][1][:PositionY]
    return (x,y)
end

function keytest(kleft::Tuple{Float64}, kright::Tuple{Float64})
    atol = 1.2
    isapprox.(kleft,kright;atol) |> all
end

my_plugin = multipoint("NucleusProperties", keyfun; keytest) do image, config
    # Segmentation parameters
    seg_params = config["segmentation"]

    # Segment and filter objects on size in image
    labeled_image = simple_segmentation(image, kwiterator(seg_params, :minsize, :maxsize)...)

    # Extract stats about our objects
    return regionprops(
        image,
        labeled_image;
        selected=unique(nonzeros(labeled_image))
    )
end

add_plugin(my_plugin)

Plugin interface

Completely custom plugin logic can be added by defining a struct subtyping AbstractPlugin and fulfilling the plugin interface:

Method Description
handle_update(state) Returns a tuple of the response (reply to client) as a String and the updated state
query_state(state, query) Returns a String

The plugin also needs a constructor that takes a Dict containing the plugin configuration.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages