Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
be46c3c
Adds validation and changes "ClassList.set_fields" functionality
DrPaulSharp Apr 30, 2024
e1f3184
Adds domains examples
DrPaulSharp Apr 30, 2024
ca430df
Adds non polarised examples
DrPaulSharp Apr 30, 2024
c2d1881
Adds absorption example
DrPaulSharp Apr 30, 2024
8183a75
Adds example for custom functions in different languages
DrPaulSharp May 1, 2024
1b4db49
Updates cells in "make_input.py"
DrPaulSharp May 1, 2024
3adcf6c
Adds "function_name" field to customFile model
DrPaulSharp May 2, 2024
de981c4
Adds wrappers for custom functions
DrPaulSharp May 7, 2024
c645b58
Fixes bug when adding data in "inputs.py"
DrPaulSharp Jun 12, 2024
5f1a743
Adds run and plot lines to examples
DrPaulSharp Jun 12, 2024
81fe6de
Adds python custom functions
DrPaulSharp Jun 12, 2024
08c35c9
Fixes data resolution bug
DrPaulSharp Jun 12, 2024
5e408a6
Applies updates to submodule
DrPaulSharp Jun 17, 2024
5d792ae
Adds tests for custom function wrappers
DrPaulSharp Jun 19, 2024
fd59591
Adds "check_indices" routine to "make_inputs.py"
DrPaulSharp Jun 19, 2024
29795d8
Tidies up examples
DrPaulSharp Jun 19, 2024
089d9d4
Fixes bug in data model.
DrPaulSharp Jun 19, 2024
c62bdc1
Moves example data into shared directoy and resolves paths in examples
DrPaulSharp Jun 20, 2024
082e3f1
Allows custom file model to accept pathlib.Path objects
DrPaulSharp Jun 20, 2024
070530a
Addresses review comments
DrPaulSharp Jun 24, 2024
b5a80ca
Reintroduces "model_post_init" for "CustomFile" model
DrPaulSharp Jun 24, 2024
0d08e2c
Removes warning from custom file validator
DrPaulSharp Jun 24, 2024
648bf2e
Adds additional "__init__.py" for test data
DrPaulSharp Jun 25, 2024
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
5 changes: 3 additions & 2 deletions RAT/classlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,9 @@ def extend(self, other: Sequence[object]) -> None:
def set_fields(self, index: int, **kwargs) -> None:
"""Assign the values of an existing object's attributes using keyword arguments."""
self._validate_name_field(kwargs)
for key, value in kwargs.items():
setattr(self.data[index], key, value)
class_handle = self.data[index].__class__
new_fields = {**self.data[index].__dict__, **kwargs}
self.data[index] = class_handle(**new_fields)

def get_names(self) -> list[str]:
"""Return a list of the values of the name_field attribute of each class object in the list.
Expand Down
Empty file added RAT/examples/__init__.py
Empty file.
Empty file.
107 changes: 107 additions & 0 deletions RAT/examples/absorption/absorption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""Custom layers model including absorption"""

import numpy as np
import os
import pathlib

import RAT
import RAT.utils.plotting

problem = RAT.Project(name="Absorption example", calculation="non polarised", model="custom layers",
geometry="substrate/liquid", absorption=True)

# Add the required parameters (substrate roughness is already there by default)
problem.parameters.append(name="Alloy Thickness", min=100.0, value=135.6, max=200.0, fit=True)
problem.parameters.append(name="Alloy SLD up", min=6.0e-6, value=9.87e-6, max=1.2e-5, fit=True)
problem.parameters.append(name="Alloy SLD imaginary up", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True)
problem.parameters.append(name="Alloy SLD down", min=6.0e-6, value=7.05e-6, max=1.3e-5, fit=True)
problem.parameters.append(name="Alloy SLD imaginary down", min=1.0e-9, value=4.87e-8, max=1.0e-7, fit=True)
problem.parameters.append(name="Alloy Roughness", min=2.0, value=5.71, max=10.0, fit=True)
problem.parameters.append(name="Gold Thickness", min=100.0, value=154.7, max=200.0, fit=True)
problem.parameters.append(name="Gold Roughness", min=0.1, value=5.42, max=10.0, fit=True)
problem.parameters.append(name="Gold SLD", min=4.0e-6, value=4.49e-6, max=5.0e-6, fit=True)
problem.parameters.append(name="Gold SLD imaginary", min=1.0e-9, value=4.20e-8, max=1.0e-7, fit=True)

