changeset 0:b995568c667e draft default tip

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/main/tools/pcdl/ commit 7c74921b41bd7ab639e5a3f8b54e407f79ed8f16
author iuc
date Mon, 04 Aug 2025 19:00:39 +0000
parents
children
files README.txt pcdl_get_conc_df.xml pcdl_macros.xml test-data/PhysiCell_settings.xml test-data/final.svg test-data/final.xml test-data/final_attached_cells_graph.txt test-data/final_cell_neighbor_graph.txt test-data/final_cells.mat test-data/final_microenvironment0.mat test-data/final_spring_attached_cells_graph.txt test-data/initial.svg test-data/initial.xml test-data/initial_attached_cells_graph.txt test-data/initial_cell_neighbor_graph.txt test-data/initial_cells.mat test-data/initial_mesh0.mat test-data/initial_microenvironment0.mat test-data/initial_spring_attached_cells_graph.txt test-data/legend.svg test-data/output00000000.xml test-data/output00000000_attached_cells_graph.txt test-data/output00000000_cell_neighbor_graph.txt test-data/output00000000_cells.mat test-data/output00000000_microenvironment0.mat test-data/output00000000_oxygen.jpeg test-data/output00000000_spring_attached_cells_graph.txt test-data/output00000001.xml test-data/output00000001_attached_cells_graph.txt test-data/output00000001_cell_neighbor_graph.txt test-data/output00000001_cells.mat test-data/output00000001_microenvironment0.mat test-data/output00000001_oxygen.jpeg test-data/output00000001_spring_attached_cells_graph.txt test-data/timeseries_cell_attribute_minmax.json
diffstat 35 files changed, 3499 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,23 @@
+pcdl
+====
+
+Galaxy wrapper for the pcdl PhysiCell Data Loader command line commands.
+Pcdl is paramount for downstream analysis from PhysiCell output.
+As such, the pcdl Galaxy tools are useful if you work with the interactive
+PhysiCell Studio Galaxy tool.
++ https://usegalaxy.eu/?tool_id=interactive_tool_pcstudio&version=latest
+
+You will have to unzip the PhysiCell output folder before you can run
+pcdl Galaxy tools on it.
++ https://usegalaxy.eu/?tool_id=toolshed.g2.bx.psu.edu%2Frepos%2Fimgteam%2Funzip%2Funzip%2F6.0%2Bgalaxy0&version=latest
++ https://usegalaxy.org/?tool_id=toolshed.g2.bx.psu.edu%2Frepos%2Frheiland%2Fphysicell_studio%2Finteractive_tool_pcstudio%2F0.3&version=latest
+
+More information about PhysiCell, PhysiCell Studio, and PhysiCell Data Loader
+can be found here:
++ https://physicell.org/index.html
++ https://physicell-studio.readthedocs.io/en/latest/index.html
++ https://github.com/elmbeech/physicelldataloader
+
+Date: 2025-06-06
+License: BSD-3-Clause
+Author: Elmar Bucher
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pcdl_get_conc_df.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,93 @@
+<tool id="pcdl_get_conc_df" name="pcdl_get_conc_df" version="3.0.1+galaxy0" profile="21.05">
+    <macros>
+        <import>pcdl_macros.xml</import>
+    </macros>
+    <requirements>
+        <expand macro="requirement"/>
+    </requirements>
+    <command><![CDATA[
+        #import re
+        mkdir output_pc &&
+        #for $file in $path:
+            #set $filename = re.sub('[^\w\-\.\s]', '_', str($file.element_identifier))
+            ln -s '$file' output_pc/$filename &&
+        #end for
+
+        pcdl_get_conc_df 'output_pc' $entropy
+        --verbose $verbose
+        --drop $drop
+        --keep $keep
+        --collapse $collapse
+    ]]></command>
+    <inputs>
+        <section name="essential" title="essential:" expanded="true">
+            <expand macro="path"/>
+            <expand macro="entropy"/>
+            <expand macro="drop"/>
+            <expand macro="keep"/>
+            <expand macro="collapse"/>
+        </section>
+        <section name="advanced" title="advanced:" expanded="false">
+            <expand macro="verbose"/>
+        </section>
+    </inputs>
+    <outputs>
+        <collection name="conc_csv" type="list">
+            <discover_datasets pattern="(?P&lt;designation&gt;.+_conc)\.csv" format="csv" directory="output_pc" visible="false"/>
+        </collection>
+    </outputs>
+    <tests>
+        <test expect_num_outputs="1">
+            <section name="essential">
+                <param name="path">
+                    <expand macro="output"/>
+                </param>
+                <param name="collapse" value="true"/>
+            </section>
+            <section name="advanced">
+                <param name="verbose" value="true"/>
+            </section>
+            <output_collection name="conc_csv" count="1">
+                <element name="timeseries_conc">
+                    <assert_contents>
+                        <has_text text="index,voxel_i,voxel_j,voxel_k,mesh_center_m,mesh_center_n,mesh_center_p"/>
+                        <has_text text=",time,runtime,xmlfile"/>
+                    </assert_contents>
+                </element>
+            </output_collection>
+        </test>
+        <test expect_num_outputs="1">
+            <section name="essential">
+                <param name="path">
+                    <expand macro="output"/>
+                </param>
+                <param name="collapse" value="false"/>
+            </section>
+            <section name="advanced">
+                <param name="verbose" value="false"/>
+            </section>
+            <output_collection name="conc_csv" count="2">
+                <element name="output00000000_conc">
+                    <assert_contents>
+                        <has_text text="index,voxel_i,voxel_j,voxel_k,mesh_center_m,mesh_center_n,mesh_center_p,"/>
+                        <has_text text=",time,runtime,xmlfile"/>
+                    </assert_contents>
+                </element>
+                <element name="output00000001_conc">
+                    <assert_contents>
+                        <has_text text="index,voxel_i,voxel_j,voxel_k,mesh_center_m,mesh_center_n,mesh_center_p,"/>
+                        <has_text text=",time,runtime,xmlfile"/>
+                    </assert_contents>
+                </element>
+            </output_collection>
+        </test>
+    </tests>
+    <help><![CDATA[
+This function extracts dataframes with concentration values for all chemical species in all voxels and saves them as csv files. Additionally, this dataframe lists voxel and mesh center coordinates.
+
+Homepage: https://github.com/elmbeech/physicelldataloader
+    ]]></help>
+    <citations>
+        <expand macro="citation"/>
+    </citations>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pcdl_macros.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,444 @@
+<macros>
+    <!-- requirements -->
+    <xml name="requirement">
+        <requirement type="package" version="3.3.8">pcdl</requirement>
+    </xml>
+    <!-- input -->
+    <xml name="aggregate_num">
+        <param argument="--aggregate_num" label="aggregation function for focus numeric data" type="select" display="radio" help="">
+            <option value="max">max</option>
+            <option value="mean" selected="true">mean</option>
+            <option value="median">median</option>
+            <option value="min">min</option>
+            <option value="std">std</option>
+            <option value="var">var</option>
+        </param>
+    </xml>
+    <xml name="allvalues">
+        <param argument="--allvalues" label="all values" type="boolean" truevalue="true" falsevalue="false" checked="false" help="For numeric data, should only the min and max values or all values be returned?"/>
+    </xml>
+    <xml name="alpha">
+        <param argument="--alpha" label="alpha channel" type="float" value="1.0" optional="false" help="Alpha channel transparency value between 1 (not transparent at all) and 0 (totally transparent)."/>
+    </xml>
+    <xml name="attribute">
+        <param name="attribute" label="attribute" type="text" value="cell_type" optional="false" help="Listing of mcds.get_cell_df dataframe column names, used for cell attributes."/>
+    </xml>
+    <xml name="cmap">
+        <param argument="--cmap" label="color map" type="select" help="Matplotlib colormap from https://matplotlib.org/stable/tutorials/colors/colormaps.html .">
+            <!-- perceptually uniform sequential -->
+            <option value="viridis" selected="true">viridis</option>
+            <option value="viridis_r">viridis reversed</option>
+            <option value="plasma">plasma</option>
+            <option value="plasma_r">plasma reversed</option>
+            <option value="inferno">inferno</option>
+            <option value="inferno_r">inferno reversed</option>
+            <option value="magam">magma</option>
+            <option value="magam_r">magma reversed</option>
+            <option value="cividis">cividis</option>
+            <option value="cividis_r">cividis reversed</option>
+            <!-- sequential -->
+            <option value="Greys">Greys</option>
+            <option value="Greys_r">Greys reversed</option>
+            <option value="Purples">Purples</option>
+            <option value="Purples_r">Purples reversed</option>
+            <option value="Blues">Blues</option>
+            <option value="Blues_r">Blues reversed</option>
+            <option value="Greens">Greens</option>
+            <option value="Greens_r">Greens reversed</option>
+            <option value="Oranges">Oranges</option>
+            <option value="Oranges_r">Oranges reversed</option>
+            <option value="Reds">Reds</option>
+            <option value="Reds_r">Reds reversed</option>
+            <option value="YlOrBr">YlOrBr</option>
+            <option value="YlOrBr_r">YlOrBr reversed</option>
+            <option value="YlOrRd">YlOrRd</option>
+            <option value="YlOrRd_r">YlOrRd reversed</option>
+            <option value="OrRd">OrRd</option>
+            <option value="OrRd_r">OrRd reversed</option>
+            <option value="PuRd">PuRd</option>
+            <option value="PuRd_r">PuRd reversed</option>
+            <option value="RdPu">RdPu</option>
+            <option value="RdPu_r">RdPu reversed</option>
+            <option value="BuPu">BuPu</option>
+            <option value="BuPu_r">BuPu reversed</option>
+            <option value="GnBu">GnBu</option>
+            <option value="GnBu_r">GnBu reversed</option>
+            <option value="PuBu">PuBu</option>
+            <option value="PuBu_r">PuBu reversed</option>
+            <option value="YlGnBu">YlGnBu</option>
+            <option value="YlGnBu_r">YlGnBu reversed</option>
+            <option value="PuBuGn">PuBuGn</option>
+            <option value="PuBuGn_r">PuBuGn reversed</option>
+            <option value="BuGn">BuGn</option>
+            <option value="BuGn_r">BuGn reversed</option>
+            <option value="YlGn">YlGn</option>
+            <option value="YlGn_r">YlGn reversed</option>
+            <!-- sequential 2 -->
+            <option value="binary">binary</option>
+            <option value="binary_r">binary reversed</option>
+            <option value="gist_yarg">gist_yarg</option>
+            <option value="gist_yarg_r">gist_yarg reversed</option>
+            <option value="gist_gray">gist_gray</option>
+            <option value="gist_gray_r">gist_gray reversed</option>
+            <option value="gray">gray</option>
+            <option value="gray_r">gray reversed</option>
+            <option value="bone">bone</option>
+            <option value="bone_r">bone reversed</option>
+            <option value="pink">pink</option>
+            <option value="pink_r">pink reversed</option>
+            <option value="spring">spring</option>
+            <option value="spring_r">spring reversed</option>
+            <option value="summer">summer</option>
+            <option value="summer_r">summer reversed</option>
+            <option value="autumn">autumn</option>
+            <option value="autumn_r">autumn reversed</option>
+            <option value="winter">winter</option>
+            <option value="winter_r">winter reversed</option>
+            <option value="cool">cool</option>
+            <option value="cool_r">cool reversed</option>
+            <option value="Wistia">Wistia</option>
+            <option value="Wistia_r">Wistia reversed</option>
+            <option value="hot">hot</option>
+            <option value="hot_r">hot reversed</option>
+            <option value="afmhot">afmhot</option>
+            <option value="afmhot_r">afmhot reversed</option>
+            <option value="gist_heat">gist_heat</option>
+            <option value="gist_heat_r">gist_heat reversed</option>
+            <option value="copper">copper</option>
+            <option value="copper_r">copper reversed</option>
+            <!-- diverging -->
+            <option value="PiYG">PiYG</option>
+            <option value="PiYG_r">PiYG reversed</option>
+            <option value="PRGn">PRGn</option>
+            <option value="PRGn_r">PRGn reversed</option>
+            <option value="BrBG">BrBG</option>
+            <option value="BrBG_r">BrBG reversed</option>
+            <option value="PuOr">PuOr</option>
+            <option value="PuOr_r">PuOr reversed</option>
+            <option value="RdGy">RdGy</option>
+            <option value="RdGy_r">RdGy reversed</option>
+            <option value="RdBu">RdBu</option>
+            <option value="RdBu_r">RdBu reversed</option>
+            <option value="RdYlBu">RdYlBu</option>
+            <option value="RdYlBu_r">RdYlBu reversed</option>
+            <option value="RdYlGn">RdYlGn</option>
+            <option value="RdYlGn_r">RdYlGn reversed</option>
+            <option value="Spectral">Spectral</option>
+            <option value="Spectral_r">Spectral reversed</option>
+            <option value="coolwarm">coolwarm</option>
+            <option value="coolwarm_r">coolwarm reversed</option>
+            <option value="bwr">bwr</option>
+            <option value="bwr_r">bwr reversed</option>
+            <option value="seismic">seismic</option>
+            <option value="seismic_r">seismic reversed</option>
+            <option value="berlin">berlin</option>
+            <option value="berlin_r">berlin reversed</option>
+            <option value="managua">managua</option>
+            <option value="managua_r">managua reversed</option>
+            <option value="vanimo">vanimo</option>
+            <option value="vanimo_r">vanimo reversed</option>
+            <!-- cyclic -->
+            <option value="twilight">twilight</option>
+            <option value="twilight_r">twilight reversed</option>
+            <option value="twilight_shifted">twilight_shifted</option>
+            <option value="twilight_shifted_r">twilight_shifted reversed</option>
+            <option value="hsv">hsv</option>
+            <option value="hsv_r">hsv reversed</option>
+            <!-- qualitative -->
+            <option value="Pastel1">Pastel1</option>
+            <option value="Pastel2">Pastel2</option>
+            <option value="Paired">Paired</option>
+            <option value="Accent">Accent</option>
+            <option value="Accent_r">Accent reversed</option>
+            <option value="Dark2">Dark2</option>
+            <option value="Dark2_r">Dark2 reversed</option>
+            <option value="Set1">Set1</option>
+            <option value="Set1_r">Set1 reversed</option>
+            <option value="Set2">Set2</option>
+            <option value="Set2_r">Set2 reversed</option>
+            <option value="Set3">Set3</option>
+            <option value="Set3_r">Set3 reversed</option>
+            <option value="tab10">tab10</option>
+            <option value="tab10_r">tab10 reversed</option>
+            <option value="tab20">tab20</option>
+            <option value="tab20_r">tab20 reversed</option>
+            <option value="tab20b">tab20b</option>
+            <option value="tab20b_r">tab20b reversed</option>
+            <option value="tab20c">tab20c</option>
+            <option value="tab20c_r">tab20c reversed</option>
+            <!-- miscellaneous -->
+            <option value="flag">flag</option>
+            <option value="flag_r">flag reversed</option>
+            <option value="prism">prism</option>
+            <option value="prism_r">prism reversed</option>
+            <option value="ocean">ocean</option>
+            <option value="ocean_r">ocean reversed</option>
+            <option value="gist_earth">gist_earth</option>
+            <option value="gist_earth_r">gist_earth reversed</option>
+            <option value="terrain">terrain</option>
+            <option value="terrain_r">terrain reversed</option>
+            <option value="gist_stern">gist_stern</option>
+            <option value="gist_stern_r">gist_stern reversed</option>
+            <option value="gnuplot">gnuplot</option>
+            <option value="gnuplot_r">gnuplot reversed</option>
+            <option value="gnuplot2">gnuplot2</option>
+            <option value="gnuplot2_r">gnuplot2 reversed</option>
+            <option value="CMRmap">CMRmap</option>
+            <option value="CMRmap_r">CMRmap reversed</option>
+            <option value="cubehelix">cubehelix</option>
+            <option value="cubehelix_r">cubehelix reversed</option>
+            <option value="brg">brg</option>
+            <option value="brg_r">brg reversed</option>
+            <option value="gist_rainbow">gist_rainbow</option>
+            <option value="gist_rainbow_r">gist_rainbow reversed</option>
+            <option value="rainbow">rainbow</option>
+            <option value="rainbow_r">rainbow reversed</option>
+            <option value="jet">jet</option>
+            <option value="jet_r">jet reversed</option>
+            <option value="turbo">turbo</option>
+            <option value="turbo_r">turbo reverse</option>
+            <option value="gist_ncar">gist_ncar</option>
+            <option value="gist_ncar_r">gist_ncar reversed</option>
+        </param>
+    </xml>
+    <xml name="collapse">
+        <param argument="--collapse" label="collapse" type="boolean" truevalue="true" falsevalue="false" checked="true" help="Should all mcds time steps from the time series be collapsed into one big file, or a many files, one file for each time step?"/>
+    </xml>
+    <xml name="color">
+        <param argument="--color" label="color" type="text" value="none" optional="false" help="Listing of color strings referred to by name, RGB or RGBA code."/>
+    </xml>
+    <xml name="custom_data_type">
+        <param argument="--custom_data_type" label="custom data type" type="text" value="" optional="true" help="Parameter to specify custom_data variable types other than float (namely: int, bool, str) like this var:dtype myint:int mybool:bool mystr:str. Downstream float and int will be handled as numeric, bool as Boolean, and str as categorical data."/>
+    </xml>
+    <xml name="drop">
+        <param argument="--drop" label="drop" type="text" value="" optional="true" help="Set of column labels (pcdl_get_cell_attribute_list, pcdl_get_substrate_list) to be dropped. Don't worry: essential columns like ID, coordinates and time will never be dropped. Attention: when the keep parameter is given, then the drop parameter has to be an empty string!"/>
+    </xml>
+    <xml name="edge_attribute">
+        <param argument="--edge_attribute" label="edge attribute" type="boolean" truevalue="true" falsevalue="false" checked="true" help="Specifies if the spatial Euclidean distance is used for edge attribute, to generate a weighted graph."/>
+    </xml>
+    <xml name="entropy">
+        <param name="entropy" label="values" type="integer" value="1" optional="false" help="Minimal number of values a variable has to have in any of the mcds time steps to be outputted. Variables that have only 1 state carry no information. None is a state too."/>
+    </xml>
+    <xml name="ext">
+        <param argument="--ext" label="file extension" type="select" display="radio" help="Output image format. Possible formats are jpeg, png, and tiff.">
+            <option value="jpeg" selected="true">jpeg</option>
+            <!--
+        <option value="png">png</option>
+        <option value="tiff">tiff</option>
+        -->
+        </param>
+    </xml>
+    <xml name="extrema">
+        <param argument="--extrema" label="extrem values" type="text" value="none" optional="false" help="Two floats separated by a space. None takes min and max from data.">
+            <validator type="regex" message="None or two float values separated by a space!">^[enoENO0-9-. ]*$</validator>
+        </param>
+    </xml>
+    <xml name="figbgcolor">
+        <param argument="--figbgcolor" label="figure background color" type="text" value="none" optional="false" help="Figure background color. None is transparent (png) or white (jpeg, tiff)."/>
+    </xml>
+    <xml name="figsizepx_x">
+        <param name="figsizepx_x" label="figure size x-axis in pixel" type="integer" value="640" optional="false" help="Size of the figure in pixels. The given x and y will be rounded to the nearest even number, to be able to generate movies from the images. (--figsizepx)"/>
+    </xml>
+    <xml name="figsizepx_y">
+        <param name="figsizepx_y" label="figure size y-axis in pixel" type="integer" value="480" optional="false" help="Size of the figure in pixels. The given x and y will be rounded to the nearest even number, to be able to generate movies from the images. (--figsizepx)"/>
+    </xml>
+    <xml name="fill">
+        <param argument="--fill" label="fill" type="boolean" truevalue="true" falsevalue="false" checked="true" help="True generates a matplotlib contourf plot. False generates a matplotlib contour plot."/>
+    </xml>
+    <xml name="focus_cell">
+        <param name="focus_cell" label="focus" type="text" value="cell_type" optional="false" help="Column name from the pcdl_get_cell_attribute_list listing."/>
+    </xml>
+    <xml name="focus_subs">
+        <param name="focus_subs" label="focus" type="text" optional="false" help="Substrate from the pcdl_get_substrate_list listing."/>
+    </xml>
+    <xml name="focus_cat">
+        <param name="focus_cat" label="focus categorical data" type="text" value="none" optional="false" help="Categorical or boolean data column within dataframe specified under frame (pcdl_get_cell_attribute_list or pcdl_get_substrate_list). None is total, which is all agents or voxels, no categories."/>
+    </xml>
+    <xml name="focus_num">
+        <param name="focus_num" label="focus numerical data" type="text" value="none" optional="false" help="Numerical data column within dataframe specified under frame (pcdl_get_cell_attribute_list or pcdl_get_substrate_list). None is count, agent or voxel count."/>
+    </xml>
+    <xml name="frame">
+        <param argument="--frame" label="frame" type="select" display="radio" help="To specifies the data dataframe from which the values are taken. Cell: agent centric value. Conc: whole domain centric substarte concentration values.">
+            <option value="cell" selected="true">cell</option>
+            <option value="conc">conc</option>
+        </param>
+    </xml>
+    <xml name="framerate">
+        <param argument="--framerate" label="values" type="integer" value="12" optional="false" help="Specifies how many images per second will be used. Humans are capable of processing 12 images per second and seeing them individually. Higher rates are seen as motion."/>
+    </xml>
+    <xml name="graph">
+        <param argument="--graph" label="graph" type="boolean" truevalue="true" falsevalue="false" checked="true" help="Should neighbor graph, attached graph, and attached spring graph be extracted and loaded into the resulting object?"/>
+    </xml>
+    <xml name="graph_type">
+        <param argument="--graph_type" label="graph type" type="select" display="radio" help="Specify which physicell graph output data should be processed. Neighbor: neighbor graph data. Attached: attached graph data. Spring: spring attache graph data.">
+            <option value="neighbor" selected="true">neighbor</option>
+            <option value="attached">attached</option>
+            <option value="spring">spring</option>
+        </param>
+    </xml>
+    <xml name="grid">
+        <param argument="--grid" label="grid" type="boolean" truevalue="true" falsevalue="false" checked="true" help="Plot axis grid lines."/>
+    </xml>
+    <xml name="interface">
+        <param name="interface" label="interface" type="select" display="radio" help="Specify the image format from which the gif will be generated. These images can be generated with the pcdl_plot_scatter or pcdl_plot_contour function.">
+            <option value="jpeg" selected="true">jpeg</option>
+            <!--
+        <option value="png">png</option>
+        <option value="tiff">tiff</option>
+        -->
+        </param>
+    </xml>
+    <xml name="keep">
+        <param argument="--keep" label="keep" type="text" value="" optional="true" help="Set of column labels (pcdl_get_cell_attribute_list, pcdl_get_substrate_list) to be kept. Set parameter values to 1 to be sure that all variables are kept. Don't worry: essential columns like ID, coordinates and time will always be kept."/>
+    </xml>
+    <xml name="legend">
+        <param argument="--legend" label="legend" type="select" display="radio" help="If True or reverse, place legend on axis subplots.">
+            <option value="false">false</option>
+            <option value="reverse">reverse</option>
+            <option value="true" selected="true">true</option>
+        </param>
+    </xml>
+    <xml name="legend_loc">
+        <param argument="--legend_loc" label="legend location" type="select" display="radio" help="The location of the categorical legend, if applicable.">
+            <option value="best">best</option>
+            <option value="upper right">upper right</option>
+            <option value="upper center"/>
+            <option value="upper left"/>
+            <option value="center left"/>
+            <option value="lower left" selected="true"/>
+            <option value="lower center"/>
+            <option value="lower right"/>
+            <option value="center right"/>
+            <option value="center"/>
+        </param>
+    </xml>
+    <xml name="linestyle">
+        <param argument="--linestyle" label="line style" type="select" display="radio" help="Matplotlib line style.">
+            <option value="-" selected="true">-</option>
+            <option value="--">--</option>
+            <option value=".-">.-</option>
+            <option value=":">:</option>
+        </param>
+    </xml>
+    <xml name="linewidth">
+        <param argument="--linewidth" label="line width" type="integer" value="1" optional="false" help="Line width in points."/>
+    </xml>
+    <xml name="logy">
+        <param argument="--logy" label="logarithmic y-axis" type="boolean" truevalue="true" falsevalue="false" checked="false" help="If True, then y axis is natural log scaled."/>
+    </xml>
+    <xml name="microenv">
+        <param argument="--microenv" label="micro environment" type="boolean" truevalue="true" falsevalue="false" checked="true" help="Should the microenvironment be extracted and loaded into the resulting object? Setting microenv to False will use less memory and speed up processing."/>
+    </xml>
+    <xml name="node_attribute">
+        <param argument="--node_attribute" label="node attribute" type="text" value="" optional="true" help="Listing of pcdl_get_cell_attribute attributes, used for node attributes."/>
+    </xml>
+    <xml name="path">
+        <param name="path" label="data collection" type="data_collection" collection_type="list" help="PhysiCell output data collection."/>
+    </xml>
+    <xml name="physiboss">
+        <param argument="--physiboss" label="physiboss" type="boolean" truevalue="true" falsevalue="false" checked="true" help="If found, should physiboss state data be extracted and loaded into the resulting object?"/>
+    </xml>
+    <xml name="s">
+        <param argument="--s" label="s" type="float" value="1.0" optional="false" help="Scatter plot dot size scale factor. With figsizepx extracted from initial.svg, scale factor 1.0 should be ok. Adjust if necessary."/>
+    </xml>
+    <xml name="scale">
+        <param argument="--scale" label="scale" type="select" display="radio" help="Specify how the data should be scaled. Possible values are None, maxabs, minmax, std. None: no scaling. Maxabs: maximum absolute value distance scaler maps all values linearly into a [-1, 1] interval. Minmax: minimum maximum distance scaler maps all values linearly into a [0, 1] interval. Std: standard deviation scaler maps all values to sigmas.">
+            <option value="none">none</option>
+            <option value="maxabs" selected="true">maxabs</option>
+            <option value="minmax">minmax</option>
+            <option value="std">std</option>
+        </param>
+    </xml>
+    <xml name="secondary_y">
+        <param argument="--secondary_y" label="secondary y-axis" type="boolean" truevalue="true" falsevalue="false" checked="false" help="Plot on the secondary y-axis?"/>
+    </xml>
+    <xml name="sharex">
+        <param argument="--sharex" label="shared x-axis" type="boolean" truevalue="true" falsevalue="false" checked="false" help="In case subplots is True, share x-axis by setting some x-axis labels to invisible."/>
+    </xml>
+    <xml name="sharey">
+        <param argument="sharey" label="shared y-axis" type="boolean" truevalue="true" falsevalue="false" checked="false" help="In case subplots is True, share y-axis range and possibly setting some y-axis labels to invisible."/>
+    </xml>
+    <xml name="subplots">
+        <param argument="--subplots" label="subplots" type="boolean" truevalue="true" falsevalue="false" checked="false" help="`Should the plot be split into subplots, one per curve?"/>
+    </xml>
+    <xml name="title">
+        <param argument="--title" label="title" type="text" value="none" optional="false" help="Title to use for the plot. None will print no title."/>
+    </xml>
+    <xml name="title_prefix.">
+        <param argument="--title_prefix" label="title" type="text" value="" optional="true" help="Title prefix."/>
+    </xml>
+    <xml name="verbose">
+        <param argument="--verbose" label="verbose" type="boolean" truevalue="true" falsevalue="false" checked="false" help="Setting verbose to True for more text output, while processing."/>
+    </xml>
+    <xml name="xlim">
+        <param argument="--xlim" label="x-axis limit" type="text" value="none" optional="false" help="Two floats separated by a space. X axis min and max value. None takes min and max from mesh x axis range.">
+            <validator type="regex" message="None or two float values separated by a space!">^[enoENO0-9-. ]*$</validator>
+        </param>
+    </xml>
+    <xml name="xyequal">
+        <param argument="--xyequal" label="equal x-axis y-axis spacing" type="boolean" truevalue="true" falsevalue="false" checked="true" help="To specify equal axis spacing for x and y axis."/>
+    </xml>
+    <xml name="ylim">
+        <param argument="--ylim" label="y-axis limit" type="text" value="none" optional="false" help="Two floats separated by a space. y axis min and max value. None takes min and max from mesh y axis range.">
+            <validator type="regex" message="None or two float values separated by a space!">^[enoENO0-9-. ]*$</validator>
+        </param>
+    </xml>
+    <xml name="yunit">
+        <param argument="--yunit" label="y-axis unit" type="text" value="none" optional="false" help="String to specify y-axis unit. None will not print a unit on the y-axis."/>
+    </xml>
+    <xml name="z_axis">
+        <param argument="--z_axis" label="z-axis" type="text" value="none" optional="false" help="For a categorical focus: list of labels; for a numeric focus: list of two floats; None, depending on the focus column variable dtype, extracts labels or min and max values from data."/>
+    </xml>
+    <xml name="z_slice">
+        <param argument="--z_slice" label="z-axis slice" type="float" value="0.0" optional="false" help="Z-axis cut position to slice a 2D xy-plain out of the 3D mesh. If z_slice position numeric but not an exact mesh center coordinate, then z_slice will be adjusted to the nearest mesh center value, the smaller one, if the coordinate lies on a saddle point."/>
+    </xml>
+    <!-- test -->
+    <xml name="output">
+        <collection type="list">
+            <element name="initial_attached_cells_graph.txt" value="initial_attached_cells_graph.txt"/>
+            <element name="initial_cell_neighbor_graph.txt" value="initial_cell_neighbor_graph.txt"/>
+            <element name="initial_cells.mat" value="initial_cells.mat"/>
+            <element name="initial_mesh0.mat" value="initial_mesh0.mat"/>
+            <element name="initial_microenvironment0.mat" value="initial_microenvironment0.mat"/>
+            <element name="initial_spring_attached_cells_graph.txt" value="initial_spring_attached_cells_graph.txt"/>
+            <element name="initial.svg" value="initial.svg"/>
+            <element name="initial.xml" value="initial.xml"/>
+            <element name="legend.svg" value="legend.svg"/>
+            <element name="output00000000_attached_cells_graph.txt" value="output00000000_attached_cells_graph.txt"/>
+            <element name="output00000000_cell_neighbor_graph.txt" value="output00000000_cell_neighbor_graph.txt"/>
+            <element name="output00000000_cells.mat" value="output00000000_cells.mat"/>
+            <element name="output00000000_microenvironment0.mat" value="output00000000_microenvironment0.mat"/>
+            <element name="output00000000_spring_attached_cells_graph.txt" value="output00000000_spring_attached_cells_graph.txt"/>
+            <element name="output00000000.xml" value="output00000000.xml"/>
+            <element name="output00000001_attached_cells_graph.txt" value="output00000001_attached_cells_graph.txt"/>
+            <element name="output00000001_cell_neighbor_graph.txt" value="output00000001_cell_neighbor_graph.txt"/>
+            <element name="output00000001_cells.mat" value="output00000001_cells.mat"/>
+            <element name="output00000001_microenvironment0.mat" value="output00000001_microenvironment0.mat"/>
+            <element name="output00000001_spring_attached_cells_graph.txt" value="output00000001_spring_attached_cells_graph.txt"/>
+            <element name="output00000001.xml" value="output00000001.xml"/>
+            <element name="final_attached_cells_graph.txt" value="final_attached_cells_graph.txt"/>
+            <element name="final_cell_neighbor_graph.txt" value="final_cell_neighbor_graph.txt"/>
+            <element name="final_cells.mat" value="final_cells.mat"/>
+            <element name="final_microenvironment0.mat" value="final_microenvironment0.mat"/>
+            <element name="final_spring_attached_cells_graph.txt" value="final_spring_attached_cells_graph.txt"/>
+            <element name="final.svg" value="final.svg"/>
+            <element name="final.xml" value="final.xml"/>
+            <element name="PhysiCell_settings.xml" value="PhysiCell_settings.xml"/>
+            <!-- test pcdl_make_gif.xml and pcdl_make_movie.xml -->
+            <element name="output00000000_oxygen.jpeg" value="output00000000_oxygen.jpeg"/>
+            <element name="output00000001_oxygen.jpeg" value="output00000001_oxygen.jpeg"/>
+        </collection>
+    </xml>
+    <!-- meta -->
+    <xml name="citation">
+        <citation type="bibtex">
+        @misc{githubphysicelldataloader,
+            author = {Bucher, Elmar},
+            year = {2025},
+            title = {physicelldataloader},
+            publisher = {GitHub},
+            journal = {GitHub repository},
+            url = {https://github.com/elmbeech/physicelldataloader},
+        }</citation>
+    </xml>
+</macros>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/PhysiCell_settings.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,405 @@
+<PhysiCell_settings version="devel-version">
+
+    <domain>
+        <x_min>-30</x_min>
+        <x_max>300</x_max>
+        <y_min>-20</y_min>
+        <y_max>200</y_max>
+        <z_min>-10</z_min>
+        <z_max>100</z_max>
+        <dx>30</dx>
+        <dy>20</dy>
+        <dz>10</dz>
+        <use_2D>false</use_2D>
+    </domain>
+
+    <overall>
+        <max_time units="min">1440.0</max_time>
+        <time_units>min</time_units>
+        <space_units>micron</space_units>
+        <dt_diffusion units="min">0.01</dt_diffusion>
+        <dt_mechanics units="min">0.1</dt_mechanics>
+        <dt_phenotype units="min">6</dt_phenotype>
+    </overall>
+
+    <parallel>
+        <omp_num_threads>1</omp_num_threads>
+    </parallel>
+
+    <save>
+        <folder>output</folder>
+        <full_data>
+            <interval units="min">60</interval>
+            <enable>true</enable>
+        </full_data>
+        <SVG>
+            <interval units="min">60</interval>
+            <enable>false</enable>
+            <plot_substrate enabled="false" limits="false">
+                <substrate>water</substrate>
+                <colormap>YlOrRd</colormap>
+                <min_conc>0</min_conc>
+                <max_conc>1</max_conc>
+            </plot_substrate>
+        </SVG>
+        <legacy_data>
+            <enable>false</enable>
+        </legacy_data>
+    </save>
+
+    <options>
+        <legacy_random_points_on_sphere_in_divide>false</legacy_random_points_on_sphere_in_divide>
+        <virtual_wall_at_domain_edge>true</virtual_wall_at_domain_edge>
+        <disable_automated_spring_adhesions>false</disable_automated_spring_adhesions>
+        <random_seed>0</random_seed>
+    </options>
+
+    <microenvironment_setup>
+        <variable name="oxygen" units="dimensionless" ID="0">
+            <physical_parameter_set>
+                <diffusion_coefficient units="micron^2/min">1e3</diffusion_coefficient>
+                <decay_rate units="1/min">1</decay_rate>
+            </physical_parameter_set>
+            <initial_condition units="dimensionless">1e3</initial_condition>
+            <Dirichlet_boundary_condition units="dimensionless" enabled="False">0.0</Dirichlet_boundary_condition>
+            <Dirichlet_options>
+                <boundary_value ID="xmin" enabled="False" />
+                <boundary_value ID="xmax" enabled="False" />
+                <boundary_value ID="ymin" enabled="False" />
+                <boundary_value ID="ymax" enabled="False" />
+                <boundary_value ID="zmin" enabled="False" />
+                <boundary_value ID="zmax" enabled="False" />
+            </Dirichlet_options>
+        </variable>
+        <variable name="water" units="dimensionless" ID="1">
+            <physical_parameter_set>
+                <diffusion_coefficient units="micron^2/min">1e6</diffusion_coefficient>
+                <decay_rate units="1/min">0.001</decay_rate>
+            </physical_parameter_set>
+            <initial_condition units="dimensionless">1e3</initial_condition>
+            <Dirichlet_boundary_condition units="dimensionless" enabled="True">1e3</Dirichlet_boundary_condition>
+            <Dirichlet_options>
+                <boundary_value ID="xmin" enabled="True">1e3</boundary_value>
+                <boundary_value ID="xmax" enabled="True">1e3</boundary_value>
+                <boundary_value ID="ymin" enabled="True">1e3</boundary_value>
+                <boundary_value ID="ymax" enabled="True">1e3</boundary_value>
+                <boundary_value ID="zmin" enabled="True">1e3</boundary_value>
+                <boundary_value ID="zmax" enabled="True">1e3</boundary_value>
+            </Dirichlet_options>
+        </variable>
+        <options>
+            <calculate_gradients>true</calculate_gradients>
+            <track_internalized_substrates_in_each_agent>true</track_internalized_substrates_in_each_agent>
+            <initial_condition type="matlab" enabled="false">
+                <filename>./config/initial.mat</filename>
+            </initial_condition>
+            <dirichlet_nodes type="matlab" enabled="false">
+                <filename>./config/dirichlet.mat</filename>
+            </dirichlet_nodes>
+        </options>
+    </microenvironment_setup>
+
+    <cell_definitions>
+        <cell_definition name="default" ID="0">
+            <phenotype>
+                <cycle code="6" name="Flow cytometry model (separated)">
+                    <phase_transition_rates units="1/min">
+                        <rate start_index="0" end_index="1" fixed_duration="false">0.003333</rate>
+                        <rate start_index="1" end_index="2" fixed_duration="true">0.002083</rate>
+                        <rate start_index="2" end_index="3" fixed_duration="true">0.004167</rate>
+                        <rate start_index="3" end_index="0" fixed_duration="true">0.016667</rate>
+                    </phase_transition_rates>
+                </cycle>
+                <death>
+                    <model code="100" name="apoptosis">
+                        <death_rate units="1/min">5.31667e-05</death_rate>
+                        <phase_durations units="min">
+                            <duration index="0" fixed_duration="true">516</duration>
+                        </phase_durations>
+                        <parameters>
+                            <unlysed_fluid_change_rate units="1/min">0.05</unlysed_fluid_change_rate>
+                            <lysed_fluid_change_rate units="1/min">0</lysed_fluid_change_rate>
+                            <cytoplasmic_biomass_change_rate units="1/min">1.66667e-02</cytoplasmic_biomass_change_rate>
+                            <nuclear_biomass_change_rate units="1/min">5.83333e-03</nuclear_biomass_change_rate>
+                            <calcification_rate units="1/min">0</calcification_rate>
+                            <relative_rupture_volume units="dimensionless">2.0</relative_rupture_volume>
+                        </parameters>
+                    </model>
+                    <model code="101" name="necrosis">
+                        <death_rate units="1/min">0.0</death_rate>
+                        <phase_durations units="min">
+                            <duration index="0" fixed_duration="true">0</duration>
+                            <duration index="1" fixed_duration="true">86400</duration>
+                        </phase_durations>
+                        <parameters>
+                            <unlysed_fluid_change_rate units="1/min">1.11667e-2</unlysed_fluid_change_rate>
+                            <lysed_fluid_change_rate units="1/min">8.33333e-4</lysed_fluid_change_rate>
+                            <cytoplasmic_biomass_change_rate units="1/min">5.33333e-5</cytoplasmic_biomass_change_rate>
+                            <nuclear_biomass_change_rate units="1/min">2.16667e-3</nuclear_biomass_change_rate>
+                            <calcification_rate units="1/min">0</calcification_rate>
+                            <relative_rupture_volume units="dimensionless">2.0</relative_rupture_volume>
+                        </parameters>
+                    </model>
+                </death>
+                <volume>
+                    <total units="micron^3">2494</total>
+                    <fluid_fraction units="dimensionless">0.75</fluid_fraction>
+                    <nuclear units="micron^3">540</nuclear>
+                    <fluid_change_rate units="1/min">0.05</fluid_change_rate>
+                    <cytoplasmic_biomass_change_rate units="1/min">0.0045</cytoplasmic_biomass_change_rate>
+                    <nuclear_biomass_change_rate units="1/min">0.0055</nuclear_biomass_change_rate>
+                    <calcified_fraction units="dimensionless">0</calcified_fraction>
+                    <calcification_rate units="1/min">0</calcification_rate>
+                    <relative_rupture_volume units="dimensionless">2.0</relative_rupture_volume>
+                </volume>
+                <mechanics>
+                    <cell_cell_adhesion_strength units="micron/min">0.4</cell_cell_adhesion_strength>
+                    <cell_cell_repulsion_strength units="micron/min">10.0</cell_cell_repulsion_strength>
+                    <relative_maximum_adhesion_distance units="dimensionless">1.25</relative_maximum_adhesion_distance>
+                    <cell_adhesion_affinities>
+                        <cell_adhesion_affinity name="blood_cells">1.0</cell_adhesion_affinity>
+                        <cell_adhesion_affinity name="default">1</cell_adhesion_affinity>
+                    </cell_adhesion_affinities>
+                    <options>
+                        <set_relative_equilibrium_distance enabled="false" units="dimensionless">1.8</set_relative_equilibrium_distance>
+                        <set_absolute_equilibrium_distance enabled="false" units="micron">15.12</set_absolute_equilibrium_distance>
+                    </options>
+                    <attachment_elastic_constant units="1/min">0.01</attachment_elastic_constant>
+                    <attachment_rate units="1/min">0.05</attachment_rate>
+                    <detachment_rate units="1/min">0.03</detachment_rate>
+                    <maximum_number_of_attachments>12</maximum_number_of_attachments>
+                </mechanics>
+                <motility>
+                    <speed units="micron/min">1</speed>
+                    <persistence_time units="min">1</persistence_time>
+                    <migration_bias units="dimensionless">.2</migration_bias>
+                    <options>
+                        <enabled>true</enabled>
+                        <use_2D>true</use_2D>
+                        <chemotaxis>
+                            <enabled>true</enabled>
+                            <substrate>oxygen</substrate>
+                            <direction>1</direction>
+                        </chemotaxis>
+                        <advanced_chemotaxis>
+                            <enabled>false</enabled>
+                            <normalize_each_gradient>false</normalize_each_gradient>
+                            <chemotactic_sensitivities>
+                                <chemotactic_sensitivity substrate="oxygen">0.0</chemotactic_sensitivity>
+                                <chemotactic_sensitivity substrate="water">0.0</chemotactic_sensitivity>
+                            </chemotactic_sensitivities>
+                        </advanced_chemotaxis>
+                    </options>
+                </motility>
+                <secretion>
+                    <substrate name="oxygen">
+                        <secretion_rate units="1/min">0</secretion_rate>
+                        <secretion_target units="substrate density">0</secretion_target>
+                        <uptake_rate units="1/min">10</uptake_rate>
+                        <net_export_rate units="total substrate/min">0.0</net_export_rate>
+                    </substrate>
+                    <substrate name="water">
+                        <secretion_rate units="1/min">5</secretion_rate>
+                        <secretion_target units="substrate density">15</secretion_target>
+                        <uptake_rate units="1/min">0</uptake_rate>
+                        <net_export_rate units="total substrate/min">0</net_export_rate>
+                    </substrate>
+                </secretion>
+                <cell_interactions>
+                    <apoptotic_phagocytosis_rate units="1/min">0.0</apoptotic_phagocytosis_rate>
+                    <necrotic_phagocytosis_rate units="1/min">0.0</necrotic_phagocytosis_rate>
+                    <other_dead_phagocytosis_rate units="1/min">0.0</other_dead_phagocytosis_rate>
+                    <live_phagocytosis_rates>
+                        <phagocytosis_rate name="blood_cells" units="1/min">0.001</phagocytosis_rate>
+                        <phagocytosis_rate name="default" units="1/min">0.0</phagocytosis_rate>
+                    </live_phagocytosis_rates>
+                    <attack_rates>
+                        <attack_rate name="blood_cells" units="1/min">0.0025</attack_rate>
+                        <attack_rate name="default" units="1/min">0.0</attack_rate>
+                    </attack_rates>
+                    <attack_damage_rate units="1/min">1.0</attack_damage_rate>
+                    <attack_duration units="min">0.1</attack_duration>
+                    <fusion_rates>
+                        <fusion_rate name="blood_cells" units="1/min">0.0</fusion_rate>
+                        <fusion_rate name="default" units="1/min">0.005</fusion_rate>
+                    </fusion_rates>
+                </cell_interactions>
+                <cell_transformations>
+                    <transformation_rates>
+                        <transformation_rate name="blood_cells" units="1/min">0.0</transformation_rate>
+                        <transformation_rate name="default" units="1/min">0.0</transformation_rate>
+                    </transformation_rates>
+                </cell_transformations>
+                <cell_integrity>
+                    <damage_rate units="1/min">0.0</damage_rate>
+                    <damage_repair_rate units="1/min">0.0</damage_repair_rate>
+                </cell_integrity>
+            </phenotype>
+            <custom_data>
+                <sample conserved="false" units="dimensionless" description="">1.0</sample>
+            </custom_data>
+            <initial_parameter_distributions enabled="false">
+          </initial_parameter_distributions>
+        </cell_definition>
+        <cell_definition name="blood_cells" ID="1">
+            <phenotype>
+                <cycle code="5" name="live">
+                    <phase_durations units="min">
+                        <duration index="0" fixed_duration="false">1388.888889</duration>
+                    </phase_durations>
+                </cycle>
+                <death>
+                    <model code="100" name="apoptosis">
+                        <death_rate units="1/min">5.31667e-05</death_rate>
+                        <phase_transition_rates units="1/min">
+                            <rate start_index="0" end_index="1" fixed_duration="false">0.001938</rate>
+                        </phase_transition_rates>
+                        <parameters>
+                            <unlysed_fluid_change_rate units="1/min">0.05</unlysed_fluid_change_rate>
+                            <lysed_fluid_change_rate units="1/min">0</lysed_fluid_change_rate>
+                            <cytoplasmic_biomass_change_rate units="1/min">1.66667e-02</cytoplasmic_biomass_change_rate>
+                            <nuclear_biomass_change_rate units="1/min">5.83333e-03</nuclear_biomass_change_rate>
+                            <calcification_rate units="1/min">0</calcification_rate>
+                            <relative_rupture_volume units="dimensionless">2.0</relative_rupture_volume>
+                        </parameters>
+                    </model>
+                    <model code="101" name="necrosis">
+                        <death_rate units="1/min">0.0</death_rate>
+                        <phase_transition_rates units="1/min">
+                            <rate start_index="0" end_index="1" fixed_duration="false">9000000000.0</rate>
+                            <rate start_index="1" end_index="2" fixed_duration="true">1.15741e-05</rate>
+                        </phase_transition_rates>
+                        <parameters>
+                            <unlysed_fluid_change_rate units="1/min">1.11667e-02</unlysed_fluid_change_rate>
+                            <lysed_fluid_change_rate units="1/min">8.33333e-4</lysed_fluid_change_rate>
+                            <cytoplasmic_biomass_change_rate units="1/min">5.33333e-05</cytoplasmic_biomass_change_rate>
+                            <nuclear_biomass_change_rate units="1/min">2.16667e-4</nuclear_biomass_change_rate>
+                            <calcification_rate units="1/min">7e-05</calcification_rate>
+                            <relative_rupture_volume units="dimensionless">2.0</relative_rupture_volume>
+                        </parameters>
+                    </model>
+                </death>
+                <volume>
+                    <total units="micron^3">2494</total>
+                    <fluid_fraction units="dimensionless">0.75</fluid_fraction>
+                    <nuclear units="micron^3">540</nuclear>
+                    <fluid_change_rate units="1/min">0.05</fluid_change_rate>
+                    <cytoplasmic_biomass_change_rate units="1/min">0.0045</cytoplasmic_biomass_change_rate>
+                    <nuclear_biomass_change_rate units="1/min">0.0055</nuclear_biomass_change_rate>
+                    <calcified_fraction units="dimensionless">0.0</calcified_fraction>
+                    <calcification_rate units="1/min">0.0</calcification_rate>
+                    <relative_rupture_volume units="dimensionless">2</relative_rupture_volume>
+                </volume>
+                <mechanics>
+                    <cell_cell_adhesion_strength units="micron/min">0.4</cell_cell_adhesion_strength>
+                    <cell_cell_repulsion_strength units="micron/min">10.0</cell_cell_repulsion_strength>
+                    <relative_maximum_adhesion_distance units="dimensionless">1.25</relative_maximum_adhesion_distance>
+                    <cell_adhesion_affinities>
+                        <cell_adhesion_affinity name="blood_cells">1.0</cell_adhesion_affinity>
+                        <cell_adhesion_affinity name="default">1.0</cell_adhesion_affinity>
+                    </cell_adhesion_affinities>
+                    <options>
+                        <set_relative_equilibrium_distance enabled="false" units="dimensionless">1.8</set_relative_equilibrium_distance>
+                        <set_absolute_equilibrium_distance enabled="false" units="micron">15.12</set_absolute_equilibrium_distance>
+                    </options>
+                    <attachment_elastic_constant units="1/min">0.01</attachment_elastic_constant>
+                    <attachment_rate units="1/min">0.0</attachment_rate>
+                    <detachment_rate units="1/min">0.0</detachment_rate>
+                    <maximum_number_of_attachments>12</maximum_number_of_attachments>
+                </mechanics>
+                <motility>
+                    <speed units="micron/min">2.5</speed>
+                    <persistence_time units="min">1.0</persistence_time>
+                    <migration_bias units="dimensionless">.5</migration_bias>
+                    <options>
+                        <enabled>true</enabled>
+                        <use_2D>true</use_2D>
+                        <chemotaxis>
+                            <enabled>true</enabled>
+                            <substrate>water</substrate>
+                            <direction>1</direction>
+                        </chemotaxis>
+                        <advanced_chemotaxis>
+                            <enabled>false</enabled>
+                            <normalize_each_gradient>false</normalize_each_gradient>
+                            <chemotactic_sensitivities>
+                                <chemotactic_sensitivity substrate="oxygen">0.0</chemotactic_sensitivity>
+                                <chemotactic_sensitivity substrate="water">0.0</chemotactic_sensitivity>
+                            </chemotactic_sensitivities>
+                        </advanced_chemotaxis>
+                    </options>
+                </motility>
+                <secretion>
+                    <substrate name="oxygen">
+                        <secretion_rate units="1/min">1000</secretion_rate>
+                        <secretion_target units="substrate density">50000</secretion_target>
+                        <uptake_rate units="1/min">0</uptake_rate>
+                        <net_export_rate units="total substrate/min">0.0</net_export_rate>
+                    </substrate>
+                    <substrate name="water">
+                        <secretion_rate units="1/min">0</secretion_rate>
+                        <secretion_target units="substrate density">1.0</secretion_target>
+                        <uptake_rate units="1/min">10</uptake_rate>
+                        <net_export_rate units="total substrate/min">0.0</net_export_rate>
+                    </substrate>
+                </secretion>
+                <cell_interactions>
+                    <apoptotic_phagocytosis_rate units="1/min">0.0</apoptotic_phagocytosis_rate>
+                    <necrotic_phagocytosis_rate units="1/min">0.0</necrotic_phagocytosis_rate>
+                    <other_dead_phagocytosis_rate units="1/min">0.0</other_dead_phagocytosis_rate>
+                    <live_phagocytosis_rates>
+                        <phagocytosis_rate name="blood_cells" units="1/min">0.0</phagocytosis_rate>
+                        <phagocytosis_rate name="default" units="1/min">0.0005</phagocytosis_rate>
+                    </live_phagocytosis_rates>
+                    <attack_rates>
+                        <attack_rate name="blood_cells" units="1/min">0</attack_rate>
+                        <attack_rate name="default" units="1/min">0.006</attack_rate>
+                    </attack_rates>
+                    <attack_damage_rate units="1/min">1.0</attack_damage_rate>
+                    <attack_duration units="min">0.1</attack_duration>
+                    <fusion_rates>
+                        <fusion_rate name="blood_cells" units="1/min">0.0</fusion_rate>
+                        <fusion_rate name="default" units="1/min">0.0</fusion_rate>
+                    </fusion_rates>
+                </cell_interactions>
+                <cell_transformations>
+                    <transformation_rates>
+                        <transformation_rate name="blood_cells" units="1/min">0.0</transformation_rate>
+                        <transformation_rate name="default" units="1/min">0.0</transformation_rate>
+                    </transformation_rates>
+                </cell_transformations>
+                <cell_integrity>
+                    <damage_rate units="1/min">0.0</damage_rate>
+                    <damage_repair_rate units="1/min">0.0</damage_repair_rate>
+                </cell_integrity>
+            </phenotype>
+            <custom_data>
+                <sample conserved="false" units="dimensionless" description="">0.0</sample>
+            </custom_data>
+            <initial_parameter_distributions enabled="false">
+          </initial_parameter_distributions>
+        </cell_definition>
+    </cell_definitions>
+
+    <initial_conditions>
+        <cell_positions type="csv" enabled="false">
+            <folder>./config</folder>
+            <filename>cells.csv</filename>
+        </cell_positions>
+    </initial_conditions>
+
+    <cell_rules>
+        <rulesets>
+            <ruleset protocol="CBHG" version="3.0" format="csv" enabled="false">
+                <folder>./config</folder>
+                <filename>cell_rules.csv</filename>
+            </ruleset>
+        </rulesets>
+        <settings />
+    </cell_rules>
+
+    <user_parameters>
+        <random_seed type="int" units="dimensionless" description="">0</random_seed>
+        <number_of_cells type="int" units="none" description="initial number of cells (for each cell type)">64</number_of_cells>
+    </user_parameters>
+</PhysiCell_settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/final.svg	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with PhysiCell (http://PhysiCell.MathCancer.org/) -->
+<svg 
+ xmlns:dc="http://purl.org/dc/elements/1.1/" 
+ xmlns:cc="http://creativecommons.org/ns#" 
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+ xmlns:svg="http://www.w3.org/2000/svg" 
+ xmlns="http://www.w3.org/2000/svg" 
+ version="1.1" 
+ width="330" 
+ height="235.4" 
+ id="svg2">
+  <rect x="0" y="0" width="330" height="235.4" stroke-width="0.44" stroke="white" fill="white"/>
+  <text x="2.75" y="6.6"
+   font-family="Arial" font-size="5.5" fill="black" >
+   Current time: 1 days, 0 hours, and 0.01 minutes, z = 0.00 &#956;m
+  </text>
+  <text x="2.75" y="12.65"
+   font-family="Arial" font-size="5.225" fill="black" >
+   153 agents
+  </text>
+ <g id="tissue" 
+    transform="translate(0,235.4) scale(1,-1)">
+  <g id="ECM">
+  </g>
+  <g id="cells">
+   <g id="cell221" type="blood_cells" dead="false" >
+  <circle cx="11.6773" cy="40.0676" r="7.56839" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="11.6773" cy="40.0676" r="4.59401" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell211" type="blood_cells" dead="false" >
+  <circle cx="246.546" cy="23.6682" r="7.73991" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="246.546" cy="23.6682" r="4.32432" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell217" type="blood_cells" dead="false" >
+  <circle cx="32.4856" cy="22.041" r="7.588" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="32.4856" cy="22.041" r="4.32853" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell181" type="blood_cells" dead="false" >
+  <circle cx="298.995" cy="154.977" r="8.20756" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="298.995" cy="154.977" r="4.91146" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell116" type="blood_cells" dead="false" >
+  <circle cx="55.4011" cy="52.7132" r="8.3834" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="55.4011" cy="52.7132" r="5.01959" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell186" type="blood_cells" dead="false" >
+  <circle cx="276.325" cy="20.5077" r="7.55579" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="276.325" cy="20.5077" r="3.81607" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell121" type="blood_cells" dead="false" >
+  <circle cx="171.568" cy="25.0672" r="8.32907" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="171.568" cy="25.0672" r="4.96197" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell61" type="default" dead="false" >
+  <circle cx="98.0084" cy="68.538" r="9.5346" stroke-width="0.5" stroke="black" fill="grey"/>
+  <circle cx="98.0084" cy="68.538" r="5.79063" stroke-width="0.5" stroke="grey" fill="grey"/>
+   </g>
+   <g id="cell227" type="default" dead="false" >
+  <circle cx="252.012" cy="118.395" r="16.4982" stroke-width="0.5" stroke="black" fill="grey"/>
+  <circle cx="252.012" cy="118.395" r="6.01826" stroke-width="0.5" stroke="grey" fill="grey"/>
+   </g>
+   <g id="cell114" type="blood_cells" dead="false" >
+  <circle cx="60.1648" cy="190.79" r="11.7838" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="60.1648" cy="190.79" r="5.27501" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell76" type="blood_cells" dead="false" >
+  <circle cx="36.3672" cy="103.597" r="8.41242" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="36.3672" cy="103.597" r="5.05119" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell78" type="blood_cells" dead="false" >
+  <circle cx="32.7971" cy="133.644" r="8.38582" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="32.7971" cy="133.644" r="5.03282" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell81" type="blood_cells" dead="false" >
+  <circle cx="114.284" cy="28.2712" r="6.33528" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="114.284" cy="28.2712" r="3.64177" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell82" type="blood_cells" dead="false" >
+  <circle cx="91.1458" cy="162.9" r="7.80952" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="91.1458" cy="162.9" r="4.60238" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell92" type="blood_cells" dead="false" >
+  <circle cx="242.122" cy="186.211" r="8.22893" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="242.122" cy="186.211" r="4.73931" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell149" type="blood_cells" dead="false" >
+  <circle cx="297.842" cy="107.582" r="8.29668" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="297.842" cy="107.582" r="4.88818" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell146" type="blood_cells" dead="false" >
+  <circle cx="167.537" cy="123.751" r="8.3816" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="167.537" cy="123.751" r="5.02782" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell166" type="blood_cells" dead="false" >
+  <circle cx="127.977" cy="54.0253" r="8.2632" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="127.977" cy="54.0253" r="4.90888" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell167" type="blood_cells" dead="false" >
+  <circle cx="288.107" cy="197.185" r="7.41716" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="288.107" cy="197.185" r="4.51857" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell175" type="default" dead="false" >
+  <circle cx="279.985" cy="85.2776" r="12.5052" stroke-width="0.5" stroke="black" fill="grey"/>
+  <circle cx="279.985" cy="85.2776" r="7.09876" stroke-width="0.5" stroke="grey" fill="grey"/>
+   </g>
+   <g id="cell194" type="default" dead="false" >
+  <circle cx="49.4206" cy="148.405" r="10.0222" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell199" type="blood_cells" dead="false" >
+  <circle cx="77.3926" cy="41.0929" r="7.97396" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="77.3926" cy="41.0929" r="4.80584" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell201" type="default" dead="false" >
+  <circle cx="181.596" cy="185.073" r="12.4176" stroke-width="0.5" stroke="black" fill="grey"/>
+  <circle cx="181.596" cy="185.073" r="7.03455" stroke-width="0.5" stroke="grey" fill="grey"/>
+   </g>
+   <g id="cell212" type="blood_cells" dead="false" >
+  <circle cx="15.0027" cy="184.561" r="7.55186" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="15.0027" cy="184.561" r="4.15016" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell209" type="default" dead="false" >
+  <circle cx="148.078" cy="30.1195" r="19.3662" stroke-width="0.5" stroke="black" fill="grey"/>
+  <circle cx="148.078" cy="30.1195" r="7.40524" stroke-width="0.5" stroke="grey" fill="grey"/>
+   </g>
+   <g id="cell224" type="blood_cells" dead="false" >
+  <circle cx="34.9009" cy="163.503" r="6.03498" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="34.9009" cy="163.503" r="3.70414" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell233" type="blood_cells" dead="false" >
+  <circle cx="66.7854" cy="12.0238" r="5.48717" stroke-width="0.5" stroke="black" fill="red"/>
+   </g>
+   <g id="cell249" type="blood_cells" dead="false" >
+  <circle cx="32.8655" cy="148.559" r="6.03275" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="32.8655" cy="148.559" r="3.7005" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell251" type="blood_cells" dead="false" >
+  <circle cx="129.5" cy="38.4617" r="3.68004" stroke-width="0.5" stroke="black" fill="red"/>
+   </g>
+  </g>
+ </g>
+  <rect x="124.5" y="227.7" width="200" height="2.2" stroke-width="0.44" stroke="rgb(255,255,255)" fill="rgb(0,0,0)"/>
+  <text x="125.875" y="226.325"
+   font-family="Arial" font-size="5.5" fill="black" >
+   200 &#956;m
+  </text>
+  <text x="5.5" y="229.9"
+   font-family="Arial" font-size="4.125" fill="black" >
+   0 days, 0 hours, 0 minutes, and 10.5490 seconds
+  </text>
+  <rect x="0" y="15.4" width="330" height="220" stroke-width="0.44" stroke="rgb(0,0,0)" fill="none"/>
+  <rect x="355" y="15.4" width="25" height="195" stroke-width="0.44" stroke="black" fill="none"/>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/final.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<MultiCellDS version="2" type="snapshot/simulation">
+	<metadata>
+		<software>
+			<name>PhysiCell</name>
+			<version>1.14.1</version>
+			<URL>http://physicell.org</URL>
+			<creator>
+				<orcid-identifier>
+					<path>0000-0002-9925-0151</path>
+					<given-names>Paul</given-names>
+					<family-name>Macklin</family-name>
+					<email>macklinp@iu.edu</email>
+					<url>http://MathCancer.org</url>
+					<organization-name>Indiana University &amp; PhysiCell Project</organization-name>
+					<department-name>Intelligent Systems Engineering</department-name>
+				</orcid-identifier>
+			</creator>
+			<citation>
+				<text>A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin. PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: 10.1371/journal.pcbi.1005991</text>
+				<DOI>10.1371/journal.pcbi.1005991</DOI>
+				<URL>https://dx.doi.org/PMC5841829</URL>
+				<PMID>29474446</PMID>
+				<PMCID>PMC5841829</PMCID>
+			</citation>
+			<user />
+		</software>
+		<citation />
+		<current_time units="min">1440.010000</current_time>
+		<current_runtime units="sec">10.548248</current_runtime>
+		<created>2025-01-05T08:14:42Z</created>
+		<last_modified>2025-01-05T08:14:42Z</last_modified>
+	</metadata>
+	<microenvironment>
+		<domain name="microenvironment">
+			<mesh type="Cartesian" uniform="false" regular="true" units="micron">
+				<bounding_box type="axis-aligned" units="micron">-30.000000 -20.000000 -10.000000 300.000000 200.000000 100.000000</bounding_box>
+				<x_coordinates delimiter=" ">-15 15 45 75 105 135 165 195 225 255 285</x_coordinates>
+				<y_coordinates delimiter=" ">-10 10 30 50 70 90 110 130 150 170 190</y_coordinates>
+				<z_coordinates delimiter=" ">-5 5 15 25 35 45 55 65 75 85 95</z_coordinates>
+				<voxels type="matlab">
+					<filename>initial_mesh0.mat</filename>
+				</voxels>
+			</mesh>
+			<variables>
+				<variable name="oxygen" units="dimensionless" ID="0">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">1.000000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+				<variable name="water" units="dimensionless" ID="1">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">0.001000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+			</variables>
+			<data type="matlab">
+				<filename>final_microenvironment0.mat</filename>
+			</data>
+		</domain>
+	</microenvironment>
+	<cellular_information>
+		<cell_populations>
+			<cell_population type="individual">
+				<custom>
+					<simplified_data type="matlab" source="PhysiCell" data_version="2">
+						<cell_types>
+							<type ID="0" type="0">default</type>
+							<type ID="1" type="1">blood_cells</type>
+						</cell_types>
+						<labels>
+							<label index="0" size="1" units="none">ID</label>
+							<label index="1" size="3" units="microns">position</label>
+							<label index="4" size="1" units="cubic microns">total_volume</label>
+							<label index="5" size="1" units="none">cell_type</label>
+							<label index="6" size="1" units="none">cycle_model</label>
+							<label index="7" size="1" units="none">current_phase</label>
+							<label index="8" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="9" size="1" units="cubic microns">nuclear_volume</label>
+							<label index="10" size="1" units="cubic microns">cytoplasmic_volume</label>
+							<label index="11" size="1" units="none">fluid_fraction</label>
+							<label index="12" size="1" units="none">calcified_fraction</label>
+							<label index="13" size="3" units="none">orientation</label>
+							<label index="16" size="1" units="none">polarity</label>
+							<label index="17" size="3" units="micron/min">velocity</label>
+							<label index="20" size="1" units="none">pressure</label>
+							<label index="21" size="1" units="none">number_of_nuclei</label>
+							<label index="22" size="1" units="min">total_attack_time</label>
+							<label index="23" size="1" units="none">contact_with_basement_membrane</label>
+							<label index="24" size="1" units="1/min">current_cycle_phase_exit_rate</label>
+							<label index="25" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="26" size="1" units="none">dead</label>
+							<label index="27" size="1" units="none">current_death_model</label>
+							<label index="28" size="2" units="1/min">death_rates</label>
+							<label index="30" size="1" units="1/min">cytoplasmic_biomass_change_rate</label>
+							<label index="31" size="1" units="1/min">nuclear_biomass_change_rate</label>
+							<label index="32" size="1" units="1/min">fluid_change_rate</label>
+							<label index="33" size="1" units="1/min">calcification_rate</label>
+							<label index="34" size="1" units="cubic microns">target_solid_cytoplasmic</label>
+							<label index="35" size="1" units="cubic microns">target_solid_nuclear</label>
+							<label index="36" size="1" units="none">target_fluid_fraction</label>
+							<label index="37" size="1" units="microns">radius</label>
+							<label index="38" size="1" units="microns">nuclear_radius</label>
+							<label index="39" size="1" units="square microns">surface_area</label>
+							<label index="40" size="1" units="micron/min">cell_cell_adhesion_strength</label>
+							<label index="41" size="1" units="micron/min">cell_BM_adhesion_strength</label>
+							<label index="42" size="1" units="micron/min">cell_cell_repulsion_strength</label>
+							<label index="43" size="1" units="micron/min">cell_BM_repulsion_strength</label>
+							<label index="44" size="2" units="none">cell_adhesion_affinities</label>
+							<label index="46" size="1" units="none">relative_maximum_adhesion_distance</label>
+							<label index="47" size="1" units="none">maximum_number_of_attachments</label>
+							<label index="48" size="1" units="1/min">attachment_elastic_constant</label>
+							<label index="49" size="1" units="1/min">attachment_rate</label>
+							<label index="50" size="1" units="1/min">detachment_rate</label>
+							<label index="51" size="1" units="none">is_motile</label>
+							<label index="52" size="1" units="min">persistence_time</label>
+							<label index="53" size="1" units="micron/min">migration_speed</label>
+							<label index="54" size="3" units="none">migration_bias_direction</label>
+							<label index="57" size="1" units="none">migration_bias</label>
+							<label index="58" size="3" units="micron/min">motility_vector</label>
+							<label index="61" size="1" units="none">chemotaxis_index</label>
+							<label index="62" size="1" units="none">chemotaxis_direction</label>
+							<label index="63" size="2" units="none">chemotactic_sensitivities</label>
+							<label index="65" size="2" units="1/min">secretion_rates</label>
+							<label index="67" size="2" units="1/min">uptake_rates</label>
+							<label index="69" size="2" units="stuff/cubic micron">saturation_densities</label>
+							<label index="71" size="2" units="stuff/min">net_export_rates</label>
+							<label index="73" size="2" units="stuff">internalized_total_substrates</label>
+							<label index="75" size="2" units="none">fraction_released_at_death</label>
+							<label index="77" size="2" units="none">fraction_transferred_when_ingested</label>
+							<label index="79" size="1" units="1/min">apoptotic_phagocytosis_rate</label>
+							<label index="80" size="1" units="1/min">necrotic_phagocytosis_rate</label>
+							<label index="81" size="1" units="1/min">other_dead_phagocytosis_rate</label>
+							<label index="82" size="2" units="1/min">live_phagocytosis_rates</label>
+							<label index="84" size="2" units="1/min">attack_rates</label>
+							<label index="86" size="2" units="none">immunogenicities</label>
+							<label index="88" size="1" units="none">attack_target</label>
+							<label index="89" size="1" units="1/min">attack_damage_rate</label>
+							<label index="90" size="1" units="min">attack_duration</label>
+							<label index="91" size="1" units="none">attack_total_damage_delivered</label>
+							<label index="92" size="2" units="1/min">fusion_rates</label>
+							<label index="94" size="2" units="1/min">transformation_rates</label>
+							<label index="96" size="2" units="none">asymmetric_division_probabilities</label>
+							<label index="98" size="1" units="none">damage</label>
+							<label index="99" size="1" units="1/min">damage_rate</label>
+							<label index="100" size="1" units="1/min">damage_repair_rate</label>
+							<label index="101" size="1" units="dimensionless">sample</label>
+						</labels>
+						<filename>final_cells.mat</filename>
+					</simplified_data>
+					<neighbor_graph type="text" source="PhysiCell" data_version="2">
+						<filename>final_cell_neighbor_graph.txt</filename>
+					</neighbor_graph>
+					<attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>final_attached_cells_graph.txt</filename>
+					</attached_cells_graph>
+					<spring_attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>final_spring_attached_cells_graph.txt</filename>
+					</spring_attached_cells_graph>
+				</custom>
+			</cell_population>
+		</cell_populations>
+	</cellular_information>
+</MultiCellDS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/final_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,153 @@
+210: 
+1: 
+221: 
+225: 
+211: 
+206: 
+108: 
+230: 
+164: 
+152: 
+213: 
+137: 
+143: 
+185: 
+159: 
+229: 
+242: 
+17: 
+102: 
+161: 
+217: 
+115: 
+135: 
+160: 
+239: 
+244: 
+106: 
+181: 
+120: 
+112: 
+188: 
+116: 
+125: 
+158: 
+136: 
+186: 
+139: 
+190: 
+124: 
+226: 
+132: 
+238: 
+142: 
+228: 
+148: 
+153: 
+145: 
+123: 
+48: 
+154: 
+131: 
+51: 
+215: 
+127: 
+216: 
+144: 
+130: 
+57: 
+214: 
+121: 
+180: 
+61: 
+163: 
+227: 
+64: 
+65: 
+138: 
+67: 
+134: 
+69: 
+70: 
+71: 
+72: 
+73: 
+114: 
+75: 
+76: 
+241: 
+78: 
+79: 
+150: 
+81: 
+82: 
+83: 
+84: 
+151: 
+119: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+149: 
+146: 
+147: 
+156: 
+157: 
+165: 
+166: 
+167: 
+168: 
+169: 
+170: 
+171: 
+172: 
+173: 
+174: 
+175: 
+177: 
+182: 
+183: 
+184: 
+187: 
+218: 
+245: 
+194: 
+195: 
+197: 
+243: 
+199: 
+200: 
+201: 
+202: 
+212: 
+204: 
+205: 
+207: 
+208: 
+209: 
+219: 
+224: 
+231: 
+232: 
+233: 
+234: 
+235: 
+236: 
+237: 
+240: 
+246: 
+247: 
+248: 
+249: 
+250: 
+251: 
+252: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/final_cell_neighbor_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,153 @@
+210: 
+1: 
+221: 
+225: 195
+211: 
+206: 158,217
+108: 17
+230: 180,96,188
+164: 48
+152: 
+213: 
+137: 218,51
+143: 102
+185: 
+159: 
+229: 250,139
+242: 204
+17: 243,108
+102: 143
+161: 214,94
+217: 206
+115: 195,226
+135: 
+160: 97
+239: 124
+244: 170
+106: 
+181: 57
+120: 168,240
+112: 
+188: 230
+116: 
+125: 158,182
+158: 206,125
+136: 87
+186: 134
+139: 151,229
+190: 
+124: 239
+226: 115,90
+132: 
+238: 
+142: 
+228: 72
+148: 
+153: 95
+145: 
+123: 169
+48: 164
+154: 
+131: 
+51: 137,236,247
+215: 
+127: 207,157
+216: 
+144: 173
+130: 
+57: 181,98
+214: 161,94,202,165
+121: 209
+180: 230
+61: 
+163: 
+227: 150
+64: 252,194
+65: 
+138: 204
+67: 
+134: 186
+69: 209
+70: 
+71: 
+72: 228
+73: 183,96
+114: 
+75: 
+76: 
+241: 
+78: 249,194
+79: 
+150: 227
+81: 209
+82: 
+83: 
+84: 243
+151: 139
+119: 
+87: 136
+88: 
+89: 
+90: 226
+91: 165
+92: 
+93: 
+94: 161,235,214
+95: 153
+96: 230,73
+97: 160
+98: 183,57
+149: 
+146: 
+147: 170,171
+156: 197
+157: 248,127
+165: 91,214
+166: 251,209
+167: 184
+168: 120
+169: 123
+170: 147,244
+171: 147
+172: 
+173: 177,144
+174: 
+175: 
+177: 173
+182: 125
+183: 98,73
+184: 167
+187: 
+218: 137
+245: 
+194: 78,249,64,224
+195: 115,225
+197: 156
+243: 17,84
+199: 
+200: 
+201: 
+202: 214
+212: 
+204: 138,242
+205: 
+207: 127
+208: 
+209: 166,251,81,69,121
+219: 
+224: 249,194
+231: 
+232: 
+233: 
+234: 
+235: 94
+236: 51,247
+237: 
+240: 120
+246: 
+247: 236,51
+248: 157
+249: 78,194,224
+250: 229
+251: 166,209
+252: 64
\ No newline at end of file
Binary file test-data/final_cells.mat has changed
Binary file test-data/final_microenvironment0.mat has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/final_spring_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,153 @@
+210: 
+1: 
+221: 
+225: 
+211: 
+206: 
+108: 17
+230: 96,160
+164: 48
+152: 
+213: 
+137: 51
+143: 
+185: 
+159: 
+229: 
+242: 
+17: 108,243
+102: 
+161: 
+217: 
+115: 
+135: 
+160: 230
+239: 184
+244: 
+106: 
+181: 
+120: 
+112: 
+188: 
+116: 
+125: 
+158: 
+136: 
+186: 
+139: 
+190: 
+124: 
+226: 
+132: 
+238: 
+142: 
+228: 
+148: 
+153: 
+145: 
+123: 
+48: 164
+154: 
+131: 
+51: 247,137
+215: 
+127: 
+216: 
+144: 
+130: 
+57: 98
+214: 165,94
+121: 209
+180: 
+61: 
+163: 
+227: 150
+64: 
+65: 
+138: 
+67: 
+134: 
+69: 
+70: 
+71: 
+72: 
+73: 183
+114: 
+75: 
+76: 
+241: 
+78: 194
+79: 
+150: 227
+81: 209
+82: 
+83: 
+84: 
+151: 
+119: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 214
+95: 
+96: 230
+97: 
+98: 57
+149: 
+146: 
+147: 
+156: 
+157: 
+165: 214
+166: 
+167: 184
+168: 
+169: 
+170: 
+171: 
+172: 
+173: 
+174: 
+175: 
+177: 
+182: 
+183: 73
+184: 167,239
+187: 
+218: 
+245: 
+194: 78
+195: 
+197: 
+243: 17
+199: 
+200: 
+201: 
+202: 
+212: 
+204: 
+205: 
+207: 
+208: 
+209: 121,251,81
+219: 
+224: 
+231: 
+232: 
+233: 
+234: 
+235: 
+236: 
+237: 
+240: 
+246: 
+247: 51
+248: 
+249: 
+250: 
+251: 209
+252: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/initial.svg	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with PhysiCell (http://PhysiCell.MathCancer.org/) -->
+<svg 
+ xmlns:dc="http://purl.org/dc/elements/1.1/" 
+ xmlns:cc="http://creativecommons.org/ns#" 
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+ xmlns:svg="http://www.w3.org/2000/svg" 
+ xmlns="http://www.w3.org/2000/svg" 
+ version="1.1" 
+ width="330" 
+ height="235.4" 
+ id="svg2">
+  <rect x="0" y="0" width="330" height="235.4" stroke-width="0.44" stroke="white" fill="white"/>
+  <text x="2.75" y="6.6"
+   font-family="Arial" font-size="5.5" fill="black" >
+   Current time: 0 days, 0 hours, and 0.00 minutes, z = 0.00 &#956;m
+  </text>
+  <text x="2.75" y="12.65"
+   font-family="Arial" font-size="5.225" fill="black" >
+   128 agents
+  </text>
+ <g id="tissue" 
+    transform="translate(0,235.4) scale(1,-1)">
+  <g id="ECM">
+  </g>
+  <g id="cells">
+   <g id="cell0" type="default" dead="false" >
+  <circle cx="52.7318" cy="218.272" r="6.23542" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell3" type="default" dead="false" >
+  <circle cx="191.157" cy="124.201" r="5.7871" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell27" type="default" dead="false" >
+  <circle cx="224.485" cy="179.039" r="5.63702" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell49" type="default" dead="false" >
+  <circle cx="25.3463" cy="143.367" r="1.01298" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell57" type="default" dead="false" >
+  <circle cx="315.533" cy="148.077" r="5.98617" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell60" type="default" dead="false" >
+  <circle cx="42.9673" cy="37.4551" r="4.43211" stroke-width="0.5" stroke="black" fill="grey"/>
+   </g>
+   <g id="cell64" type="blood_cells" dead="false" >
+  <circle cx="46.8638" cy="39.5511" r="8.40204" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="46.8638" cy="39.5511" r="5.03387" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell66" type="blood_cells" dead="false" >
+  <circle cx="139.057" cy="186.207" r="6.28998" stroke-width="0.5" stroke="black" fill="red"/>
+   </g>
+   <g id="cell72" type="blood_cells" dead="false" >
+  <circle cx="155.065" cy="24.5973" r="7.30388" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="155.065" cy="24.5973" r="2.84469" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell79" type="blood_cells" dead="false" >
+  <circle cx="39.9525" cy="78.6143" r="7.70317" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="39.9525" cy="78.6143" r="3.75293" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell97" type="blood_cells" dead="false" >
+  <circle cx="307.785" cy="150.396" r="8.26678" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="307.785" cy="150.396" r="4.80472" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+   <g id="cell117" type="blood_cells" dead="false" >
+  <circle cx="30.9781" cy="131.92" r="7.92567" stroke-width="0.5" stroke="black" fill="red"/>
+  <circle cx="30.9781" cy="131.92" r="4.1907" stroke-width="0.5" stroke="red" fill="red"/>
+   </g>
+  </g>
+ </g>
+  <rect x="124.5" y="227.7" width="200" height="2.2" stroke-width="0.44" stroke="rgb(255,255,255)" fill="rgb(0,0,0)"/>
+  <text x="125.875" y="226.325"
+   font-family="Arial" font-size="5.5" fill="black" >
+   200 &#956;m
+  </text>
+  <text x="5.5" y="229.9"
+   font-family="Arial" font-size="4.125" fill="black" >
+   0 days, 0 hours, 0 minutes, and 0.0095 seconds
+  </text>
+  <rect x="0" y="15.4" width="330" height="220" stroke-width="0.44" stroke="rgb(0,0,0)" fill="none"/>
+  <rect x="355" y="15.4" width="25" height="195" stroke-width="0.44" stroke="black" fill="none"/>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/initial.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<MultiCellDS version="2" type="snapshot/simulation">
+	<metadata>
+		<software>
+			<name>PhysiCell</name>
+			<version>1.14.1</version>
+			<URL>http://physicell.org</URL>
+			<creator>
+				<orcid-identifier>
+					<path>0000-0002-9925-0151</path>
+					<given-names>Paul</given-names>
+					<family-name>Macklin</family-name>
+					<email>macklinp@iu.edu</email>
+					<url>http://MathCancer.org</url>
+					<organization-name>Indiana University &amp; PhysiCell Project</organization-name>
+					<department-name>Intelligent Systems Engineering</department-name>
+				</orcid-identifier>
+			</creator>
+			<citation>
+				<text>A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin. PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: 10.1371/journal.pcbi.1005991</text>
+				<DOI>10.1371/journal.pcbi.1005991</DOI>
+				<URL>https://dx.doi.org/PMC5841829</URL>
+				<PMID>29474446</PMID>
+				<PMCID>PMC5841829</PMCID>
+			</citation>
+			<user />
+		</software>
+		<citation />
+		<current_time units="min">0.000000</current_time>
+		<current_runtime units="sec">0.008479</current_runtime>
+		<created>2025-01-05T08:14:32Z</created>
+		<last_modified>2025-01-05T08:14:32Z</last_modified>
+	</metadata>
+	<microenvironment>
+		<domain name="microenvironment">
+			<mesh type="Cartesian" uniform="false" regular="true" units="micron">
+				<bounding_box type="axis-aligned" units="micron">-30.000000 -20.000000 -10.000000 300.000000 200.000000 100.000000</bounding_box>
+				<x_coordinates delimiter=" ">-15 15 45 75 105 135 165 195 225 255 285</x_coordinates>
+				<y_coordinates delimiter=" ">-10 10 30 50 70 90 110 130 150 170 190</y_coordinates>
+				<z_coordinates delimiter=" ">-5 5 15 25 35 45 55 65 75 85 95</z_coordinates>
+				<voxels type="matlab">
+					<filename>initial_mesh0.mat</filename>
+				</voxels>
+			</mesh>
+			<variables>
+				<variable name="oxygen" units="dimensionless" ID="0">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">1.000000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+				<variable name="water" units="dimensionless" ID="1">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">0.001000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+			</variables>
+			<data type="matlab">
+				<filename>initial_microenvironment0.mat</filename>
+			</data>
+		</domain>
+	</microenvironment>
+	<cellular_information>
+		<cell_populations>
+			<cell_population type="individual">
+				<custom>
+					<simplified_data type="matlab" source="PhysiCell" data_version="2">
+						<cell_types>
+							<type ID="0" type="0">default</type>
+							<type ID="1" type="1">blood_cells</type>
+						</cell_types>
+						<labels>
+							<label index="0" size="1" units="none">ID</label>
+							<label index="1" size="3" units="microns">position</label>
+							<label index="4" size="1" units="cubic microns">total_volume</label>
+							<label index="5" size="1" units="none">cell_type</label>
+							<label index="6" size="1" units="none">cycle_model</label>
+							<label index="7" size="1" units="none">current_phase</label>
+							<label index="8" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="9" size="1" units="cubic microns">nuclear_volume</label>
+							<label index="10" size="1" units="cubic microns">cytoplasmic_volume</label>
+							<label index="11" size="1" units="none">fluid_fraction</label>
+							<label index="12" size="1" units="none">calcified_fraction</label>
+							<label index="13" size="3" units="none">orientation</label>
+							<label index="16" size="1" units="none">polarity</label>
+							<label index="17" size="3" units="micron/min">velocity</label>
+							<label index="20" size="1" units="none">pressure</label>
+							<label index="21" size="1" units="none">number_of_nuclei</label>
+							<label index="22" size="1" units="min">total_attack_time</label>
+							<label index="23" size="1" units="none">contact_with_basement_membrane</label>
+							<label index="24" size="1" units="1/min">current_cycle_phase_exit_rate</label>
+							<label index="25" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="26" size="1" units="none">dead</label>
+							<label index="27" size="1" units="none">current_death_model</label>
+							<label index="28" size="2" units="1/min">death_rates</label>
+							<label index="30" size="1" units="1/min">cytoplasmic_biomass_change_rate</label>
+							<label index="31" size="1" units="1/min">nuclear_biomass_change_rate</label>
+							<label index="32" size="1" units="1/min">fluid_change_rate</label>
+							<label index="33" size="1" units="1/min">calcification_rate</label>
+							<label index="34" size="1" units="cubic microns">target_solid_cytoplasmic</label>
+							<label index="35" size="1" units="cubic microns">target_solid_nuclear</label>
+							<label index="36" size="1" units="none">target_fluid_fraction</label>
+							<label index="37" size="1" units="microns">radius</label>
+							<label index="38" size="1" units="microns">nuclear_radius</label>
+							<label index="39" size="1" units="square microns">surface_area</label>
+							<label index="40" size="1" units="micron/min">cell_cell_adhesion_strength</label>
+							<label index="41" size="1" units="micron/min">cell_BM_adhesion_strength</label>
+							<label index="42" size="1" units="micron/min">cell_cell_repulsion_strength</label>
+							<label index="43" size="1" units="micron/min">cell_BM_repulsion_strength</label>
+							<label index="44" size="2" units="none">cell_adhesion_affinities</label>
+							<label index="46" size="1" units="none">relative_maximum_adhesion_distance</label>
+							<label index="47" size="1" units="none">maximum_number_of_attachments</label>
+							<label index="48" size="1" units="1/min">attachment_elastic_constant</label>
+							<label index="49" size="1" units="1/min">attachment_rate</label>
+							<label index="50" size="1" units="1/min">detachment_rate</label>
+							<label index="51" size="1" units="none">is_motile</label>
+							<label index="52" size="1" units="min">persistence_time</label>
+							<label index="53" size="1" units="micron/min">migration_speed</label>
+							<label index="54" size="3" units="none">migration_bias_direction</label>
+							<label index="57" size="1" units="none">migration_bias</label>
+							<label index="58" size="3" units="micron/min">motility_vector</label>
+							<label index="61" size="1" units="none">chemotaxis_index</label>
+							<label index="62" size="1" units="none">chemotaxis_direction</label>
+							<label index="63" size="2" units="none">chemotactic_sensitivities</label>
+							<label index="65" size="2" units="1/min">secretion_rates</label>
+							<label index="67" size="2" units="1/min">uptake_rates</label>
+							<label index="69" size="2" units="stuff/cubic micron">saturation_densities</label>
+							<label index="71" size="2" units="stuff/min">net_export_rates</label>
+							<label index="73" size="2" units="stuff">internalized_total_substrates</label>
+							<label index="75" size="2" units="none">fraction_released_at_death</label>
+							<label index="77" size="2" units="none">fraction_transferred_when_ingested</label>
+							<label index="79" size="1" units="1/min">apoptotic_phagocytosis_rate</label>
+							<label index="80" size="1" units="1/min">necrotic_phagocytosis_rate</label>
+							<label index="81" size="1" units="1/min">other_dead_phagocytosis_rate</label>
+							<label index="82" size="2" units="1/min">live_phagocytosis_rates</label>
+							<label index="84" size="2" units="1/min">attack_rates</label>
+							<label index="86" size="2" units="none">immunogenicities</label>
+							<label index="88" size="1" units="none">attack_target</label>
+							<label index="89" size="1" units="1/min">attack_damage_rate</label>
+							<label index="90" size="1" units="min">attack_duration</label>
+							<label index="91" size="1" units="none">attack_total_damage_delivered</label>
+							<label index="92" size="2" units="1/min">fusion_rates</label>
+							<label index="94" size="2" units="1/min">transformation_rates</label>
+							<label index="96" size="2" units="none">asymmetric_division_probabilities</label>
+							<label index="98" size="1" units="none">damage</label>
+							<label index="99" size="1" units="1/min">damage_rate</label>
+							<label index="100" size="1" units="1/min">damage_repair_rate</label>
+							<label index="101" size="1" units="dimensionless">sample</label>
+						</labels>
+						<filename>initial_cells.mat</filename>
+					</simplified_data>
+					<neighbor_graph type="text" source="PhysiCell" data_version="2">
+						<filename>initial_cell_neighbor_graph.txt</filename>
+					</neighbor_graph>
+					<attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>initial_attached_cells_graph.txt</filename>
+					</attached_cells_graph>
+					<spring_attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>initial_spring_attached_cells_graph.txt</filename>
+					</spring_attached_cells_graph>
+				</custom>
+			</cell_population>
+		</cell_populations>
+	</cellular_information>
+</MultiCellDS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/initial_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/initial_cell_neighbor_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
Binary file test-data/initial_cells.mat has changed
Binary file test-data/initial_mesh0.mat has changed
Binary file test-data/initial_microenvironment0.mat has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/initial_spring_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/legend.svg	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with PhysiCell (http://PhysiCell.MathCancer.org/) -->
+<svg 
+ xmlns:dc="http://purl.org/dc/elements/1.1/" 
+ xmlns:cc="http://creativecommons.org/ns#" 
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+ xmlns:svg="http://www.w3.org/2000/svg" 
+ xmlns="http://www.w3.org/2000/svg" 
+ version="1.1" 
+ width="1440" 
+ height="130" 
+ id="svg2">
+  <circle cx="32.5" cy="32.5" r="25" stroke-width="1" stroke="black" fill="grey"/>
+  <circle cx="32.5" cy="32.5" r="12.5" stroke-width="1" stroke="grey" fill="grey"/>
+  <text x="72.5" y="45.25"
+   font-family="Arial" font-size="42.5" fill="black" >
+   default
+  </text>
+  <circle cx="32.5" cy="97.5" r="25" stroke-width="1" stroke="black" fill="red"/>
+  <circle cx="32.5" cy="97.5" r="12.5" stroke-width="1" stroke="red" fill="red"/>
+  <text x="72.5" y="110.25"
+   font-family="Arial" font-size="42.5" fill="black" >
+   blood_cells
+  </text>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000000.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<MultiCellDS version="2" type="snapshot/simulation">
+	<metadata>
+		<software>
+			<name>PhysiCell</name>
+			<version>1.14.1</version>
+			<URL>http://physicell.org</URL>
+			<creator>
+				<orcid-identifier>
+					<path>0000-0002-9925-0151</path>
+					<given-names>Paul</given-names>
+					<family-name>Macklin</family-name>
+					<email>macklinp@iu.edu</email>
+					<url>http://MathCancer.org</url>
+					<organization-name>Indiana University &amp; PhysiCell Project</organization-name>
+					<department-name>Intelligent Systems Engineering</department-name>
+				</orcid-identifier>
+			</creator>
+			<citation>
+				<text>A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin. PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: 10.1371/journal.pcbi.1005991</text>
+				<DOI>10.1371/journal.pcbi.1005991</DOI>
+				<URL>https://dx.doi.org/PMC5841829</URL>
+				<PMID>29474446</PMID>
+				<PMCID>PMC5841829</PMCID>
+			</citation>
+			<user />
+		</software>
+		<citation />
+		<current_time units="min">0.000000</current_time>
+		<current_runtime units="sec">0.000030</current_runtime>
+		<created>2025-01-05T08:14:32Z</created>
+		<last_modified>2025-01-05T08:14:32Z</last_modified>
+	</metadata>
+	<microenvironment>
+		<domain name="microenvironment">
+			<mesh type="Cartesian" uniform="false" regular="true" units="micron">
+				<bounding_box type="axis-aligned" units="micron">-30.000000 -20.000000 -10.000000 300.000000 200.000000 100.000000</bounding_box>
+				<x_coordinates delimiter=" ">-15 15 45 75 105 135 165 195 225 255 285</x_coordinates>
+				<y_coordinates delimiter=" ">-10 10 30 50 70 90 110 130 150 170 190</y_coordinates>
+				<z_coordinates delimiter=" ">-5 5 15 25 35 45 55 65 75 85 95</z_coordinates>
+				<voxels type="matlab">
+					<filename>initial_mesh0.mat</filename>
+				</voxels>
+			</mesh>
+			<variables>
+				<variable name="oxygen" units="dimensionless" ID="0">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">1.000000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+				<variable name="water" units="dimensionless" ID="1">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">0.001000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+			</variables>
+			<data type="matlab">
+				<filename>output00000000_microenvironment0.mat</filename>
+			</data>
+		</domain>
+	</microenvironment>
+	<cellular_information>
+		<cell_populations>
+			<cell_population type="individual">
+				<custom>
+					<simplified_data type="matlab" source="PhysiCell" data_version="2">
+						<cell_types>
+							<type ID="0" type="0">default</type>
+							<type ID="1" type="1">blood_cells</type>
+						</cell_types>
+						<labels>
+							<label index="0" size="1" units="none">ID</label>
+							<label index="1" size="3" units="microns">position</label>
+							<label index="4" size="1" units="cubic microns">total_volume</label>
+							<label index="5" size="1" units="none">cell_type</label>
+							<label index="6" size="1" units="none">cycle_model</label>
+							<label index="7" size="1" units="none">current_phase</label>
+							<label index="8" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="9" size="1" units="cubic microns">nuclear_volume</label>
+							<label index="10" size="1" units="cubic microns">cytoplasmic_volume</label>
+							<label index="11" size="1" units="none">fluid_fraction</label>
+							<label index="12" size="1" units="none">calcified_fraction</label>
+							<label index="13" size="3" units="none">orientation</label>
+							<label index="16" size="1" units="none">polarity</label>
+							<label index="17" size="3" units="micron/min">velocity</label>
+							<label index="20" size="1" units="none">pressure</label>
+							<label index="21" size="1" units="none">number_of_nuclei</label>
+							<label index="22" size="1" units="min">total_attack_time</label>
+							<label index="23" size="1" units="none">contact_with_basement_membrane</label>
+							<label index="24" size="1" units="1/min">current_cycle_phase_exit_rate</label>
+							<label index="25" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="26" size="1" units="none">dead</label>
+							<label index="27" size="1" units="none">current_death_model</label>
+							<label index="28" size="2" units="1/min">death_rates</label>
+							<label index="30" size="1" units="1/min">cytoplasmic_biomass_change_rate</label>
+							<label index="31" size="1" units="1/min">nuclear_biomass_change_rate</label>
+							<label index="32" size="1" units="1/min">fluid_change_rate</label>
+							<label index="33" size="1" units="1/min">calcification_rate</label>
+							<label index="34" size="1" units="cubic microns">target_solid_cytoplasmic</label>
+							<label index="35" size="1" units="cubic microns">target_solid_nuclear</label>
+							<label index="36" size="1" units="none">target_fluid_fraction</label>
+							<label index="37" size="1" units="microns">radius</label>
+							<label index="38" size="1" units="microns">nuclear_radius</label>
+							<label index="39" size="1" units="square microns">surface_area</label>
+							<label index="40" size="1" units="micron/min">cell_cell_adhesion_strength</label>
+							<label index="41" size="1" units="micron/min">cell_BM_adhesion_strength</label>
+							<label index="42" size="1" units="micron/min">cell_cell_repulsion_strength</label>
+							<label index="43" size="1" units="micron/min">cell_BM_repulsion_strength</label>
+							<label index="44" size="2" units="none">cell_adhesion_affinities</label>
+							<label index="46" size="1" units="none">relative_maximum_adhesion_distance</label>
+							<label index="47" size="1" units="none">maximum_number_of_attachments</label>
+							<label index="48" size="1" units="1/min">attachment_elastic_constant</label>
+							<label index="49" size="1" units="1/min">attachment_rate</label>
+							<label index="50" size="1" units="1/min">detachment_rate</label>
+							<label index="51" size="1" units="none">is_motile</label>
+							<label index="52" size="1" units="min">persistence_time</label>
+							<label index="53" size="1" units="micron/min">migration_speed</label>
+							<label index="54" size="3" units="none">migration_bias_direction</label>
+							<label index="57" size="1" units="none">migration_bias</label>
+							<label index="58" size="3" units="micron/min">motility_vector</label>
+							<label index="61" size="1" units="none">chemotaxis_index</label>
+							<label index="62" size="1" units="none">chemotaxis_direction</label>
+							<label index="63" size="2" units="none">chemotactic_sensitivities</label>
+							<label index="65" size="2" units="1/min">secretion_rates</label>
+							<label index="67" size="2" units="1/min">uptake_rates</label>
+							<label index="69" size="2" units="stuff/cubic micron">saturation_densities</label>
+							<label index="71" size="2" units="stuff/min">net_export_rates</label>
+							<label index="73" size="2" units="stuff">internalized_total_substrates</label>
+							<label index="75" size="2" units="none">fraction_released_at_death</label>
+							<label index="77" size="2" units="none">fraction_transferred_when_ingested</label>
+							<label index="79" size="1" units="1/min">apoptotic_phagocytosis_rate</label>
+							<label index="80" size="1" units="1/min">necrotic_phagocytosis_rate</label>
+							<label index="81" size="1" units="1/min">other_dead_phagocytosis_rate</label>
+							<label index="82" size="2" units="1/min">live_phagocytosis_rates</label>
+							<label index="84" size="2" units="1/min">attack_rates</label>
+							<label index="86" size="2" units="none">immunogenicities</label>
+							<label index="88" size="1" units="none">attack_target</label>
+							<label index="89" size="1" units="1/min">attack_damage_rate</label>
+							<label index="90" size="1" units="min">attack_duration</label>
+							<label index="91" size="1" units="none">attack_total_damage_delivered</label>
+							<label index="92" size="2" units="1/min">fusion_rates</label>
+							<label index="94" size="2" units="1/min">transformation_rates</label>
+							<label index="96" size="2" units="none">asymmetric_division_probabilities</label>
+							<label index="98" size="1" units="none">damage</label>
+							<label index="99" size="1" units="1/min">damage_rate</label>
+							<label index="100" size="1" units="1/min">damage_repair_rate</label>
+							<label index="101" size="1" units="dimensionless">sample</label>
+						</labels>
+						<filename>output00000000_cells.mat</filename>
+					</simplified_data>
+					<neighbor_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000000_cell_neighbor_graph.txt</filename>
+					</neighbor_graph>
+					<attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000000_attached_cells_graph.txt</filename>
+					</attached_cells_graph>
+					<spring_attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000000_spring_attached_cells_graph.txt</filename>
+					</spring_attached_cells_graph>
+				</custom>
+			</cell_population>
+		</cell_populations>
+	</cellular_information>
+</MultiCellDS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000000_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000000_cell_neighbor_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
Binary file test-data/output00000000_cells.mat has changed
Binary file test-data/output00000000_microenvironment0.mat has changed
Binary file test-data/output00000000_oxygen.jpeg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000000_spring_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,128 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+15: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+38: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+53: 
+54: 
+55: 
+56: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+104: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+124: 
+125: 
+126: 
+127: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000001.xml	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<MultiCellDS version="2" type="snapshot/simulation">
+	<metadata>
+		<software>
+			<name>PhysiCell</name>
+			<version>1.14.1</version>
+			<URL>http://physicell.org</URL>
+			<creator>
+				<orcid-identifier>
+					<path>0000-0002-9925-0151</path>
+					<given-names>Paul</given-names>
+					<family-name>Macklin</family-name>
+					<email>macklinp@iu.edu</email>
+					<url>http://MathCancer.org</url>
+					<organization-name>Indiana University &amp; PhysiCell Project</organization-name>
+					<department-name>Intelligent Systems Engineering</department-name>
+				</orcid-identifier>
+			</creator>
+			<citation>
+				<text>A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin. PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellular Systems, PLoS Comput. Biol. 14(2): e1005991, 2018. DOI: 10.1371/journal.pcbi.1005991</text>
+				<DOI>10.1371/journal.pcbi.1005991</DOI>
+				<URL>https://dx.doi.org/PMC5841829</URL>
+				<PMID>29474446</PMID>
+				<PMCID>PMC5841829</PMCID>
+			</citation>
+			<user />
+		</software>
+		<citation />
+		<current_time units="min">60.000000</current_time>
+		<current_runtime units="sec">0.510965</current_runtime>
+		<created>2025-01-05T08:14:32Z</created>
+		<last_modified>2025-01-05T08:14:32Z</last_modified>
+	</metadata>
+	<microenvironment>
+		<domain name="microenvironment">
+			<mesh type="Cartesian" uniform="false" regular="true" units="micron">
+				<bounding_box type="axis-aligned" units="micron">-30.000000 -20.000000 -10.000000 300.000000 200.000000 100.000000</bounding_box>
+				<x_coordinates delimiter=" ">-15 15 45 75 105 135 165 195 225 255 285</x_coordinates>
+				<y_coordinates delimiter=" ">-10 10 30 50 70 90 110 130 150 170 190</y_coordinates>
+				<z_coordinates delimiter=" ">-5 5 15 25 35 45 55 65 75 85 95</z_coordinates>
+				<voxels type="matlab">
+					<filename>initial_mesh0.mat</filename>
+				</voxels>
+			</mesh>
+			<variables>
+				<variable name="oxygen" units="dimensionless" ID="0">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">1.000000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+				<variable name="water" units="dimensionless" ID="1">
+					<physical_parameter_set>
+						<conditions />
+						<diffusion_coefficient units="micron^2/min">1000000.000000</diffusion_coefficient>
+						<decay_rate units="1/min">0.001000</decay_rate>
+					</physical_parameter_set>
+				</variable>
+			</variables>
+			<data type="matlab">
+				<filename>output00000001_microenvironment0.mat</filename>
+			</data>
+		</domain>
+	</microenvironment>
+	<cellular_information>
+		<cell_populations>
+			<cell_population type="individual">
+				<custom>
+					<simplified_data type="matlab" source="PhysiCell" data_version="2">
+						<cell_types>
+							<type ID="0" type="0">default</type>
+							<type ID="1" type="1">blood_cells</type>
+						</cell_types>
+						<labels>
+							<label index="0" size="1" units="none">ID</label>
+							<label index="1" size="3" units="microns">position</label>
+							<label index="4" size="1" units="cubic microns">total_volume</label>
+							<label index="5" size="1" units="none">cell_type</label>
+							<label index="6" size="1" units="none">cycle_model</label>
+							<label index="7" size="1" units="none">current_phase</label>
+							<label index="8" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="9" size="1" units="cubic microns">nuclear_volume</label>
+							<label index="10" size="1" units="cubic microns">cytoplasmic_volume</label>
+							<label index="11" size="1" units="none">fluid_fraction</label>
+							<label index="12" size="1" units="none">calcified_fraction</label>
+							<label index="13" size="3" units="none">orientation</label>
+							<label index="16" size="1" units="none">polarity</label>
+							<label index="17" size="3" units="micron/min">velocity</label>
+							<label index="20" size="1" units="none">pressure</label>
+							<label index="21" size="1" units="none">number_of_nuclei</label>
+							<label index="22" size="1" units="min">total_attack_time</label>
+							<label index="23" size="1" units="none">contact_with_basement_membrane</label>
+							<label index="24" size="1" units="1/min">current_cycle_phase_exit_rate</label>
+							<label index="25" size="1" units="min">elapsed_time_in_phase</label>
+							<label index="26" size="1" units="none">dead</label>
+							<label index="27" size="1" units="none">current_death_model</label>
+							<label index="28" size="2" units="1/min">death_rates</label>
+							<label index="30" size="1" units="1/min">cytoplasmic_biomass_change_rate</label>
+							<label index="31" size="1" units="1/min">nuclear_biomass_change_rate</label>
+							<label index="32" size="1" units="1/min">fluid_change_rate</label>
+							<label index="33" size="1" units="1/min">calcification_rate</label>
+							<label index="34" size="1" units="cubic microns">target_solid_cytoplasmic</label>
+							<label index="35" size="1" units="cubic microns">target_solid_nuclear</label>
+							<label index="36" size="1" units="none">target_fluid_fraction</label>
+							<label index="37" size="1" units="microns">radius</label>
+							<label index="38" size="1" units="microns">nuclear_radius</label>
+							<label index="39" size="1" units="square microns">surface_area</label>
+							<label index="40" size="1" units="micron/min">cell_cell_adhesion_strength</label>
+							<label index="41" size="1" units="micron/min">cell_BM_adhesion_strength</label>
+							<label index="42" size="1" units="micron/min">cell_cell_repulsion_strength</label>
+							<label index="43" size="1" units="micron/min">cell_BM_repulsion_strength</label>
+							<label index="44" size="2" units="none">cell_adhesion_affinities</label>
+							<label index="46" size="1" units="none">relative_maximum_adhesion_distance</label>
+							<label index="47" size="1" units="none">maximum_number_of_attachments</label>
+							<label index="48" size="1" units="1/min">attachment_elastic_constant</label>
+							<label index="49" size="1" units="1/min">attachment_rate</label>
+							<label index="50" size="1" units="1/min">detachment_rate</label>
+							<label index="51" size="1" units="none">is_motile</label>
+							<label index="52" size="1" units="min">persistence_time</label>
+							<label index="53" size="1" units="micron/min">migration_speed</label>
+							<label index="54" size="3" units="none">migration_bias_direction</label>
+							<label index="57" size="1" units="none">migration_bias</label>
+							<label index="58" size="3" units="micron/min">motility_vector</label>
+							<label index="61" size="1" units="none">chemotaxis_index</label>
+							<label index="62" size="1" units="none">chemotaxis_direction</label>
+							<label index="63" size="2" units="none">chemotactic_sensitivities</label>
+							<label index="65" size="2" units="1/min">secretion_rates</label>
+							<label index="67" size="2" units="1/min">uptake_rates</label>
+							<label index="69" size="2" units="stuff/cubic micron">saturation_densities</label>
+							<label index="71" size="2" units="stuff/min">net_export_rates</label>
+							<label index="73" size="2" units="stuff">internalized_total_substrates</label>
+							<label index="75" size="2" units="none">fraction_released_at_death</label>
+							<label index="77" size="2" units="none">fraction_transferred_when_ingested</label>
+							<label index="79" size="1" units="1/min">apoptotic_phagocytosis_rate</label>
+							<label index="80" size="1" units="1/min">necrotic_phagocytosis_rate</label>
+							<label index="81" size="1" units="1/min">other_dead_phagocytosis_rate</label>
+							<label index="82" size="2" units="1/min">live_phagocytosis_rates</label>
+							<label index="84" size="2" units="1/min">attack_rates</label>
+							<label index="86" size="2" units="none">immunogenicities</label>
+							<label index="88" size="1" units="none">attack_target</label>
+							<label index="89" size="1" units="1/min">attack_damage_rate</label>
+							<label index="90" size="1" units="min">attack_duration</label>
+							<label index="91" size="1" units="none">attack_total_damage_delivered</label>
+							<label index="92" size="2" units="1/min">fusion_rates</label>
+							<label index="94" size="2" units="1/min">transformation_rates</label>
+							<label index="96" size="2" units="none">asymmetric_division_probabilities</label>
+							<label index="98" size="1" units="none">damage</label>
+							<label index="99" size="1" units="1/min">damage_rate</label>
+							<label index="100" size="1" units="1/min">damage_repair_rate</label>
+							<label index="101" size="1" units="dimensionless">sample</label>
+						</labels>
+						<filename>output00000001_cells.mat</filename>
+					</simplified_data>
+					<neighbor_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000001_cell_neighbor_graph.txt</filename>
+					</neighbor_graph>
+					<attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000001_attached_cells_graph.txt</filename>
+					</attached_cells_graph>
+					<spring_attached_cells_graph type="text" source="PhysiCell" data_version="2">
+						<filename>output00000001_spring_attached_cells_graph.txt</filename>
+					</spring_attached_cells_graph>
+				</custom>
+			</cell_population>
+		</cell_populations>
+	</cellular_information>
+</MultiCellDS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000001_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,125 @@
+0: 
+1: 
+2: 
+3: 
+4: 
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+126: 
+16: 
+17: 
+18: 
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 
+29: 
+30: 
+31: 
+32: 
+33: 
+34: 
+35: 
+36: 
+37: 
+124: 
+39: 
+40: 
+41: 
+42: 
+43: 
+44: 
+45: 
+46: 
+47: 
+48: 
+49: 
+50: 
+51: 
+52: 
+127: 
+54: 
+55: 
+130: 
+57: 
+58: 
+59: 
+60: 
+61: 
+62: 
+63: 
+64: 
+65: 
+66: 
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 
+76: 
+77: 
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 
+96: 
+97: 
+98: 
+99: 
+100: 
+101: 
+102: 
+103: 
+125: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 
+117: 
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 
+131: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000001_cell_neighbor_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,125 @@
+0: 
+1: 68
+2: 
+3: 
+4: 59
+5: 
+6: 
+7: 69,58
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+126: 22
+16: 109
+17: 
+18: 98
+19: 76,94
+20: 106
+21: 
+22: 126
+23: 
+24: 94
+25: 
+26: 
+27: 
+28: 48
+29: 
+30: 
+31: 35
+32: 95
+33: 
+34: 47
+35: 31
+36: 77
+37: 65,123
+124: 
+39: 75
+40: 74,86
+41: 87
+42: 
+43: 
+44: 84
+45: 
+46: 54
+47: 34
+48: 28
+49: 
+50: 60,116
+51: 
+52: 
+127: 75
+54: 46
+55: 
+130: 
+57: 97
+58: 7
+59: 66,4
+60: 64,50
+61: 
+62: 
+63: 
+64: 60
+65: 37
+66: 59
+67: 
+68: 1
+69: 7
+70: 
+71: 
+72: 
+73: 
+74: 40
+75: 127,39
+76: 19,81
+77: 36
+78: 
+79: 116
+80: 73
+81: 76
+82: 
+83: 
+84: 44
+85: 
+86: 40
+87: 41
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 19,24
+95: 32
+96: 
+97: 57
+98: 18
+99: 
+100: 
+101: 
+102: 
+103: 
+125: 121
+105: 
+106: 20
+107: 
+108: 
+109: 16
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 50,79
+117: 
+118: 122
+119: 
+120: 
+121: 125
+122: 118
+123: 37
+131: 
\ No newline at end of file
Binary file test-data/output00000001_cells.mat has changed
Binary file test-data/output00000001_microenvironment0.mat has changed
Binary file test-data/output00000001_oxygen.jpeg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/output00000001_spring_attached_cells_graph.txt	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,125 @@
+0: 
+1: 
+2: 
+3: 
+4: 59
+5: 
+6: 
+7: 
+8: 
+9: 
+10: 
+11: 
+12: 
+13: 
+14: 
+126: 
+16: 
+17: 
+18: 98
+19: 
+20: 
+21: 
+22: 
+23: 
+24: 
+25: 
+26: 
+27: 
+28: 48
+29: 
+30: 
+31: 35
+32: 95
+33: 
+34: 
+35: 31
+36: 77
+37: 123,65
+124: 
+39: 75
+40: 
+41: 
+42: 
+43: 
+44: 84
+45: 
+46: 54
+47: 
+48: 28
+49: 117
+50: 116,60
+51: 
+52: 
+127: 
+54: 46
+55: 
+130: 
+57: 
+58: 
+59: 66,4
+60: 64,50
+61: 
+62: 
+63: 
+64: 60
+65: 37
+66: 59
+67: 
+68: 
+69: 
+70: 
+71: 
+72: 
+73: 
+74: 
+75: 39
+76: 
+77: 36
+78: 
+79: 
+80: 
+81: 
+82: 
+83: 
+84: 44
+85: 
+86: 
+87: 
+88: 
+89: 
+90: 
+91: 
+92: 
+93: 
+94: 
+95: 32
+96: 
+97: 
+98: 18
+99: 
+100: 
+101: 
+102: 
+103: 
+125: 
+105: 
+106: 
+107: 
+108: 
+109: 
+110: 
+111: 
+112: 
+113: 
+114: 
+115: 
+116: 50
+117: 49
+118: 
+119: 
+120: 
+121: 
+122: 
+123: 37
+131: 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/timeseries_cell_attribute_minmax.json	Mon Aug 04 19:00:39 2025 +0000
@@ -0,0 +1,1 @@
+{"apoptotic_phagocytosis_rate": [0.0, 0.0], "asymmetric_division_probabilities_000": [0.0, 0.0], "asymmetric_division_probabilities_001": [0.0, 0.0], "attachment_elastic_constant": [0.01, 0.01], "attachment_rate": [0.0, 0.05], "attack_damage_rate": [1.0, 1.0], "attack_duration": [0.1, 0.1], "attack_target": [-1.0, -1.0], "attack_total_damage_delivered": [0.0, 0.20000000000003126], "blood_cells_attack_rates": [0.0, 0.0025], "blood_cells_cell_adhesion_affinities": [1.0, 1.0], "blood_cells_fusion_rates": [0.0, 0.0], "blood_cells_immunogenicities": [1.0, 1.0], "blood_cells_live_phagocytosis_rates": [0.0, 0.001], "blood_cells_transformation_rates": [0.0, 0.0], "calcification_rate": [0.0, 0.0], "calcified_fraction": [0.0, 0.0], "cell_BM_adhesion_strength": [4.0, 4.0], "cell_BM_repulsion_strength": [100.0, 100.0], "cell_cell_adhesion_strength": [0.4, 0.4], "cell_cell_repulsion_strength": [10.0, 10.0], "cell_count_voxel": [1, 2], "cell_density_micron3": [0.00016666666666666666, 0.0003333333333333333], "cell_type": ["blood_cells", "default"], "chemotaxis_direction": [1.0, 1.0], "chemotaxis_index": ["oxygen", "water"], "contact_with_basement_membrane": [false], "current_cycle_phase_exit_rate": [0.0007199999999424, 0.003333], "current_death_model": ["0"], "current_phase": ["G0G1_phase", "S_phase", "apoptotic", "live"], "cycle_model": ["apoptosis_death_model", "flow_cytometry_separated_cycle_model", "live_cells_cycle_model"], "cytoplasmic_biomass_change_rate": [0.0045, 0.0166667], "cytoplasmic_volume": [983.5947499999987, 5862.0], "damage": [0.0, 0.20000000000003126], "damage_rate": [0.0, 0.0], "damage_repair_rate": [0.0, 0.0], "dead": [false, true], "death_rates_0": [5.31667e-05, 5.31667e-05], "death_rates_1": [0.0, 0.0], "default_attack_rates": [0.0, 0.006], "default_cell_adhesion_affinities": [1.0, 1.0], "default_fusion_rates": [0.0, 0.005], "default_immunogenicities": [1.0, 1.0], "default_live_phagocytosis_rates": [0.0, 0.0005], "default_transformation_rates": [0.0, 0.0], "detachment_rate": [0.0, 0.03], "elapsed_time_in_phase": [0.0, 59.999999999997826], "fluid_change_rate": [0.05, 0.05], "fluid_fraction": [0.6373991145328126, 0.7569238623013873], "is_motile": [false, true], "maximum_number_of_attachments": [12, 12], "migration_bias": [0.2, 0.5], "migration_bias_direction_vectorlength": [0.0, 1.0], "migration_bias_direction_x": [-1.0, 1.0], "migration_bias_direction_y": [-1.0, 1.0], "migration_bias_direction_z": [-1.0, 1.0], "migration_speed": [1.0, 2.5], "motility_vector_vectorlength": [0.0, 2.5000000000000004], "motility_vector_x": [-2.486793550458016, 2.455852993003917], "motility_vector_y": [-2.4966742471817582, 2.2730577339090874], "motility_vector_z": [-2.1068935111770823, 1.8946060981594308], "necrotic_phagocytosis_rate": [0.0, 0.0], "nuclear_biomass_change_rate": [0.0055, 0.00583333], "nuclear_radius": [4.020509832078209, 7.285770189015841], "nuclear_volume": [272.22749999999957, 1620.0], "number_of_nuclei": [1, 3], "orientation_vectorlength": [0.9999999999999999, 1.0], "orientation_x": [-0.9998198763652759, 0.9881209318256264], "orientation_y": [-0.9923765290928437, 0.9980932470125923], "orientation_z": [-0.9988291520969345, 0.9995130292635848], "other_dead_phagocytosis_rate": [0.0, 0.0], "oxygen": [680.3846029534271, 49664.8227525245], "oxygen_chemotactic_sensitivities": [0.0, 0.0], "oxygen_decay_rate": [1.0, 1.0], "oxygen_diffusion_coefficient": [1000.0, 1000.0], "oxygen_fraction_released_at_death": [0.0, 0.0], "oxygen_fraction_transferred_when_ingested": [1.0, 1.0], "oxygen_internalized_total_substrates": [-114595021520.99211, 29061231019.999565], "oxygen_net_export_rates": [0.0, 0.0], "oxygen_saturation_densities": [0.0, 50000.0], "oxygen_secretion_rates": [0.0, 1000.0], "oxygen_uptake_rates": [0.0, 10.0], "persistence_time": [1.0, 1.0], "polarity": [0.0, 0.0], "position_vectorlength": [15.702462882974425, 320.2332747956235], "pressure": [0.0, 3.477442475942624], "radius": [6.692882306092925, 12.133228172907586], "relative_maximum_adhesion_distance": [1.25, 1.25], "sample": [0.0, 1.0], "surface_area": [562.906469544556, 1849.9610886837118], "target_fluid_fraction": [0.0, 0.75], "target_solid_cytoplasmic": [0.0, 1465.5], "target_solid_nuclear": [0.0, 405.0], "total_attack_time": [0.0, 0.20000000000003126], "total_volume": [1255.8222499999983, 7482.0], "velocity_vectorlength": [0.0, 0.0], "velocity_x": [0.0, 0.0], "velocity_y": [0.0, 0.0], "velocity_z": [0.0, 0.0], "water": [937.8055019681188, 1000.0], "water_chemotactic_sensitivities": [0.0, 0.0], "water_decay_rate": [0.001, 0.001], "water_diffusion_coefficient": [1000000.0, 1000000.0], "water_fraction_released_at_death": [0.0, 0.0], "water_fraction_transferred_when_ingested": [1.0, 1.0], "water_internalized_total_substrates": [0.0, 2109883578.3197234], "water_net_export_rates": [0.0, 0.0], "water_saturation_densities": [1.0, 15.0], "water_secretion_rates": [0.0, 5.0], "water_uptake_rates": [0.0, 10.0]}
\ No newline at end of file