Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds example projects #59

Merged
merged 3 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/DSPC_custom_XY/controls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"procedure":"calculate","parallel":"single","calcSldDuringFit":false,"resampleMinAngle":0.9,"resampleNPoints":50,"display":"iter"}
137 changes: 137 additions & 0 deletions examples/DSPC_custom_XY/custom_XY_DSPC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import math

import numpy as np


def custom_XY_DSPC(params, bulk_in, bulk_out, contrast):
"""This function makes a model of a supported DSPC bilayer using volume restricted distribution functions."""
# Split up the parameters
subRough = params[0]
oxideThick = params[1]
oxideHydration = params[2]
waterThick = params[3]
lipidAPM = params[4]
lipidCoverage = params[5]
bilayerRough = params[6]

# We are going to need our Neutron scattering cross-sections, plus the component volumes
# (the volumes are taken from Armen et al as usual).
# Define these first

# define all the neutron b's.
bc = 0.6646e-4 # Carbon
bo = 0.5843e-4 # Oxygen
bh = -0.3739e-4 # Hydrogen
bp = 0.513e-4 # Phosphorus
bn = 0.936e-4 # Nitrogen

# Now make the lipid groups
COO = (4 * bo) + (2 * bc)
GLYC = (3 * bc) + (5 * bh)
CH3 = (2 * bc) + (6 * bh)
PO4 = (1 * bp) + (4 * bo)
CH2 = (1 * bc) + (2 * bh)
CHOL = (5 * bc) + (12 * bh) + (1 * bn)

# Group these into heads and tails
heads = CHOL + PO4 + GLYC + COO
tails = (34 * CH2) + (2 * CH3)

# We need volumes for each. Use literature values
vHead = 319
vTail = 782

# Start making our sections. For each we are using a roughened Heaviside to describe our groups.
# We will make these as Volume Fractions (i.e. with a height of 1 for full occupancy),
# which we will correct later for hydration.

# Make an array of z values for our model
z = np.arange(0, 141)

# Make our Silicon substrate
vfSilicon, siSurf = layer(z, -25, 50, 1, subRough, subRough)

# Add the Oxide
vfOxide, oxSurface = layer(z, siSurf, oxideThick, 1, subRough, subRough)

# We fill in the water at the end, but there may be a hydration layer between the bilayer and the oxide,
# so we start the bilayer stack an appropriate distance away
watSurface = oxSurface + waterThick

# Now make the first lipid head group
# Work out the thickness
headThick = vHead / lipidAPM

# ... and make a box for the volume fraction (1 for now, we correct for coverage later)
vfHeadL, headLSurface = layer(z, watSurface, headThick, 1, bilayerRough, bilayerRough)

# ... also do the same for the tails
# We'll make both together, so the thickness will be twice the volume
tailsThick = (2 * vTail) / lipidAPM
vfTails, tailsSurf = layer(z, headLSurface, tailsThick, 1, bilayerRough, bilayerRough)

# Finally the upper head ...
vfHeadR, headSurface = layer(z, tailsSurf, headThick, 1, bilayerRough, bilayerRough)

# Making the model
# We've created the volume fraction profiles corresponding to each of the groups.
# We now convert them to SLDs, taking in account of the hydrations to scale the volume fractions

# 1. Oxide ...
vfOxide = vfOxide * (1 - oxideHydration)

# 2. Lipid ...
# Scale both the heads and tails according to overall coverage
vfTails = vfTails * lipidCoverage
vfHeadL = vfHeadL * lipidCoverage
vfHeadR = vfHeadR * lipidCoverage

# Some extra work to deal with head hydration, which we take to be an additional 30% always
vfHeadL = vfHeadL * 0.7
vfHeadR = vfHeadR * 0.7

# Make a total Volume Fraction across the whole interface
vfTot = vfSilicon + vfOxide + vfHeadL + vfTails + vfHeadR

# All the volume that's left, we will fill with water
vfWat = 1 - vfTot

# Now convert all the Volume Fractions to SLDs
sld_Value_Tails = tails / vTail
sld_Value_Head = heads / vHead

sldSilicon = vfSilicon * 2.073e-6
sldOxide = vfOxide * 3.41e-6

sldHeadL = vfHeadL * sld_Value_Head
sldHeadR = vfHeadR * sld_Value_Head
sldTails = vfTails * sld_Value_Tails
sldWat = vfWat * bulk_out[contrast]

# Put this all together
totSLD = sldSilicon + sldOxide + sldHeadL + sldTails + sldHeadR + sldWat

