Skip to content

Commit 08a46c0

Browse files
committed
added custom model files
1 parent 5c25b85 commit 08a46c0

File tree

13 files changed

+676
-5
lines changed

13 files changed

+676
-5
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import math
2+
3+
import numpy as np
4+
5+
6+
def custom_XY_DSPC(params, bulk_in, bulk_out, contrast):
7+
"""This function makes a model of a supported DSPC bilayer using volume restricted distribution functions."""
8+
# Split up the parameters
9+
subRough = params[0]
10+
oxideThick = params[1]
11+
oxideHydration = params[2]
12+
waterThick = params[3]
13+
lipidAPM = params[4]
14+
lipidCoverage = params[5]
15+
bilayerRough = params[6]
16+
17+
# We are going to need our Neutron scattering cross-sections, plus the component volumes
18+
# (the volumes are taken from Armen et al as usual).
19+
# Define these first
20+
21+
# define all the neutron b's.
22+
bc = 0.6646e-4 # Carbon
23+
bo = 0.5843e-4 # Oxygen
24+
bh = -0.3739e-4 # Hydrogen
25+
bp = 0.513e-4 # Phosphorus
26+
bn = 0.936e-4 # Nitrogen
27+
28+
# Now make the lipid groups
29+
COO = (4 * bo) + (2 * bc)
30+
GLYC = (3 * bc) + (5 * bh)
31+
CH3 = (2 * bc) + (6 * bh)
32+
PO4 = (1 * bp) + (4 * bo)
33+
CH2 = (1 * bc) + (2 * bh)
34+
CHOL = (5 * bc) + (12 * bh) + (1 * bn)
35+
36+
# Group these into heads and tails
37+
heads = CHOL + PO4 + GLYC + COO
38+
tails = (34 * CH2) + (2 * CH3)
39+
40+
# We need volumes for each. Use literature values
41+
vHead = 319
42+
vTail = 782
43+
44+
# Start making our sections. For each we are using a roughened Heaviside to describe our groups.
45+
# We will make these as Volume Fractions (i.e. with a height of 1 for full occupancy),
46+
# which we will correct later for hydration.
47+
48+
# Make an array of z values for our model
49+
z = np.arange(0, 141)
50+
51+
# Make our Silicon substrate
52+
vfSilicon, siSurf = layer(z, -25, 50, 1, subRough, subRough)
53+
54+
# Add the Oxide
55+
vfOxide, oxSurface = layer(z, siSurf, oxideThick, 1, subRough, subRough)
56+
57+
# We fill in the water at the end, but there may be a hydration layer between the bilayer and the oxide,
58+
# so we start the bilayer stack an appropriate distance away
59+
watSurface = oxSurface + waterThick
60+
61+
# Now make the first lipid head group
62+
# Work out the thickness
63+
headThick = vHead / lipidAPM
64+
65+
# ... and make a box for the volume fraction (1 for now, we correct for coverage later)
66+
vfHeadL, headLSurface = layer(z, watSurface, headThick, 1, bilayerRough, bilayerRough)
67+
68+
# ... also do the same for the tails
69+
# We'll make both together, so the thickness will be twice the volume
70+
tailsThick = (2 * vTail) / lipidAPM
71+
vfTails, tailsSurf = layer(z, headLSurface, tailsThick, 1, bilayerRough, bilayerRough)
72+
73+
# Finally the upper head ...
74+
vfHeadR, headSurface = layer(z, tailsSurf, headThick, 1, bilayerRough, bilayerRough)
75+
76+
# Making the model
77+
# We've created the volume fraction profiles corresponding to each of the groups.
78+
# We now convert them to SLDs, taking in account of the hydrations to scale the volume fractions
79+
80+
# 1. Oxide ...
81+
vfOxide = vfOxide * (1 - oxideHydration)
82+
83+
# 2. Lipid ...
84+
# Scale both the heads and tails according to overall coverage
85+
vfTails = vfTails * lipidCoverage
86+
vfHeadL = vfHeadL * lipidCoverage
87+
vfHeadR = vfHeadR * lipidCoverage
88+
89+
# Some extra work to deal with head hydration, which we take to be an additional 30% always
90+
vfHeadL = vfHeadL * 0.7
91+
vfHeadR = vfHeadR * 0.7
92+
93+
# Make a total Volume Fraction across the whole interface
94+
vfTot = vfSilicon + vfOxide + vfHeadL + vfTails + vfHeadR
95+
96+
# All the volume that's left, we will fill with water
97+
vfWat = 1 - vfTot
98+
99+
# Now convert all the Volume Fractions to SLDs
100+
sld_Value_Tails = tails / vTail
101+
sld_Value_Head = heads / vHead
102+
103+
sldSilicon = vfSilicon * 2.073e-6
104+
sldOxide = vfOxide * 3.41e-6
105+
106+
sldHeadL = vfHeadL * sld_Value_Head
107+
sldHeadR = vfHeadR * sld_Value_Head
108+
sldTails = vfTails * sld_Value_Tails
109+
sldWat = vfWat * bulk_out[contrast]
110+
111+
# Put this all together
112+
totSLD = sldSilicon + sldOxide + sldHeadL + sldTails + sldHeadR + sldWat
113+
114+
# Make the SLD array for output
115+
SLD = [[a, b] for (a, b) in zip(z, totSLD)]
116+
117+
return SLD, subRough
118+
119+
120+
def layer(z, prevLaySurf, thickness, height, Sigma_L, Sigma_R):
121+
"""This produces a layer, with a defined thickness, height and roughness.
122+
Each side of the layer has its own roughness value.
123+
"""
124+
# Find the edges
125+
left = prevLaySurf
126+
right = prevLaySurf + thickness
127+
128+
# Make our heaviside
129+
a = (z - left) / ((2**0.5) * Sigma_L)
130+
b = (z - right) / ((2**0.5) * Sigma_R)
131+
132+
erf_a = np.array([math.erf(value) for value in a])
133+
erf_b = np.array([math.erf(value) for value in b])
134+
135+
VF = np.array((height / 2) * (erf_a - erf_b))
136+
137+
return VF, right

examples/DSPC_custom_XY/project.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import numpy as np
2+
3+
4+
def custom_bilayer_DSPC(params, bulk_in, bulk_out, contrast):
5+
"""CUSTOMBILAYER RAT Custom Layer Model File.
6+
7+
This file accepts 3 vectors containing the values for params, bulk in and bulk out.
8+
The final parameter is an index of the contrast being calculated.
9+
10+
The function should output a matrix of layer values, in the form...
11+
12+
Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1
13+
....
14+
thick n, SLD n, Rough n, Percent Hydration n, Hydration how n]
15+
16+
The "hydrate how" parameter decides if the layer is hydrated with Bulk out or Bulk in phases.
17+
Set to 1 for Bulk out, zero for Bulk in.
18+
Alternatively, leave out hydration and just return...
19+
20+
Output = [thick 1, SLD 1, Rough 1,
21+
....
22+
thick n, SLD n, Rough n]
23+
24+
The second output parameter should be the substrate roughness.
25+
"""
26+
sub_rough = params[0]
27+
oxide_thick = params[1]
28+
oxide_hydration = params[2]
29+
lipidAPM = params[3]
30+
headHydration = params[4]
31+
bilayerHydration = params[5]
32+
bilayerRough = params[6]
33+
waterThick = params[7]
34+
35+
# We have a constant SLD for the bilayer
36+
oxide_SLD = 3.41e-6
37+
38+
# Now make the lipid layers
39+
# Use known lipid volume and compositions to make the layers
40+
41+
# define all the neutron b's.
42+
bc = 0.6646e-4 # Carbon
43+
bo = 0.5843e-4 # Oxygen
44+
bh = -0.3739e-4 # Hydrogen
45+
bp = 0.513e-4 # Phosphorus
46+
bn = 0.936e-4 # Nitrogen
47+
48+
# Now make the lipid groups
49+
COO = (4 * bo) + (2 * bc)
50+
GLYC = (3 * bc) + (5 * bh)
51+
CH3 = (2 * bc) + (6 * bh)
52+
PO4 = (1 * bp) + (4 * bo)
53+
CH2 = (1 * bc) + (2 * bh)
54+
CHOL = (5 * bc) + (12 * bh) + (1 * bn)
55+
56+
# Group these into heads and tails:
57+
Head = CHOL + PO4 + GLYC + COO
58+
Tails = (34 * CH2) + (2 * CH3)
59+
60+
# We need volumes for each. Use literature values:
61+
vHead = 319
62+
vTail = 782
63+
64+
# We use the volumes to calculate the SLDs
65+
SLDhead = Head / vHead
66+
SLDtail = Tails / vTail
67+
68+
# We calculate the layer thickness' from the volumes and the APM
69+
headThick = vHead / lipidAPM
70+
tailThick = vTail / lipidAPM
71+
72+
# Manually deal with hydration for layers in this example.
73+
oxSLD = (oxide_hydration * bulk_out[contrast]) + ((1 - oxide_hydration) * oxide_SLD)
74+
headSLD = (headHydration * bulk_out[contrast]) + ((1 - headHydration) * SLDhead)
75+
tailSLD = (bilayerHydration * bulk_out[contrast]) + ((1 - bilayerHydration) * SLDtail)
76+
77+
# Make the layers
78+
oxide = [oxide_thick, oxSLD, sub_rough]
79+
water = [waterThick, bulk_out[contrast], bilayerRough]
80+
head = [headThick, headSLD, bilayerRough]
81+
tail = [tailThick, tailSLD, bilayerRough]
82+
83+
output = np.array([oxide, water, head, tail, tail, head])
84+
85+
return output, sub_rough

