[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.
# 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
Run the damage branch (probably main too) on this file.
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
Checklist
mainbranch to check if the issue persists. Instructions on how to do this can be found here.topostats --core 1 process.topostats --log-level debug <command>.topostats --versionDescribe the bug
On the damage branch, with a particular image, (specifically
20251203_TAF_water_blank.0_00002.topostatsfound 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:
Include the configuration file
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