Skip to content

Commit

Permalink
Merge pull request #43 from PhysiCell-Models/dev
Browse files Browse the repository at this point in the history
Dev to Main - final scripts for processing Painter data
  • Loading branch information
johnmetzcar authored Sep 16, 2024
2 parents 1a14d48 + 866fb28 commit 651d2df
Show file tree
Hide file tree
Showing 18 changed files with 954 additions and 6 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
- uses: actions/checkout@v3

- name: Install dependencies
run : brew install gcc@11
run : brew install gcc@13

- name: Build model
run: |
make PHYSICELL_CPP=g++-11
make invasive_carcinoma PHYSICELL_CPP=g++-11
make fibrosis PHYSICELL_CPP=g++-11
make PHYSICELL_CPP=g++-13
make invasive_carcinoma PHYSICELL_CPP=g++-13
make fibrosis PHYSICELL_CPP=g++-13
- name: Run model
run: |
Expand Down
2 changes: 1 addition & 1 deletion python_imaging/image_processing_for_physicell.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ def create_density_histogram(self, histogram_options=None, options: dict=None):

# Add a horizontal line at 95% of total count
inset_ax.axvline(x=bin_centers[percentile_95], color='blue', linestyle='--')

print('95th percentile value:', bin_centers[percentile_95])
# Set the same y-axis limits for the inset
inset_ax.set_xlim(-500, 500)
# inset_ax.set_xlim(0, inset_ax.get_xlim()[1])
Expand Down
78 changes: 78 additions & 0 deletions scripts/data_analysis_Painter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import numpy as np
import csv


try:
from pyMCDS_ECM import *
except ImportError:
from pyMCDS import *


## Adapting the code from the image processing code - create_density_histogram function.
## I don't need the histogram - just the 95th percentile value - converted back from bin number to position.

def create_density_histogram(mcds):

# inherited from the image processing code
num_bins = 40

y_positions = mcds.data['discrete_cells']['position_y']

# Create a 1D histogram of the y-positions, ensuring the range spans -500 to 500
hist, bin_edges = np.histogram(y_positions, bins=num_bins, range=(-500, 500)) ## not automatic

# Print the histogram counts
print("Histogram counts for each bin:")
for i, count in enumerate(hist):
print(f"Bin {i+1}: {count} counts")

bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2

# Calculate the cumulative sum and find the 95th percentile value
cumulative_counts = np.cumsum(hist)

total_count = cumulative_counts[-1]
percentile_95 = np.searchsorted(cumulative_counts, 0.95 * total_count)

print(f"95th percentile bin number: {percentile_95}")
print(f"95th percentile center of bin in um: {bin_centers[percentile_95]}")
# to doulbe check - print bin centers then bin edges
# print(bin_centers)
# print(bin_edges)

return bin_centers[percentile_95]

percentile_centers = []
for n in range(1, 21):
# folder name needs padded with 1 zero
if n < 10:
folder_name = "0" + str(n)
else:
folder_name = str(n)

# Parameters
# ----------
# xml_name: str
# String containing the name of the xml file without the path
# output_path: str, optional
# String containing the path (relative or absolute) to the directory
# where PhysiCell output files are stored (default= ".")

mcds = pyMCDS('output00000005.xml', folder_name)


percentile_centers.append(create_density_histogram(mcds))

# add in value for the extra run (the run used for detail in the paper)

percentile_centers.append(0.0) # placeholder for the extra run - these were determined by outputing the value from the image processing code. so just make the image
# processing code output the value and then copy it here.

print(percentile_centers)
print('Mean of 95th percentile centers:')
print(np.mean(percentile_centers))

print('Standard deviation of 95th percentile centers:')
print(np.std(percentile_centers))

np.savetxt("95th_percentile_center.csv", percentile_centers, delimiter=",", fmt="%s") # rename as needed
76 changes: 76 additions & 0 deletions scripts/invasive_front_vizualization_of_variance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# Read the CSV files into DataFrames
df_parallel = pd.read_csv('../Painter_data/95th_percentile_center_parallel.csv', header=None, names=['Position'])
df_perpendicular = pd.read_csv('../Painter_data/95th_percentile_center_orthogonal.csv', header=None, names=['Position'])
df_random = pd.read_csv('../Painter_data/95th_percentile_center_random.csv', header=None, names=['Position'])

# Add a 'Category' column to each DataFrame to differentiate the data
df_parallel['Category'] = 'Parallel'
df_perpendicular['Category'] = 'Perpendicular'
df_random['Category'] = 'Random'

# Combine the DataFrames into a single DataFrame
df_combined = pd.concat([df_random, df_parallel, df_perpendicular])

# Assuming the positional data is in a column called 'Position' in the CSV files
# If the column name is different, replace 'Position' with the actual name
sns.set(style="whitegrid")

# Create the beeswarm plot to show variations
fig, ax = plt.subplots(figsize=(5, 6))
# ax = sns.stripplot(x='Category', y='Position', data=df_combined, size=8)

# # plot the mean line
# sns.boxplot(showmeans=True,
# meanline=True,
# meanprops={'color': 'k'},
# medianprops={'visible': False},
# whiskerprops={'visible': False},
# zorder=10,
# x="Category",
# y="Position",
# data=df_combined,
# showfliers=False,
# showbox=False,
# showcaps=False,
# ax=ax)



# Boxplot to show distribution statistics, mean is shown as a green triangle
sns.boxplot(x='Category', y='Position', data=df_combined, showmeans=True, meanline=True, width=0.3,
# meanprops={"marker":".", "markerfacecolor":"red", "markeredgecolor":"red", "markersize":"5"},
boxprops=dict(alpha=0.7), ax=ax)

sns.pointplot(x='Category', y='Position', data=df_combined, estimator=np.mean, join=False, color='red', markers='o', scale=0.75, ax=ax)

# Jitter plot (strip plot) overlayed on the boxplot
sns.stripplot(x='Category', y='Position', data=df_combined, jitter=True, size=5, color='black', alpha=0.5, ax=ax)

plt.tick_params(axis='x', which='major', labelsize=14)
plt.tick_params(axis='y', which='major', labelsize=14)

# Customize the plot

# Set y-axis intervals to 125
plt.yticks(range(-500, 501, 125))

# Add grid lines
ax.set_axisbelow(True) # https://stackoverflow.com/questions/1726391/matplotlib-draw-grid-lines-behind-other-graph-elements # Not workign - but overall fig gets job done.

# plt.rc('axes', axisbelow=True)
ax.yaxis.grid(linestyle='--', linewidth=0.7)

plt.ylabel('Position (µm)', fontsize=16)
plt.xlabel('', fontsize=2)
plt.ylim(-500, 500) # Set limits based on your preference
plt.tight_layout()
# Save figure
plt.savefig('painter_extent_of_invasive_front.png', dpi=300)

# Show the plot
plt.show()
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
make -j4
make fibrosis -j4
make invasive_spheroid -j4
make invasive_carcinoma -j4
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 651d2df

Please sign in to comment.