Skip to content

[bug]: (damage branch) nodestats : key error : 'avg_mask' #1369

Description

@SylviaWhittle

Checklist

  • Run using the main branch to check if the issue persists. Instructions on how to do this can be found here.
  • Find the offending file in the output. If processing halts, re-run analysis with topostats --core 1 process.
  • Describe the bug.
  • Include the configuration file.
  • Copy of the log-file from running with topostats --log-level debug <command>.
  • The exact command that failed. This is what you typed at the command line, including any options.
  • TopoStats version, this is reported by topostats --version
  • Operating System and Python Version

Describe the bug

On the damage branch, with a particular image, (specifically 20251203_TAF_water_blank.0_00002.topostats found in the damage project directory on the X drive (ask Tobi or Sylvia), can't post full path or image here), nodestats crashes.

Copy of the log-file from running with topostats --log-level debug <command>

here's the relevant part:

[Tue, 16 Jun 2026 12:35:27] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Disordered Tracing stage completed successfully.
[Tue, 16 Jun 2026 12:35:27] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Disordered trace plotting completed successfully.
[Tue, 16 Jun 2026 12:35:27] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : *** Nodestats ***
[Tue, 16 Jun 2026 12:35:27] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : There are 1 grains
[Tue, 16 Jun 2026 12:35:27] [ERROR   ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Nodestats for grain 0 failed. Please consider raising an issue on GitHub. Error: 
Traceback (most recent call last):
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 1764, in nodestats_image
    _, node_image_dict = nodestats.get_node_stats()
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 167, in get_node_stats
    self.analyse_nodes(max_branch_length=self.branch_pairing_length)
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 540, in analyse_nodes
    branch_image, avg_image = nodeStats.add_branches_to_labelled_image(
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 649, in add_branches_to_labelled_image
    avg_image[masked_image[branch_index]["avg_mask"] != 0] = i + 1
              ~~~~[Tue, 16 Jun 2026 12:35:27] [ERROR   ] [topostats] [nodestats.py] [1783] [20251203_TAF_water_blank.0_00002.spm] : Nodestats for grain 0 failed. Please consider raising an issue on GitHub. Error: 
Traceback (most recent call last):
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 1764, in nodestats_image
    _, node_image_dict = nodestats.get_node_stats()
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 167, in get_node_stats
    self.analyse_nodes(max_branch_length=self.branch_pairing_length)
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 540, in analyse_nodes
    branch_image, avg_image = nodeStats.add_branches_to_labelled_image(
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/sylvi/src/TopoStats/topostats/tracing/nodestats.py", line 649, in add_branches_to_labelled_image
    avg_image[masked_image[branch_index]["avg_mask"] != 0] = i + 1
              ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'avg_mask'
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'avg_mask'
[Tue, 16 Jun 2026 12:35:27] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : NodeStats stage completed successfully.
[Tue, 16 Jun 2026 12:35:28] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Nodestats plotting completed successfully.
[Tue, 16 Jun 2026 12:35:28] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : *** Ordered Tracing ***
[Tue, 16 Jun 2026 12:35:28] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Calculating Ordered Traces and Statistics for 1 grains...
[Tue, 16 Jun 2026 12:35:28] [INFO    ] [topostats] [20251203_TAF_water_blank.0_00002.spm] : Grain 1 present in NodeStats. Tracing via Nodestats.

Include the configuration file

# Config file generated 2026-04-22 13:38:04
# For more information on configuration and how to use it:
# https://afm-spm.github.io/TopoStats/main/configuration.html
base_dir: ../all_data # Directory in which to search for data files
output_dir: ./output # Directory to output results to
log_level: info # Verbosity of output. Options: warning, error, info, debug
cores: 1 # Number of CPU cores to utilise for processing multiple files simultaneously.
file_ext: .spm # File extension of the data files.
output_stats: full # Options : basic (image, grain), full (image, grain, molecule, branch)
loading:
  channel: Height Sensor # Channel to pull data from in the data files.
  extract: raw # Array to extract when loading .topostats files.
filter:
  run: true # Options : true, false
  row_alignment_quantile: 0.5 # lower values may improve flattening of larger features
  threshold_method: std_dev # Options : otsu, std_dev, absolute
  otsu_threshold_multiplier: 1.0
  threshold_std_dev:
    below: 10.0 # Threshold for data below the image background
    above: 1.0 # Threshold for data above the image background
  threshold_absolute:
    below: -1.0 # Threshold for data below the image background
    above: 1.0 # Threshold for data above the image background
  gaussian_size: 1.0121397464510862 # Gaussian blur intensity in px
  gaussian_mode: nearest # Mode for Gaussian blurring. Options : nearest, reflect, constant, mirror, wrap
  # Scar removal parameters. Be careful with editing these as making the algorithm too sensitive may
  # result in ruining legitimate data.
  remove_scars:
    run: false
    removal_iterations: 2 # Number of times to run scar removal.
    threshold_low: 0.250 # lower values make scar removal more sensitive
    threshold_high: 0.666 # lower values make scar removal more sensitive
    max_scar_width: 4 # Maximum thickness of scars in pixels.
    min_scar_length: 16 # Minimum length of scars in pixels.
grains:
  run: true # Options : true, false
  # Thresholding by height
  grain_crop_padding: 1 # Padding to apply to grains. Needs to be at least 1, more padding may help with unets.
  threshold_method: absolute # Options : std_dev, otsu, absolute, unet
  otsu_threshold_multiplier: 1.0
  threshold_std_dev:
    below: [10.0] # Thresholds for grains below the image background. List[float].
    above: [1.0] # Thresholds for grains above the image background. List[float].
  threshold_absolute:
    below: [-1000.0] # Thresholds for grains below the image background. List[float].
    above: [1.2] # Thresholds for grains above the image background. List[float].
  area_thresholds:
    above: [300, 300000000000] # above surface [Low, High] in nm^2 (also takes null)
    below: [null, null] # below surface [Low, High] in nm^2 (also takes null)
  remove_edge_intersecting_grains: true # Whether or not to remove grains that touch the image border
  endpoint_connection_config:
    run: true # Whether to run the endpoint connection process
    class_indices: [1] # List of class indices to process
    skeletonisation_holearea_min_max: [0, null] # Range (min, max) of a hole area in nm to refill in the smoothed masks.
    skeletonisation_mask_smoothing_dilation_iterations: 2 # Number of dilation iterations to use for grain smoothing.
    skeletonisation_mask_smoothing_gaussian_sigma: 2 # Gaussian smoothing parameter 'sigma' in pixels.
    skeletonisation_method: topostats # Options : zhang | lee | thin | topostats
    skeletonisation_height_bias: 0.6 # Percentage of lowest pixels to remove each skeletonisation iteration. 1 equates to zhang.
    endpoint_connection_distance_nm: 10.0 # Maximum distance in nm to connect endpoints.
    endpoint_connection_cost_map_height_maximum: 3.0 # Maximum height in nm to consider when building the cost map for endpoint connection. Should roughly be the maximum height of your sample.
    pruning_params:
      method: topostats # Method to clean branches of the skeleton. Options : topostats
      max_length: 10.0 # Maximum length in nm to remove a branch containing an endpoint.
      height_threshold: # The height to remove branches below.
      method_values: mid # The method to obtain a branch's height for pruning. Options : min | median | mid.
      method_outlier: abs # The method to prune branches based on height. Options : abs | mean_abs | iqr.
      only_height_prune_endpoints: False # Whether to restrict height-based pruning to skeleton segments containing an endpoint or not.
  unet_config:
    model_path: null # Path to a trained U-Net model
    upper_norm_bound: 5.0 # Upper bound for normalisation of input data. This should be slightly higher than the maximum desired / expected height of grains.
    lower_norm_bound: -1.0 # Lower bound for normalisation of input data. This should be slightly lower than the minimum desired / expected height of the background.
    remove_disconnected_grains: false # Whether to remove grains in the crop that don't touch the original grain mask.
    confidence: 0.5 # Confidence threshold for the UNet model. Smaller is more generous, larger is more strict.
  vetting:
    whole_grain_size_thresholds: null # Size thresholds for whole grains in nanometres squared, ie all classes combined. Tuple of 2 floats, ie [low, high] eg [100, 1000] for grains to be between 100 and 1000 nm^2. Can use None to not set an upper/lower bound.
    class_conversion_size_thresholds: null # Class conversion size thresholds, list of tuples of 3 integers and 2 integers, ie list[tuple[tuple[int, int, int], tuple[int, int]]] eg [[[1, 2, 3], [5, 10]]] for each region of class 1 to convert to 2 if smaller than 5 nm^2 and to class 3 if larger than 10 nm^2.
    class_region_number_thresholds: null # Class region number thresholds, list of lists, ie [[class, low, high],] eg [[1, 2, 4], [2, 1, 1]] for class 1 to have 2-4 regions and class 2 to have 1 region. Can use None to not set an upper/lower bound.
    class_size_thresholds: null # Class size thresholds (nm^2), list of tuples of 3 integers, ie [[class, low, high],] eg [[1, 100, 1000], [2, 1000, None]] for class 1 to have 100-1000 nm^2 and class 2 to have 1000-any nm^2. Can use None to not set an upper/lower bound.
    nearby_conversion_classes_to_convert: null # Class conversion for nearby regions, list of tuples of two-integer tuples, eg [[[1, 2], [3, 4]]] to convert class 1 to 2 and 3 to 4 for small touching regions
    class_touching_threshold: 5 # Number of dilation steps to use for detecting touching regions
    keep_largest_labelled_regions_classes: null # Classes to keep the only largest regions for, list of integers eg [1, 2] to keep only the largest regions of class 1 and 2
    class_connection_point_thresholds: null # Class connection point thresholds, [[[class_1, class_2], [min, max]]] eg [[[1, 2], [1, 1]]] for class 1 to have 1 connection point with class 2
  classes_to_merge: null # Classes to merge into a single combined class. List of lists, eg [[1, 2]] to merge classes 1 and 2. New classes will be appended to the tensor.
grainstats:
  run: true # Options : true, false
  edge_detection_method: binary_erosion # Options: canny, binary erosion. Do not change this unless you are sure of what this will do.
  extract_height_profile: true # Extract height profiles along maximum feret of molecules
  class_names: ["DNA", "Protein"] # The names corresponding to each class of a object identified, please specify merged classes after.
disordered_tracing:
  run: true # Options : true, false
  class_index: 1 # The class index to trace. This is the class index of the grains.
  min_skeleton_size: 10 # Minimum number of pixels in a skeleton for it to be retained.
  mask_smoothing_params:
    gaussian_sigma: 2 # Gaussian smoothing parameter 'sigma' in pixels.
    dilation_iterations: 2 # Number of dilation iterations to use for grain smoothing.
    holearea_min_max: [0, null] # Range (min, max) of a hole area in nm to refill in the smoothed masks.
  skeletonisation_params:
    method: topostats # Options : zhang | lee | thin | topostats
    height_bias: 0.6 # Percentage of lowest pixels to remove each skeletonisation iteration. 1 equates to zhang.
  pruning_params:
    method: topostats # Method to clean branches of the skeleton. Options : topostats
    max_length: 10.0 # Maximum length in nm to remove a branch containing an endpoint.
    height_threshold: # The height to remove branches below.
    method_values: mid # The method to obtain a branch's height for pruning. Options : min | median | mid.
    method_outlier: abs # The method to prune branches based on height. Options : abs | mean_abs | iqr.
    only_height_prune_endpoints: False # Whether to restrict height-based pruning to skeleton segments containing an endpoint or not.
close_strand_correction:
  run: true
  true_peak_threshold_median_multiplier: 1.1  # Minimum height in nm required for a crossing to be considered a true crossing.
  branch_explore_distance_nm: 2.5  # Maximum distance in nm to explore along a branch from a node for creating
  cost_image_exponent: 4.0  # Exponent to apply to the cost image to increase the cost of using lower pixels
  cost_image_base: 0.01  # base cost to prevent zero cost pixels, just in case
  crossing_correction_strand_minimum_height_nm: 1.0  # minimum height for a strand to be used for crossing correction
nodestats:
  run: true # Options : true, false
  node_joining_length: 7.0 # The distance in nanometres over which to join nearby crossing points.
  node_extend_dist: 14.0 # The distance in nanometres over which to join nearby odd-branched nodes.
  branch_pairing_length: 20.0 # The length in nanometres from the crossing point to pair and trace, obtaining FWHM's.
  pair_odd_branches: false # Whether to try and pair odd-branched nodes. Options: true and false.
ordered_tracing:
  run: true
  ordering_method: nodestats # The method of ordering the disordered traces. Options : nodestats | original
splining:
  run: true # Options : true, false
  method: "rolling_window" # Options : "spline", "rolling_window"
  rolling_window_size: 5.0e-9 # size in nm of the rolling window.
  rolling_window_resampling: true # Whether to resample the trace or not.
  rolling_window_resample_regular_spatial_interval: 0.5e-9 # The spatial interval to resample the trace to in nm.
  spline_step_size: 7.0e-9 # The sampling rate of the spline in metres.
  spline_linear_smoothing: 5.0 # The amount of smoothing to apply to linear features.
  spline_circular_smoothing: 5.0 # The amount of smoothing to apply to circular features.
  spline_degree: 3 # The polynomial degree of the spline.
curvature:
  run: true # Options : true, false
  smoothing_method: "gaussian" # Options : "gaussian", "savitzky_golay"
  smoothing_gaussian_sigma_nm: 1.0 # The sigma of the Gaussian smoothing kernel in nm.
  smoothing_savgol_window_length_nm: 10.0 # The window length of the Savitzky-Golay smoothing kernel in nm.
  smoothing_savgol_polyorder: 2 # The polynomial order of the Savitzky-Golay smoothing kernel.
  curvature_turn_minimum_delay_nm: 20.0 # The minimum distance in nm before re-assessing if in a turn or not.
  curvature_turn_threshold_iqr_multiplier: 1.5 # The multiplier for the IQR for determining if in a turn or not.
plotting:
  run: true # Options : true, false
  style: topostats.mplstyle # Options : topostats.mplstyle or path to a matplotlibrc params file
  savefig_format: null # Options : null, png, svg or pdf. tif is also available although no metadata will be saved. (defaults to png) See https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html
  savefig_dpi: 400 # Options : null (defaults to the value in topostats/plotting_dictionary.yaml), see https://afm-spm.github.io/TopoStats/main/configuration.html#further-customisation and https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html
  pixel_interpolation: null # Options : https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html
  grain_crop_plot_size_nm: -1 # Size in nm of the square cropped grain images if using the grains image set. If -1, will use the grain's default bounding box size.
  image_set: # Options : all, core, filters, grains, grain_crops, disordered_tracing, nodestats, ordered_tracing, splining. Uncomment to include
    # - all
    - core
    # - filters
    # - grains
    # - grain_crops
    # - disordered_tracing
    - close_strand_correction
    # - nodestats
    # - ordered_tracing
    # - splining
    # - curvature
  zrange: [-3, 4] # low and high height range for core images (can take [null, null]). low <= high
  colorbar: true # Options : true, false
  trace_linewidth: 1.0 # Linewidth for spline and cuvature traces.
  axes: true # Options : true, false (due to off being a bool when parsed)
  num_ticks: [null, null] # Number of ticks to have along the x and y axes. Options : null (auto) or integer > 1
  cmap: null # Colormap/colourmap to use (default is 'nanoscope' which is used if null, other options are 'afmhot', 'viridis' etc.)
  mask_cmap: blue_purple_green # Options : blu, jet_r and any in matplotlib
  histogram_log_axis: false # Options : true, false
  number_grains: true # Add grain numbers next to each grain mask in images with mask overlays. Options : true, false
summary_stats:
  run: false # Whether to make summary plots for output data
  config: null

To Reproduce

Run the damage branch (probably main too) on this file.

TopoStats Version

Git main branch

Python Version

3.11

Operating System

MacOS M1/M2 (post-2021)

Python Packages

absl-py==2.2.2
AFMReader @ git+https://github.com/AFM-SPM/AFMReader@7869b5be94ebf9febf20d0121a2828f4202f087c
annotated-types==0.7.0
anyio==4.12.1
appnope==0.1.4
argon2-cffi==25.1.0
argon2-cffi-bindings==25.1.0
arrow==1.4.0
art==6.5
astroid==3.3.10
asttokens==3.0.0
astunparse==1.6.3
async-lru==2.3.0
attrs==26.1.0
babel==2.18.0
backrefs==6.2
beautifulsoup4==4.14.3
biopython==1.85
black==25.1.0
bleach==6.3.0
certifi==2025.4.26
cffi==2.0.0
cfgv==3.4.0
charset-normalizer==3.4.2
cheap_repr==0.5.2
click==8.2.1
cmapy==0.6.6
colorama==0.4.6
comm==0.2.2
contourpy==1.3.2
coverage==7.8.2
cycler==0.12.1
debugpy==1.8.14
decorator==5.2.1
defusedxml==0.7.1
dill==0.4.0
distlib==0.3.9
docstring_parser==0.16
docutils==0.22.4
EditorConfig==0.17.1
et_xmlfile==2.0.0
execnet==2.1.1
executing==2.2.0
fastjsonschema==2.21.2
filelock==3.18.0
filetype==1.2.0
flatbuffers==25.2.10
fonttools==4.58.0
fqdn==1.5.1
gast==0.6.0
ghp-import==2.1.0
google-pasta==0.2.0
gprof2dot==2025.4.14
griffelib==2.0.2
grpcio==1.71.0
h11==0.16.0
h5py==3.13.0
hmmlearn==0.3.3
httpcore==1.0.9
httpx==0.28.1
icdiff==2.0.7
identify==2.6.12
idna==3.10
igor==0.3
igor2==0.5.12
imageio==2.37.0
iniconfig==2.1.0
ipykernel==6.29.5
ipython==8.36.0
ipython-genutils==0.2.0
ipywidgets==8.1.8
isoduration==20.11.0
isort==6.0.1
itsdangerous==2.2.0
jedi==0.19.2
Jinja2==3.1.6
joblib==1.5.0
jsbeautifier==1.15.4
json5==0.14.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
jupyter-events==0.12.1
jupyter-highlight-selected-word==0.2.0
jupyter-lsp==2.3.1
jupyter_client==8.6.3
jupyter_contrib_core==0.4.2
jupyter_contrib_nbextensions==0.7.0
jupyter_core==5.8.1
jupyter_nbextensions_configurator==0.6.4
jupyter_server==2.17.0
jupyter_server_terminals==0.5.4
jupyterlab==4.5.6
jupyterlab_pygments==0.3.0
jupyterlab_server==2.28.0
jupyterlab_widgets==3.0.16
jupyterthemes==0.20.0
keras==3.10.0
kiwisolver==1.4.8
lark==1.3.1
lazy_loader==0.4
lesscpy==0.15.1
Levenshtein==0.27.3
libclang==18.1.1
line_profiler==5.0.2
llvmlite==0.44.0
loguru==0.7.3
loro==1.10.3
lxml==6.1.0
magicgui==0.10.0
marimo==0.21.1
Markdown==3.8
markdown-it-py==3.0.0
MarkupSafe==3.0.2
matplotlib==3.9.4
matplotlib-inline==0.1.7
mccabe==0.7.0
mdurl==0.1.2
mergedeep==1.3.4
mike==2.2.0
mistune==3.2.0
mkdocs==1.6.1
mkdocs-autorefs==1.4.4
mkdocs-get-deps==0.2.2
mkdocs-material==9.7.6
mkdocs-material-extensions==1.3.1
mkdocs-mermaid2-plugin==1.2.3
mkdocstrings==1.0.4
mkdocstrings-python==2.0.3
ml_dtypes==0.5.1
msgspec==0.20.0
mypy_extensions==1.1.0
namex==0.0.9
narwhals==2.18.0
nbclient==0.10.4
nbconvert==7.17.1
nbformat==5.10.4
nest-asyncio==1.6.0
networkx==3.4.2
nodeenv==1.9.1
notebook==7.5.5
notebook_shim==0.2.4
numba==0.61.2
numpy==2.0.2
numpyencoder @ git+https://github.com/AFM-SPM/numpyencoder@cd84c7cbb7e59386ed7c0a7e03e03c4134b2b84c
opencv-python==4.12.0.88
openpyxl==3.1.5
opt_einsum==3.4.0
optree==0.15.0
overrides==7.7.0
packaging==25.0
paginate==0.5.7
pandas==2.2.3
pandas_flavor==0.7.0
pandocfilters==1.5.1
parso==0.8.4
pathspec==0.12.1
patsy==1.0.1
pexpect==4.9.0
pillow==11.1.0
pingouin==0.5.5
platformdirs==4.3.8
pluggy==1.6.0
ply==3.11
pprintpp==0.4.0
pre_commit==4.2.0
prometheus_client==0.25.0
prompt_toolkit==3.0.51
protobuf==5.29.4
psutil==5.9.8
psygnal==0.13.0
ptyprocess==0.7.0
pure_eval==0.2.3
pyconify==0.2.1
pycparser==3.0
pydantic==2.12.5
pydantic_core==2.41.5
pyFFTW==0.15.0
pyfiglet==1.0.3
Pygments==2.19.1
pylint==3.3.7
pymdown-extensions==10.21.2
pyparsing==3.2.3
-e git+https://github.com/scholi/pySPM.git@b0f62f6c12c397875805a88c4faa5c9bd8ff5693#egg=pyspm
pytest==8.3.5
pytest-cov==6.1.1
pytest-durations==1.5.2
pytest-github-actions-annotate-failures==0.3.0
pytest-icdiff==0.9
pytest-mpl==0.17.0
pytest-profiling==1.8.1
pytest-regtest==2.3.1
pytest-testmon==2.1.3
pytest-xdist==3.7.0
python-dateutil==2.9.0.post0
python-json-logger==4.1.0
pytz==2025.2
pyupgrade==3.20.0
PyYAML==6.0.2
pyyaml_env_tag==1.1
pyzmq==26.4.0
QtPy==2.4.3
RapidFuzz==3.14.3
referencing==0.37.0
requests==2.32.3
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rfc3987-syntax==1.1.0
rich==14.0.0
rpds-py==0.30.0
ruamel.yaml==0.18.10
ruamel.yaml.clib==0.2.12
schema==0.7.7
scikit-image==0.25.2
scikit-learn==1.6.1
scipy==1.15.3
seaborn==0.13.2
Send2Trash==2.1.0
six==1.17.0
skan==0.12.2
snoop==0.6.0
soupsieve==2.8.3
stack-data==0.6.3
starlette==0.52.1
statsmodels==0.14.5
superqt==0.7.3
syrupy==5.1.0
tabulate==0.9.0
tensorboard==2.19.0
tensorboard-data-server==0.7.2
tensorflow==2.19.0
tensorflow-io-gcs-filesystem==0.37.1
termcolor==3.1.0
terminado==0.18.1
threadpoolctl==3.6.0
tifffile==2025.5.21
tinycss2==1.4.0
tokenize_rt==6.2.0
tomlkit==0.13.2
toolz==1.0.0
topoly==1.1.0
-e git+ssh://git@github.com/AFM-SPM/TopoStats.git@9158227663427669d075fdaf5bf55ba07d9506ec#egg=topostats
tornado==6.5.1
tqdm==4.67.1
traitlets==5.14.3
ty==0.0.32
typing-inspection==0.4.2
typing_extensions==4.15.0
tzdata==2025.2
uri-template==1.3.0
urllib3==2.4.0
uvicorn==0.42.0
verspec==0.1.0
virtualenv==20.31.2
watchdog==6.0.0
wcwidth==0.2.13
webcolors==25.10.0
webencodings==0.5.1
websocket-client==1.9.0
websockets==16.0
Werkzeug==3.1.3
widgetsnbextension==4.0.15
wrapt==1.17.2
xarray==2025.8.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions