Skip to content

Instantly share code, notes, and snippets.

@ximeg
Last active October 16, 2024 20:13
Show Gist options
  • Save ximeg/4436fb1e17dfda50b7d46e8c1976ad6b to your computer and use it in GitHub Desktop.
Save ximeg/4436fb1e17dfda50b7d46e8c1976ad6b to your computer and use it in GitHub Desktop.
Microarrayer layout generator
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,
)
)
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()
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