Making large scale structures in Geant4¶
Geant4 simulations use a large scale structure
[ ]:
import sys
from pathlib import Path
try:
# The voxelisation library produces the cubic voxelisation that
# can be used to build DNA
from fractaldna.structure_models import voxelisation as v
# The hilbert module produces and handles L-Strings
from fractaldna.structure_models import hilbert as h
except (ImportError, ModuleNotFoundError):
sys.path.append(str(Path.cwd().parent.parent.parent))
from fractaldna.structure_models import voxelisation as v
from fractaldna.structure_models import hilbert as h
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
Fractal Cell Shapes¶
Generating a square shape¶
[ ]:
# Start with the initial L-String X for a Hilbert Curve
initial_string = "X"
# Iterate it as required (here, nn=3)
# for nn = 8, this takes about two hours on my 16GB RAM Mac
nn = 3
iterated_lstring = h.iterate_lstring(initial_string)
for _ in range(nn - 1):
iterated_lstring = h.iterate_lstring(iterated_lstring)
vf = v.VoxelisedFractal.fromLString(iterated_lstring, pbar=True)
vf.center_fractal()
# fig = vf.to_plot()
# fig.savefig('results/fractal-X-3-centred.svg')
# If you are saving a BIG fractal, try using the to_text() method instead
# as large dataframes are very slow to generate beyond 6 iterations.
# (Very slow as in multiple hours slow!)
# with open(f'results/fractal-X-{nn}-centred.csv', 'w') as ff:
# ff.write(vf.to_text())
vf.to_frame().to_csv(f"results/fractal-X-{nn}-centred.csv", index=False, sep=" ")
Generating a Rectangular Shape¶
The seed XFXFX
will generate a rectangular shape with aspect ratio 1:1:3
[ ]:
# Start with the initial L-String XFXFX for a Hilbert Curve
initial_string = "XFXFX"
# Iterate it as required (here, nn=4)
nn = 4
iterated_lstring = h.iterate_lstring(initial_string)
for _ in range(nn - 1):
iterated_lstring = h.iterate_lstring(iterated_lstring)
vf = v.VoxelisedFractal.fromLString(iterated_lstring, pbar=True)
vf.center_fractal()
# fig = vf.to_plot()
# fig.savefig(f'results/fractal-XFXFX-{nn}-centred.svg')
vf.to_frame().to_csv(f"results/fractal-XFXFX-{nn}-centred.csv", index=False, sep=" ")
Note that the x-axis is compressed relative to the others in the below image
Importing a shape from a path¶
The voxelisation
model can convert the path of this curve to a voxelised representation, of straight and curved boxes.
In this example we perform this on a text file with X/Y/Z columns:
X Y Z
-22 -106 216
-22 -107 216
-22 -107 215
-22 -108 215
-22 -108 214
-23 -108 214
-23 -109 214
[ ]:
%%capture
df = pd.read_csv("results/example-path.csv", sep="\t")
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot(df.X, df.Y, df.Z)
fig.savefig("example-path.svg")
vf = v.VoxelisedFractal.from_path(df.values)
fig_fractal = vf.to_plot()
fig_fractal.savefig("example-path-voxels.svg")
vf.to_frame().to_csv("results/example-path-voxels.csv", sep=" ", index=False)
Left: Source Plot, Right:Voxelised Plot
Generating Random Volumes¶
It can be useful to generate randomised volumes for testing a simulation. This was the subject of (this article)[https://doi.org/10.1016/j.ejmp.2018.02.011].
To generate a randomised volume, the fractaldna.structure_models.random_placements
is available.
In that paper, 200,000 non overlapping prisms were simulated in a r=3000nm ball. The prisms had dimensions 30x30x100nm
[ ]:
from fractaldna.structure_models import random_placements as rp
# Generating 200,000 prisms can take around 4-5 hours
prisms = rp.generate_non_overlapping_prisms(
n_prisms=200_000,
size=[30, 30, 100], # nanometres
rad=3000, # nanometres
early_exit=-1,
verbose=True,
)
df = prisms.to_frame()
df.to_csv("results/prisms_200k_r3000.csv", sep=" ", index=False)