problem.parameters.append(name="Thiol APM", min=40.0, value=56.27, max=100.0, fit=True)
problem.parameters.append(name="Thiol Head Hydration", min=20.0, value=30.0, max=50.0, fit=True)
problem.parameters.append(name="Thiol Coverage", min=0.5, value=0.9, max=1.0, fit=True)

problem.parameters.append(name="CW Thickness", min=1.0, value=12.87, max=25.0, fit=True)
problem.parameters.append(name="Bilayer APM", min=48.0, value=65.86, max=90.0, fit=True)
problem.parameters.append(name="Bilayer Head Hydration", min=20.0, value=30.0, max=50.0, fit=True)
problem.parameters.append(name="Bilayer Roughness", min=1.0, value=3.87, max=10.0, fit=True)
problem.parameters.append(name="Bilayer Coverage", min=0.5, value=0.94, max=1.0, fit=True)

# Change the existing Bulk In parameter to be Silicon
problem.bulk_in.set_fields(0, name="Silicon", min=2.0e-6, value=2.073e-6, max=2.1e-6)

# We need 2 bulk outs - D2O and H2O
problem.bulk_out.set_fields(0, name="D2O", min=5.8e-06, value=6.21e-06, max=6.35e-06, fit=True)
problem.bulk_out.append(name="H2O", min=-5.6e-07, value=-3.15e-07, max=0.0, fit=True)

# Use a different scalefactor for each dataset
del problem.scalefactors[0]
problem.scalefactors.append(name="Scalefactor 1", min=0.5, value=1, max=1.5, fit=True)
problem.scalefactors.append(name="Scalefactor 2", min=0.5, value=1, max=1.5, fit=True)
problem.scalefactors.append(name="Scalefactor 3", min=0.5, value=1, max=1.5, fit=True)
problem.scalefactors.append(name="Scalefactor 4", min=0.5, value=1, max=1.5, fit=True)

# Similarly, use an individual background for each dataset
del problem.backgrounds[0]
del problem.background_parameters[0]

problem.background_parameters.append(name="Background parameter 1", min=5.0e-08, value=7.88e-06, max=9.0e-05, fit=True)
problem.background_parameters.append(name="Background parameter 2", min=1.0e-08, value=5.46e-06, max=9.0e-05, fit=True)
problem.background_parameters.append(name="Background parameter 3", min=1.0e-06, value=9.01e-06, max=9.0e-05, fit=True)
problem.background_parameters.append(name="Background parameter 4", min=1.0e-06, value=5.61e-06, max=9.0e-05, fit=True)

problem.backgrounds.append(name="Background 1", type="constant", value_1="Background parameter 1")
problem.backgrounds.append(name="Background 2", type="constant", value_1="Background parameter 2")
problem.backgrounds.append(name="Background 3", type="constant", value_1="Background parameter 3")
problem.backgrounds.append(name="Background 4", type="constant", value_1="Background parameter 4")

# Make the resolution fittable
problem.resolution_parameters.set_fields(0, fit=True)

# Now add the data we need
data_path = os.path.join(pathlib.Path(__file__).parents[1].resolve(), "data")

data_1 = np.loadtxt(os.path.join(data_path, "D2O_spin_down.dat"))
problem.data.append(name="D2O_dn", data=data_1)

data_2 = np.loadtxt(os.path.join(data_path, "D2O_spin_up.dat"))
problem.data.append(name="D2O_up", data=data_2)

data_3 = np.loadtxt(os.path.join(data_path, "H2O_spin_down.dat"))
problem.data.append(name="H2O_dn", data=data_3)

data_4 = np.loadtxt(os.path.join(data_path, "H2O_spin_up.dat"))
problem.data.append(name="H2O_up", data=data_4)

# Add the custom file
problem.custom_files.append(name="DPPC absorption", filename="volume_thiol_bilayer.py", language="python",
path=pathlib.Path(__file__).parent.resolve())