# Make the SLD array for output
SLD = [[a, b] for (a, b) in zip(z, totSLD)]

return SLD, subRough


def layer(z, prevLaySurf, thickness, height, Sigma_L, Sigma_R):
"""This produces a layer, with a defined thickness, height and roughness.
Each side of the layer has its own roughness value.
"""
# Find the edges
left = prevLaySurf
right = prevLaySurf + thickness

# Make our heaviside
a = (z - left) / ((2**0.5) * Sigma_L)
b = (z - right) / ((2**0.5) * Sigma_R)

erf_a = np.array([math.erf(value) for value in a])
erf_b = np.array([math.erf(value) for value in b])

VF = np.array((height / 2) * (erf_a - erf_b))

return VF, right
1 change: 1 addition & 0 deletions examples/DSPC_custom_XY/project.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/DSPC_custom_layers/controls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"procedure":"calculate","parallel":"single","calcSldDuringFit":false,"resampleMinAngle":0.9,"resampleNPoints":50,"display":"iter"}
85 changes: 85 additions & 0 deletions examples/DSPC_custom_layers/custom_bilayer_DSPC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import numpy as np


def custom_bilayer_DSPC(params, bulk_in, bulk_out, contrast):
"""CUSTOMBILAYER RAT Custom Layer Model File.

This file accepts 3 vectors containing the values for params, bulk in and bulk out.
The final parameter is an index of the contrast being calculated.

The function should output a matrix of layer values, in the form...

Output = [thick 1, SLD 1, Rough 1, Percent Hydration 1, Hydrate how 1
....
thick n, SLD n, Rough n, Percent Hydration n, Hydration how n]

The "hydrate how" parameter decides if the layer is hydrated with Bulk out or Bulk in phases.
Set to 1 for Bulk out, zero for Bulk in.
Alternatively, leave out hydration and just return...

Output = [thick 1, SLD 1, Rough 1,
....
thick n, SLD n, Rough n]

The second output parameter should be the substrate roughness.
"""
sub_rough = params[0]
oxide_thick = params[1]
oxide_hydration = params[2]
lipidAPM = params[3]
headHydration = params[4]
bilayerHydration = params[5]
bilayerRough = params[6]
waterThick = params[7]

# We have a constant SLD for the bilayer
oxide_SLD = 3.41e-6

# Now make the lipid layers
# Use known lipid volume and compositions to make the layers

# define all the neutron b's.
bc = 0.6646e-4 # Carbon
bo = 0.5843e-4 # Oxygen
bh = -0.3739e-4 # Hydrogen
bp = 0.513e-4 # Phosphorus
bn = 0.936e-4 # Nitrogen

# Now make the lipid groups
COO = (4 * bo) + (2 * bc)
GLYC = (3 * bc) + (5 * bh)
CH3 = (2 * bc) + (6 * bh)
PO4 = (1 * bp) + (4 * bo)
CH2 = (1 * bc) + (2 * bh)
CHOL = (5 * bc) + (12 * bh) + (1 * bn)

# Group these into heads and tails:
Head = CHOL + PO4 + GLYC + COO
Tails = (34 * CH2) + (2 * CH3)

# We need volumes for each. Use literature values:
vHead = 319
vTail = 782

# We use the volumes to calculate the SLDs
SLDhead = Head / vHead
SLDtail = Tails / vTail

# We calculate the layer thickness' from the volumes and the APM
headThick = vHead / lipidAPM
tailThick = vTail / lipidAPM

# Manually deal with hydration for layers in this example.
oxSLD = (oxide_hydration * bulk_out[contrast]) + ((1 - oxide_hydration) * oxide_SLD)
headSLD = (headHydration * bulk_out[contrast]) + ((1 - headHydration) * SLDhead)
tailSLD = (bilayerHydration * bulk_out[contrast]) + ((1 - bilayerHydration) * SLDtail)

# Make the layers
oxide = [oxide_thick, oxSLD, sub_rough]
water = [waterThick, bulk_out[contrast], bilayerRough]
head = [headThick, headSLD, bilayerRough]
tail = [tailThick, tailSLD, bilayerRough]

output = np.array([oxide, water, head, tail, tail, head])

return output, sub_rough
1 change: 1 addition & 0 deletions examples/DSPC_custom_layers/project.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/DSPC_standard_layers/controls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"procedure":"calculate","parallel":"single","calcSldDuringFit":false,"resampleMinAngle":0.9,"resampleNPoints":50,"display":"iter"}
Loading
Loading