examples/DSPC_custom_layers/project.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

examples/absorption/project.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
def volume_thiol_bilayer(params, bulk_in, bulk_out, contrast):
2+
"""VolumeThiolBilayer RAT Custom Layer Model File.
3+
4+
This file accepts 3 vectors containing the values for params, bulk in and bulk out.
5+
The final parameter is an index of the contrast being calculated
6+
7+
The function should output a matrix of layer values, in the form...
8+
9+
Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1
10+
....
11+
thick n, SLD n, Rough n, Percent Hydration n, Hydration how n]
12+
13+
The "hydrate how" parameter decides if the layer is hydrated with Bulk out or Bulk in phases.
14+
Set to 1 for Bulk out, zero for Bulk in.
15+
Alternatively, leave out hydration and just return...
16+
17+
Output = [thick 1, SLD 1, Rough 1,
18+
....
19+
thick n, SLD n, Rough n]
20+
21+
The second output parameter should be the substrate roughness.
22+
"""
23+
subRough = params[0]
24+
alloyThick = params[1]
25+
alloySLDUp = params[2]
26+
alloyISLDUp = params[3]
27+
alloySLDDown = params[4]
28+
alloyISLDDown = params[5]
29+
alloyRough = params[6]
30+
goldThick = params[7]
31+
goldRough = params[8]
32+
goldSLD = params[9]
33+
goldISLD = params[10]
34+
thiolAPM = params[11]
35+
thiolHeadHydr = params[12]
36+
thiolCoverage = params[13]
37+
cwThick = params[14]
38+
bilayerAPM = params[15]
39+
bilHeadHydr = params[16]
40+
bilayerRough = params[17]
41+
bilayerCoverage = params[18]
42+
43+
# Make the metal layers
44+
gold = [goldThick, goldSLD, goldISLD, goldRough]
45+
alloyUp = [alloyThick, alloySLDUp, alloyISLDUp, alloyRough]
46+
alloyDown = [alloyThick, alloySLDDown, alloyISLDDown, alloyRough]
47+
48+
# Neutron b's..
49+
# define all the neutron b's.
50+
bc = 0.6646e-4 # Carbon
51+
bo = 0.5843e-4 # Oxygen
52+
bh = -0.3739e-4 # Hydrogen
53+
bp = 0.513e-4 # Phosphorus
54+
bn = 0.936e-4 # Nitrogen
55+
56+
# Work out the total scattering length in each fragment
57+
# Define scattering lengths
58+
# Hydrogenated version
59+
COO = (2 * bo) + (bc)
60+
GLYC = (3 * bc) + (5 * bh)
61+
CH3 = (1 * bc) + (3 * bh)
62+
PO4 = (1 * bp) + (4 * bo)
63+
CH2 = (1 * bc) + (2 * bh)
64+
CH = (1 * bc) + (1 * bh)
65+
CHOL = (5 * bc) + (12 * bh) + (1 * bn)
66+
67+
# And also volumes
68+
vCH3 = 52.7 # CH3 volume in the paper appears to be for 2 * CH3's
69+
vCH2 = 28.1
70+
vCOO = 39.0
71+
vGLYC = 68.8
72+
vPO4 = 53.7
73+
vCHOL = 120.4
74+
vCHCH = 42.14
75+
76+
vHead = vCHOL + vPO4 + vGLYC + 2 * vCOO
77+
vTail = (28 * vCH2) + (1 * vCHCH) + (2 * vCH3) # Tail volume
78+
79+
# Calculate sum_b's for other fragments
80+
sumbHead = CHOL + PO4 + GLYC + 2 * COO
81+
sumbTail = (28 * CH2) + (2 * CH) + 2 * CH3
82+
83+
# Calculate SLDs and Thickness
84+
sldHead = sumbHead / vHead
85+
thickHead = vHead / thiolAPM
86+
87+
sldTail = sumbTail / vTail
88+
thickTail = vTail / thiolAPM
89+
90+
# Correct head SLD based on hydration
91+
thiolHeadHydr = thiolHeadHydr / 100
92+
sldHead = sldHead * (1 - thiolHeadHydr) + (thiolHeadHydr * bulk_out[contrast])
93+
94+
# Now correct both the SLDs for the coverage parameter
95+
sldTail = (thiolCoverage * sldTail) + ((1 - thiolCoverage) * bulk_out[contrast])
96+
sldHead = (thiolCoverage * sldHead) + ((1 - thiolCoverage) * bulk_out[contrast])
97+
98+
SAMTAILS = [thickTail, sldTail, 0, goldRough]
99+
SAMHEAD = [thickHead, sldHead, 0, goldRough]
100+
101+
# Now do the same for the bilayer
102+
vHead = vCHOL + vPO4 + vGLYC + 2 * vCOO
103+
vTail = 28 * vCH2 # Tail volume
104+
vMe = 2 * vCH3
105+
106+
sumbHead = CHOL + PO4 + GLYC + 2 * COO
107+
sumbTail = 28 * CH2
108+
sumbMe = 2 * CH3
109+
110+
sldHead = sumbHead / vHead
111+
thickHead = vHead / bilayerAPM
112+
bilHeadHydr = bilHeadHydr / 100
113+
sldHead = sldHead * (1 - bilHeadHydr) + (bilHeadHydr * bulk_out[contrast])
114+
115+
sldTail = sumbTail / vTail
116+
thickTail = vTail / bilayerAPM
117+
118+
sldMe = sumbMe / vMe
119+
thickMe = vMe / bilayerAPM
120+
121+
sldTail = (bilayerCoverage * sldTail) + ((1 - bilayerCoverage) * bulk_out[contrast])
122+
sldHead = (bilayerCoverage * sldHead) + ((1 - bilayerCoverage) * bulk_out[contrast])
123+
sldMe = (bilayerCoverage * sldMe) + ((1 - bilayerCoverage) * bulk_out[contrast])
124+
125+
BILTAILS = [thickTail, sldTail, 0, bilayerRough]
126+
BILHEAD = [thickHead, sldHead, 0, bilayerRough]
127+
BILME = [thickMe, sldMe, 0, bilayerRough]
128+
129+
BILAYER = [BILHEAD, BILTAILS, BILME, BILME, BILTAILS, BILHEAD]
130+
131+
CW = [cwThick, bulk_out[contrast], 0, bilayerRough]
132+
133+
if contrast == 1 or contrast == 3:
134+
output = [alloyUp, gold, SAMTAILS, SAMHEAD, CW, *BILAYER]
135+
else:
136+
output = [alloyDown, gold, SAMTAILS, SAMHEAD, CW, *BILAYER]
137+
138+
return output, subRough

0 commit comments

Comments
 (0)