# Finally add the contrasts
problem.contrasts.append(name="D2O Down", data="D2O_dn", background="Background 1", bulk_in="Silicon",
bulk_out="D2O", scalefactor="Scalefactor 1", resolution="Resolution 1", resample=True,
model=["DPPC absorption"])

problem.contrasts.append(name="D2O Up", data="D2O_up", background="Background 2", bulk_in="Silicon",
bulk_out="D2O", scalefactor="Scalefactor 2", resolution="Resolution 1", resample=True,
model=["DPPC absorption"])

problem.contrasts.append(name="H2O Down", data="H2O_dn", background="Background 3", bulk_in="Silicon",
bulk_out="H2O", scalefactor="Scalefactor 3", resolution="Resolution 1", resample=True,
model=["DPPC absorption"])

problem.contrasts.append(name="H2O Up", data="H2O_up", background="Background 4", bulk_in="Silicon",
bulk_out="H2O", scalefactor="Scalefactor 4", resolution="Resolution 1", resample=True,
model=["DPPC absorption"])

# Now make a controls block
controls = RAT.set_controls(parallel="contrasts", resampleParams=[0.9, 150.0])

# Run the code and plot the results
problem, results = RAT.run(problem, controls)
RAT.utils.plotting.plot_ref_sld(problem, results, True)
143 changes: 143 additions & 0 deletions RAT/examples/absorption/volume_thiol_bilayer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
def volume_thiol_bilayer(params, bulk_in, bulk_out, contrast):
"""
volumeThiolBilayer 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.
"""
subRough = params[0]
alloyThick = params[1]
alloySLDUp = params[2]
alloyISLDUp = params[3]
alloySLDDown = params[4]
alloyISLDDown = params[5]
alloyRough = params[6]
goldThick = params[7]
goldRough = params[8]
goldSLD = params[9]
goldISLD = params[10]
thiolAPM = params[11]
thiolHeadHydr = params[12]
thiolCoverage = params[13]
cwThick = params[14]
bilayerAPM = params[15]
bilHeadHydr = params[16]
bilayerRough = params[17]
bilayerCoverage = params[18]

# Make the metal layers
gold = [goldThick, goldSLD, goldISLD, goldRough]
alloyUp = [alloyThick, alloySLDUp, alloyISLDUp, alloyRough]
alloyDown = [alloyThick, alloySLDDown, alloyISLDDown, alloyRough]

# Neutron b's..
# 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
bd = 0.6671e-4 # Deuterium

# Work out the total scattering length in each fragment
# Define scattering lengths
# Hydrogenated version
COO = (2*bo) + (bc)
GLYC = (3*bc) + (5*bh)
CH3 = (1*bc) + (3*bh)
PO4 = (1*bp) + (4*bo)
CH2 = (1*bc) + (2*bh)
CH = (1*bc) + (1*bh)
CHOL = (5*bc) + (12*bh) + (1*bn)
H2O = (2*bh) + (1*bo)
D2O = (2*bd) + (1*bo)

# And also volumes
vCH3 = 52.7 # CH3 volume in the paper appears to be for 2 * CH3's
vCH2 = 28.1
vCOO = 39.0
vGLYC = 68.8
vPO4 = 53.7
vCHOL = 120.4
vWAT = 30.4
vCHCH = 42.14

vHead = vCHOL + vPO4 + vGLYC + 2*vCOO
vTail = (28*vCH2) + (1*vCHCH) + (2*vCH3) # Tail volume

# Calculate sum_b's for other fragments
sumbHead = CHOL + PO4 + GLYC + 2*COO
sumbTail = (28*CH2) + (2*CH) + 2*CH3

# Calculate SLDs and Thickness
sldHead = sumbHead/vHead
thickHead = vHead/thiolAPM

sldTail = sumbTail/vTail
thickTail = vTail/thiolAPM

# Correct head SLD based on hydration
thiolHeadHydr = thiolHeadHydr/100
sldHead = (sldHead * (1 - thiolHeadHydr) + (thiolHeadHydr * bulk_out[contrast]))

