Last active
October 16, 2024 20:13
-
-
Save ximeg/4436fb1e17dfda50b7d46e8c1976ad6b to your computer and use it in GitHub Desktop.
Microarrayer layout generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HEADER = """\ | |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
<IndirectPrinting> | |
""" | |
FOOTER = """\ | |
<Attributes> | |
<PrintName>CustomPrint</PrintName> | |
<Originals>4</Originals> | |
<Replicants>{Replicants}</Replicants> | |
<maxInXDir>{maxInXDir}</maxInXDir> | |
<maxInYDir>{maxInYDir}</maxInYDir> | |
</Attributes> | |
<integrity>Lnu0jwyG1z2wa9ReqqU3lHDT36vkrLmFErBTt00iBTMDHn916BMMCA..</integrity> | |
</IndirectPrinting> | |
""" | |
SAMPLE = """\ | |
<Sample> | |
<SampleNumber>{SampleNumber}</SampleNumber> | |
<SpotNumber>{SpotNumber}</SpotNumber> | |
<SpotRow>{SpotRow}</SpotRow> | |
<SpotCol>{SpotCol}</SpotCol> | |
<SampleLabel>{SampleNumber}:{SpotNumber}</SampleLabel> | |
<Depositions>1</Depositions> | |
</Sample> | |
""" | |
data = dict(SampleNumber=1, SpotNumber=0, SpotRow=3, SpotCol=4) | |
samples = "" | |
ROWS = 20 | |
COLS = 5 | |
cell_size = 80 # um | |
spot2spot = 2 # cells | |
fov2fov = 5 # cells | |
maxInXDir = COLS * fov2fov | |
maxInYDir = ROWS * fov2fov | |
for SampleNumber in range(1, 5): | |
SpotNumber = 0 | |
i = (0 if SampleNumber <= 2 else 1) * spot2spot | |
j = ((SampleNumber - 1) % 2) * spot2spot | |
for SpotRow in range(i, i + maxInYDir, fov2fov): | |
for SpotCol in range(j, j + maxInXDir, fov2fov): | |
samples += SAMPLE.format( | |
SampleNumber=SampleNumber, | |
SpotNumber=SpotNumber, | |
SpotRow=SpotRow, | |
SpotCol=SpotCol, | |
) | |
SpotNumber += 1 | |
with open("out.xml", "w") as output_file: | |
output_file.write(HEADER) | |
output_file.write(samples) | |
output_file.write( | |
FOOTER.format( | |
Replicants=ROWS * COLS, | |
maxInXDir=maxInXDir - spot2spot, | |
maxInYDir=maxInYDir - spot2spot, | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FNAME = "5um distance test 120-170.xml" | |
HEADER = """\ | |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
<IndirectPrinting> | |
""" | |
FOOTER = """\ | |
<Attributes> | |
<PrintName>CustomPrint</PrintName> | |
<Originals>4</Originals> | |
<Replicants>{Replicants}</Replicants> | |
<maxInXDir>{maxInXDir}</maxInXDir> | |
<maxInYDir>{maxInYDir}</maxInYDir> | |
</Attributes> | |
<integrity>Lnu0jwyG1z2wa9ReqqU3lHDT36vkrLmFErBTt00iBTMDHn916BMMCA..</integrity> | |
</IndirectPrinting> | |
""" | |
SAMPLE = """\ | |
<Sample> | |
<SampleNumber>{SampleNumber}</SampleNumber> | |
<SpotNumber>{SpotNumber}</SpotNumber> | |
<SpotRow>{SpotRow}</SpotRow> | |
<SpotCol>{SpotCol}</SpotCol> | |
<SampleLabel>{SampleNumber}:{SpotNumber}</SampleLabel> | |
<Depositions>1</Depositions> | |
</Sample> | |
""" | |
import numpy as np | |
data = dict(SampleNumber=1, SpotNumber=0, SpotRow=3, SpotCol=4) | |
samples = "" | |
cell_size = 5 # um | |
dMIN = 120 | |
dMAX = 170 | |
XREPS = 3 | |
xgrid = np.arange(dMIN / cell_size, (dMAX + cell_size) / cell_size).astype(int) | |
maxInXDir = 0 | |
maxInYDir = 0 | |
SpotNumber = 0 | |
for rep in range(XREPS): | |
x_origin = int(rep * dMAX * 3 / cell_size) | |
for row, N in enumerate(reversed(xgrid)): | |
samples += SAMPLE.format( | |
SampleNumber=1, | |
SpotNumber=SpotNumber, | |
SpotRow=row, | |
SpotCol=x_origin, | |
) | |
SpotNumber += 1 | |
samples += SAMPLE.format( | |
SampleNumber=1, | |
SpotNumber=SpotNumber, | |
SpotRow=row, | |
SpotCol=x_origin + N, | |
) | |
SpotNumber += 1 | |
maxInXDir = max(maxInXDir, row) | |
maxInYDir = max(maxInYDir, x_origin + N) | |
with open(FNAME, "w") as output_file: | |
output_file.write(HEADER) | |
output_file.write(samples) | |
output_file.write( | |
FOOTER.format( | |
Replicants=SpotNumber, | |
maxInXDir=maxInXDir, | |
maxInYDir=maxInYDir, | |
) | |
) | |
print( | |
f"""Spacing: x={cell_size}um, y={dMAX*3} | |
Array size: W={maxInXDir*cell_size/1000}mm, H={dMAX*3*len(xgrid)}mm""" | |
) | |
import xml.etree.ElementTree as ET | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
# Parse the XML file | |
tree = ET.parse(FNAME) | |
root = tree.getroot() | |
# Extract data and store in a list of dictionaries | |
samples = [] | |
for sample in root.findall("Sample"): | |
sample_data = { | |
"SampleNumber": int(sample.find("SampleNumber").text), | |
"SpotNumber": int(sample.find("SpotNumber").text), | |
"SpotRow": int(sample.find("SpotRow").text), | |
"SpotCol": int(sample.find("SpotCol").text), | |
"SampleLabel": sample.find("SampleLabel").text, | |
"Depositions": int(sample.find("Depositions").text), | |
} | |
samples.append(sample_data) | |
# Convert to DataFrame | |
df = pd.DataFrame(samples) | |
# Print the DataFrame | |
print(df) | |
# Visualize spot positions on a grid | |
plt.figure(figsize=(8, 6)) | |
plt.scatter(df["SpotCol"], df["SpotRow"], s=100, c=df["SampleNumber"], marker="o") | |
# Annotate spots with their labels | |
for i, label in enumerate(df["SampleLabel"]): | |
plt.annotate( | |
label, | |
(df["SpotCol"][i], df["SpotRow"][i]), | |
textcoords="offset points", | |
xytext=(0, 10), | |
ha="center", | |
) | |
plt.gca().invert_yaxis() # Invert y-axis to match typical grid layout | |
plt.xlabel("SpotCol") | |
plt.ylabel("SpotRow") | |
plt.title("Spot Positions on Grid") | |
# Set up major and minor ticks | |
plt.gca().xaxis.set_major_locator(plt.MultipleLocator(10 * cell_size)) | |
plt.gca().yaxis.set_major_locator(plt.MultipleLocator(10)) | |
plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(cell_size)) | |
plt.gca().yaxis.set_minor_locator(plt.MultipleLocator(1)) | |
# Show grid lines | |
plt.grid(which="major", color="black", linestyle="-", linewidth=0.75) | |
plt.grid(which="minor", color="gray", linestyle=":", linewidth=0.5) | |
plt.grid(True) | |
# plt.gca().set_aspect("equal", adjustable="box") | |
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import xml.etree.ElementTree as ET | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
# Parse the XML file | |
tree = ET.parse('4spots 160um 400um 6x20.xml') | |
root = tree.getroot() | |
# Extract data and store in a list of dictionaries | |
samples = [] | |
for sample in root.findall('Sample'): | |
sample_data = { | |
'SampleNumber': int(sample.find('SampleNumber').text), | |
'SpotNumber': int(sample.find('SpotNumber').text), | |
'SpotRow': int(sample.find('SpotRow').text), | |
'SpotCol': int(sample.find('SpotCol').text), | |
'SampleLabel': sample.find('SampleLabel').text, | |
'Depositions': int(sample.find('Depositions').text) | |
} | |
samples.append(sample_data) | |
# Convert to DataFrame | |
df = pd.DataFrame(samples) | |
# Print the DataFrame | |
print(df) | |
# Visualize spot positions on a grid | |
plt.figure(figsize=(8, 6)) | |
plt.scatter(df['SpotCol'], df['SpotRow'], s=100, c=df['SampleNumber'], marker='o') | |
# Annotate spots with their labels | |
for i, label in enumerate(df['SampleLabel']): | |
plt.annotate(label, (df['SpotCol'][i], df['SpotRow'][i]), textcoords="offset points", xytext=(0,10), ha='center') | |
plt.gca().invert_yaxis() # Invert y-axis to match typical grid layout | |
plt.xlabel('SpotCol') | |
plt.ylabel('SpotRow') | |
plt.title('Spot Positions on Grid') | |
plt.grid(True) | |
plt.gca().set_aspect('equal', adjustable='box') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment