Workflow#

This section gives a broad overview of the steps taken in processing images.

Topotracing : Processing a single .spm file#

Topotracing loads images from .spm files and extracts the specified channel, performing various filtering stages (Filters() class) before finding grains (Grains() class) and then calculating statistics for each grain (GrainStats() class). The Gaussian filtered image and labelling of grains is then passed onto DNA Tracing.

%%{init: {'theme': 'base', } }%% graph TD; subgraph Background Flattening A1([Load YAML Configuration]) --> A2([Load SPM]) A2 --> A3([Extract channel from SPM]) A3 --> A4([Initial Align]) A4 --> A5([Initial Tilt Removal]) A5 --> A6([Thresholding Otsu]) A6 --> A7([Mask Generation]) A7 --> A8([Masked Align]) A8 --> A9([Masked Tilt Removal]) A9 --> A10([Background Zeroing]) end subgraph Grain Finding A10 --> B1([Lower Thresholding]) B1 --> B2([Gaussian Filtering]) B2 --> B3([Tidy Edges]) B3 --> B4([Preliminary Statistics]) B4 --> B5([Size Thresholding]) B5 --> B6([Label Regions]) end subgraph Grain Statistics B6 --> C2([Calculate Points]) C2 --> C8([Height & Volume Statistics]) C2 --> C3([Calculate Edges]) C2 --> C4([Calculate Centroid]) C3 --> C5([Calculate Radius Statistics]) C3 --> C6([Convex Hull / Graham Scan]) C6 --> C7([Minimum Bounding Box Statistics]) end subgraph DNA Tracing B2 --> D1([More Analysis]) B5 --> D1 end style A1 fill:#648FFF,stroke:#000000 style A2 fill:#648FFF,stroke:#000000 style A3 fill:#648FFF,stroke:#000000 style A4 fill:#648FFF,stroke:#000000 style A5 fill:#648FFF,stroke:#000000 style A6 fill:#648FFF,stroke:#000000 style A7 fill:#648FFF,stroke:#000000 style A8 fill:#648FFF,stroke:#000000 style A9 fill:#648FFF,stroke:#000000 style A10 fill:#648FFF,stroke:#000000 style B1 fill:#DC267F,stroke:#000000 style B2 fill:#DC267F,stroke:#000000 style B3 fill:#DC267F,stroke:#000000 style B4 fill:#DC267F,stroke:#000000 style B5 fill:#DC267F,stroke:#000000 style B6 fill:#DC267F,stroke:#000000 style C2 fill:#FE6100,stroke:#000000 style C3 fill:#FE6100,stroke:#000000 style C4 fill:#FE6100,stroke:#000000 style C5 fill:#FE6100,stroke:#000000 style C6 fill:#FE6100,stroke:#000000 style C7 fill:#FE6100,stroke:#000000 style C8 fill:#FE6100,stroke:#000000 style D1 fill:#785EF0,stroke:#000000

DNA Tracing : Processing a single grain#

%%{init: {'theme': 'base', } }%% graph TD; subgraph dnaTrace A1(["get_numpy_arrays() | Load Numpy arrays to dictionary indexed by number"]) --> A2(["skimage.filters.gaussian() | Filter full image"]) A2 -- For each image --> A3(["get_disordered_trace() | extracts mask"]) A3 --> A4(["purge_obvious_crap() | Removes ites if len() < 10 (i.e. small objects) "]) A4 --> A5(["linear_or_circular on unordered traces() | linear or circular molecule"]) A5 --> A6(["get_ordered_traces() | Reorders points in the array?"]) A6 --> A7(["linear_or_circular() on ordered traces"]) A7 --> A8(["get_fitted_traces()"]) A8 --> A9(["get_splined_traces()"]) A9 --> A10(["measure_contour_length()"]) A10 --> A11(["measure_end_to_end_distance()"]) A11 --> A12(["report_basic_stats()"]) end subgraph "get_disordered_trace()" A3 --> B1(["ndimage.binary_dilation() | extracts mask"]) B1 --> B2(["scipy.ndimage.gaussian_filter molecule()"]) B2 --> B3(["getSkeleton()"]) B3 --> A4 end subgraph "getSkeleton()" B3 --> C1(["Skeletonize | to be replaced by get_skeleton()"]) C1 --> B3 end style A1 fill:#648FFF,stroke:#000000 style A2 fill:#648FFF,stroke:#000000 style A3 fill:#648FFF,stroke:#000000 style A4 fill:#648FFF,stroke:#000000 style A5 fill:#648FFF,stroke:#000000 style A6 fill:#648FFF,stroke:#000000 style A7 fill:#648FFF,stroke:#000000 style A8 fill:#648FFF,stroke:#000000 style A9 fill:#648FFF,stroke:#000000 style A10 fill:#648FFF,stroke:#000000 style A11 fill:#648FFF,stroke:#000000 style A12 fill:#648FFF,stroke:#000000 style B1 fill:#DC267F,stroke:#000000 style B2 fill:#DC267F,stroke:#000000 style B3 fill:#DC267F,stroke:#000000 style C1 fill:#FE6100,stroke:#000000