# Now correct both the SLDs for the coverage parameter
sldTail = (thiolCoverage*sldTail) + ((1-thiolCoverage) * bulk_out[contrast])
sldHead = (thiolCoverage*sldHead) + ((1-thiolCoverage) * bulk_out[contrast])

SAMTAILS = [thickTail, sldTail, 0, goldRough]
SAMHEAD = [thickHead, sldHead, 0, goldRough]

# Now do the same for the bilayer
vHead = vCHOL + vPO4 + vGLYC + 2*vCOO
vTail = (28*vCH2) # Tail volume
vMe = (2*vCH3)

sumbHead = CHOL + PO4 + GLYC + 2*COO
sumbTail = (28*CH2)
sumbMe = 2*CH3

sldHead = sumbHead/vHead
thickHead = vHead/bilayerAPM
bilHeadHydr = bilHeadHydr / 100
sldHead = (sldHead * (1 - bilHeadHydr) + (bilHeadHydr * bulk_out[contrast]))

sldTail = sumbTail/vTail
thickTail = vTail/bilayerAPM

sldMe = sumbMe/vMe
thickMe = vMe/bilayerAPM

sldTail = (bilayerCoverage * sldTail) + ((1-bilayerCoverage) * bulk_out[contrast])
sldHead = (bilayerCoverage * sldHead) + ((1-bilayerCoverage) * bulk_out[contrast])
sldMe = (bilayerCoverage * sldMe) + ((1-bilayerCoverage) * bulk_out[contrast])

BILTAILS = [thickTail, sldTail, 0, bilayerRough]
BILHEAD = [thickHead, sldHead, 0, bilayerRough]
BILME = [thickMe, sldMe, 0, bilayerRough]

BILAYER = [BILHEAD, BILTAILS, BILME, BILME, BILTAILS, BILHEAD]

CW = [cwThick, bulk_out[contrast], 0, bilayerRough]

if contrast == 1 or contrast == 3:
output = [alloyUp, gold, SAMTAILS, SAMHEAD, CW, *BILAYER]
else:
output = [alloyDown, gold, SAMTAILS, SAMHEAD, CW, *BILAYER]

return output, subRough
100 changes: 100 additions & 0 deletions RAT/examples/data/D2O_spin_down.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
0.01218 1.015359223955 0.0231718818417596
0.012545 0.919431439253596 0.0193509380578665
0.012922 0.924921688167335 0.0183337262959345
0.013309 0.892889622419078 0.01658695139614
0.013709 0.88564788305433 0.0151834012597258
0.01412 0.954057058169692 0.0152655865808885
0.014544 0.801205833810502 0.0128764862406952
0.01498 0.57206372730641 0.00977028529084846
0.015429 0.507292263127758 0.00840850146518913
0.015892 0.441240863619522 0.0072616120448651
0.016369 0.411263430900333 0.00703930748762168
0.01686 0.398699855165213 0.00667722051938428
0.017366 0.369396072619489 0.00590757519620061
0.017887 0.333584829398094 0.00529590083869447
0.018423 0.300131361783826 0.00480817811310586
0.018976 0.254862070126983 0.00436222169827209
0.019545 0.218629795547172 0.0038320590117552
0.020132 0.183303580450672 0.00337229276836539
0.020736 0.158391997035939 0.00306386203644447
0.021358 0.128249520024251 0.00266512849877059
0.021998 0.0956717976354879 0.0021819192293442
0.022658 0.0688201017211762 0.00176311091650106
0.023338 0.0481760921553437 0.00145639799252248
0.024038 0.0328252888275119 0.00118309811714777
0.024759 0.0183323789955876 0.000868570851156994
0.025502 0.0106467041665263 0.000644514803462562
0.026267 0.00788878035636094 0.000551382666981037
0.027055 0.0069025565024083 0.0005165549530129
0.027867 0.00807841288019132 0.000666341069082825
0.028703 0.0104166526322881 0.000419481963016605
0.029564 0.0134376368351915 0.000465997507494358
0.030451 0.0158250530499512 0.000492135134224797
0.031365 0.018520664219071 0.000528646973626596
0.032305 0.0188403112263801 0.000530903701707703
0.033275 0.0189720098352925 0.000529859543938832
0.034273 0.0167957829499141 0.000677826804540402
0.035301 0.0143561588467109 0.000448314190440904
0.03636 0.0120825895112668 0.000385361581730607
0.037451 0.00911010812085284 0.000338273434605409
0.038574 0.0064407693084981 0.000272228771598909
0.039732 0.00380747078042373 0.000191909461416686
0.040924 0.00219977095894102 0.000139024554548823
0.042151 0.00106749974738118 9.30715079659133e-05
0.043416 0.000526289198019469 6.53777493347705e-05
0.044718 0.000538684361211223 6.36026811276904e-05
0.04606 0.000666071609013439 6.89514635050019e-05
0.047442 0.00096513860352319 8.1892283337263e-05
0.048865 0.00123628279834282 9.06632085957762e-05
0.050331 0.000932500252618815 7.56441779783758e-05
0.051841 0.000704570716426959 6.33837448213143e-05
0.053396 0.000422547071305871 4.87823773114622e-05
0.054998 0.000225234935497996 3.52790595843578e-05
0.056648 0.000224295193506012 3.47502441981879e-05
0.058347 0.000348546599750749 4.2399541917882e-05
0.060098 0.000753444036511839 6.21105459934656e-05
0.061901 0.00108427363670046 0.000132874128465088
0.063758 0.00147590016504429 6.80656135268955e-05
0.06567 0.00157522988312169 6.65397958839974e-05
0.06764 0.00123685540099027 5.63878877698811e-05
0.06967 0.000809188588366061 4.4090403853279e-05
0.07176 0.000394860049176463 3.01087945030146e-05
0.073913 0.000158546936575836 1.87827141365489e-05
0.07613 0.000205156792077874 2.11738354272626e-05
0.078414 0.000432213951295092 3.08747347502442e-05
0.080766 0.000654956381151268 3.77210414631682e-05
0.083189 0.000798309138064603 4.33157061537943e-05
0.085685 0.000842635319478595 5.73848900266092e-05
0.088255 0.000695947994206608 4.00080838020816e-05
0.090903 0.000486577520293712 3.1324396241032e-05
0.09363 0.000518575903533295 3.11105123109569e-05
0.096439 0.000572434234901815 3.26076998214827e-05
0.099332 0.000634309003334568 3.34605409410893e-05
0.10231 0.000482232476674863 2.81521775741857e-05
0.10538 0.000365623631648085 2.39677995217084e-05
0.10854 0.000216433695981677 1.81376940954562e-05
0.1118 0.00016573141567584 1.53181312944188e-05
0.11515 0.000215844252079895 1.6793425174307e-05
0.11861 0.000301364141601267 1.9534170905049e-05
0.12217 0.000246353868436121 1.75755330256998e-05
0.12583 0.000162551786857085 1.40661524470343e-05
0.12961 7.50985213378692e-05 9.36878978746337e-06
0.13349 6.5539425376402e-05 8.69884468995251e-06
0.1375 4.34100171780794e-05 7.01707703189734e-06
0.14162 4.008555357203e-05 6.73885951025632e-06
0.14587 3.09498467445855e-05 5.80450671966048e-06
0.15025 9.04307992859308e-06 3.1003401933376e-06
0.15476 1.20906733133484e-05 3.56933544410388e-06
0.1594 1.50092626898851e-05 4.01428138367746e-06
0.16418 2.38057866549901e-05 5.21304186735828e-06
0.16911 2.45653272255718e-05 5.35080332783186e-06
0.17418 1.01465189127286e-05 3.58853447404763e-06
0.17941 9.15355855704133e-06 3.55249418976725e-06
0.18479 4.82434571726902e-06 2.64124760012126e-06
0.19033 1.52628919801947e-06 1.52659234059753e-06
0.19604 3.69800262723568e-06 2.61612044865102e-06
0.20192 1.54286099228671e-06 1.90198389976085e-06
0.20798 1.2093704739129e-05 5.23729327360302e-06
0.21422 2.37360638620364e-06 2.37431371888578e-06
0.22065 5.71086934554886e-06 4.04257469096298e-06
0.22727 3.01060999023207e-06 3.01168783050962e-06
Loading