Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a2d2470

Browse files
authoredOct 3, 2024··
Merge pull request #97 from refnx/main
Fold in contemporaneous updates from main
2 parents db71f40 + 1be91bf commit a2d2470

14 files changed

+142
-52
lines changed
 

‎.github/workflows/test.yml

+11-11
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ jobs:
1111
strategy:
1212
max-parallel: 3
1313
matrix:
14-
python-version: ["3.10", "3.11"]
14+
python-version: ["3.10", "3.11", "3.12"]
1515

1616
steps:
17-
- uses: actions/checkout@v2
17+
- uses: actions/checkout@v4
1818
- name: Set up Python ${{ matrix.python-version }}
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v5
2020
with:
2121
python-version: ${{ matrix.python-version }}
2222

@@ -33,9 +33,9 @@ jobs:
3333
pytest --pyargs refellips
3434
popd
3535
36-
- uses: actions/upload-artifact@v1
36+
- uses: actions/upload-artifact@v4
3737
with:
38-
name: refellips-wheel
38+
name: refellips-linux-${{ matrix.python-version }}
3939
path: dist/
4040

4141
lint:
@@ -45,10 +45,10 @@ jobs:
4545
python-version: ["3.11"]
4646

4747
steps:
48-
- uses: actions/checkout@v2
48+
- uses: actions/checkout@v4
4949

5050
- name: Set up Python ${{ matrix.python-version }}
51-
uses: actions/setup-python@v2
51+
uses: actions/setup-python@v5
5252
with:
5353
python-version: ${{ matrix.python-version }}
5454

@@ -69,10 +69,10 @@ jobs:
6969
python-version: ["3.10"]
7070

7171
steps:
72-
- uses: actions/checkout@v2
72+
- uses: actions/checkout@v4
7373

7474
- name: Set up Python ${{ matrix.python-version }}
75-
uses: actions/setup-python@v2
75+
uses: actions/setup-python@v5
7676
with:
7777
python-version: ${{ matrix.python-version }}
7878

@@ -98,9 +98,9 @@ jobs:
9898
python-version: ["3.11"]
9999

100100
steps:
101-
- uses: actions/checkout@v2
101+
- uses: actions/checkout@v4
102102
- name: Set up Python ${{ matrix.python-version }}
103-
uses: actions/setup-python@v2
103+
uses: actions/setup-python@v5
104104
with:
105105
python-version: ${{ matrix.python-version }}
106106

‎demos/refellipsDemo_UserDefinedOscillator.ipynb

+9-9
Large diffs are not rendered by default.

‎docs/examples.rst

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ Examples
44
.. toctree::
55
:maxdepth: 2
66

7-
User defined dielectric functions <https://nbviewer.org/github/refnx/refellips/blob/master/demos/refellipsDemo_UserDefinedOscillator.ipynb>
8-
Variable angle analysis <https://nbviewer.org/github/refnx/refellips/blob/master/demos/refellipsDemo.ipynb>
9-
Spectroscopic & variable angle analysis <https://nbviewer.org/github/refnx/refellips/blob/master/demos/refellipsDemo_Spectroscopic.ipynb>
10-
Batch fitting and surface maps <https://nbviewer.org/github/refnx/refellips/blob/master/demos/refellipsDemo_Map.ipynb>
11-
Solid-liquid interface analysis <https://nbviewer.org/github/refnx/refellips/blob/master/demos/refellipsDemo_Spectroscopic_SL.ipynb>
12-
Co-refining ellipsometry and neutron reflectometry data <https://nbviewer.org/github/refnx/refellips/blob/master/demos/corefine_polyBrush.ipynb>
13-
Co-refining with Lagrange multipliers <https://nbviewer.org/github/refnx/refellips/blob/master/demos/corefine_Ellipsometry_XRR_NR.ipynb>
7+
User defined dielectric functions <https://nbviewer.org/github/refnx/refellips/blob/main/demos/refellipsDemo_UserDefinedOscillator.ipynb>
8+
Variable angle analysis <https://nbviewer.org/github/refnx/refellips/blob/main/demos/refellipsDemo.ipynb>
9+
Spectroscopic & variable angle analysis <https://nbviewer.org/github/refnx/refellips/blob/main/demos/refellipsDemo_Spectroscopic.ipynb>
10+
Batch fitting and surface maps <https://nbviewer.org/github/refnx/refellips/blob/main/demos/refellipsDemo_Map.ipynb>
11+
Solid-liquid interface analysis <https://nbviewer.org/github/refnx/refellips/blob/main/demos/refellipsDemo_Spectroscopic_SL.ipynb>
12+
Co-refining ellipsometry and neutron reflectometry data <https://nbviewer.org/github/refnx/refellips/blob/main/demos/corefine_polyBrush.ipynb>
13+
Co-refining with Lagrange multipliers <https://nbviewer.org/github/refnx/refellips/blob/main/demos/corefine_Ellipsometry_XRR_NR.ipynb>

‎docs/getting_started.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"from refellips.dataSE import DataSE, open_EP4file\n",
5050
"from refellips.reflect_modelSE import ReflectModelSE\n",
5151
"from refellips.objectiveSE import ObjectiveSE\n",
52-
"from refellips.structureSE import RI, Cauchy, load_material"
52+
"from refellips.dispersion import RI, Cauchy, load_material"
5353
]
5454
},
5555
{

‎pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[project]
2-
requires-python = ">=3.7"
2+
requires-python = ">=3.9"
33
name = "refellips"
44
dynamic=["version", "description", "readme", "license", "classifiers", "urls", "authors"]

‎readthedocs.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ sphinx:
55
configuration: docs/conf.py
66

77
build:
8-
image: latest
8+
os: ubuntu-22.04
9+
tools:
10+
python: "3.10"
911

1012
python:
11-
version: 3.8
1213
install:
1314
- requirements: docs/requirements.txt
1415
- method: pip
1516
path: .
16-
system_packages: false
1717

1818
formats:
1919
- epub

‎refellips/dispersion.py

+25-12
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,14 @@ def __init__(self, Am, Br, En, Einf=1, wavelength=658, name=""):
371371
if not (len(self.Am) == len(self.Br) == len(self.En)):
372372
raise ValueError("A, B, E all have to be the same length")
373373

374+
self.Am.name = f"{name} - Lorentz Am"
375+
self.Br.name = f"{name} - Lorentz Br"
376+
self.En.name = f"{name} - Lorentz En"
377+
374378
self._parameters.extend([self.Am, self.Br, self.En])
375-
self.Einf = possibly_create_parameter(Einf)
379+
self.Einf = possibly_create_parameter(
380+
Einf, name=f"{name} - Lorentz Einf"
381+
)
376382
self._parameters.append(self.Einf)
377383

378384
@property
@@ -386,7 +392,7 @@ def epsilon(self, energy):
386392
A = np.array(self.Am)[:, None]
387393
B = np.array(self.Br)[:, None]
388394
E = np.array(self.En)[:, None]
389-
_e = np.asfarray(energy)
395+
_e = np.asarray(energy, np.float64)
390396
v = A / (E**2 - _e**2 - 1j * B * _e)
391397
r = np.atleast_1d(np.sum(v, axis=0) + self.Einf.value)
392398

@@ -433,7 +439,11 @@ def __init__(self, Am, Br, En, Einf=1, wavelength=658, name=""):
433439
if not (len(self.Am) == len(self.Br) == len(self.En)):
434440
raise ValueError("A, B, E all have to be the same length")
435441

436-
self.Einf = possibly_create_parameter(Einf)
442+
self.Einf = possibly_create_parameter(Einf, name=f"{name} - Gauss Einf")
443+
self.Am.name = f"{name} - Gauss Am"
444+
self.Br.name = f"{name} - Gauss Br"
445+
self.En.name = f"{name} - Gauss En"
446+
437447
self._parameters.extend([self.Am, self.Br, self.En])
438448
self._parameters.append(self.Einf)
439449

@@ -448,7 +458,7 @@ def epsilon(self, energy):
448458
A = np.array(self.Am)[:, None]
449459
B = np.array(self.Br)[:, None]
450460
E = np.array(self.En)[:, None]
451-
energies = np.asfarray(energy)
461+
energies = np.asarray(energy, np.float64)
452462

453463
# TODO cache if params don't change
454464
_e_pad = np.linspace(-20, 20, 2048)
@@ -523,8 +533,14 @@ def __init__(self, Am, C, En, Eg, Einf=1, wavelength=658, name=""):
523533
if not (len(self.Am) == len(self.C) == len(self.En)):
524534
raise ValueError("A, B, E all have to be the same length")
525535

526-
self.Einf = possibly_create_parameter(Einf)
527-
self.Eg = possibly_create_parameter(Eg)
536+
self.Einf = possibly_create_parameter(
537+
Einf, name=f"{name} - TaucLorentz Einf"
538+
)
539+
self.Eg = possibly_create_parameter(Eg, name=f"{name} - TaucLorentz Eg")
540+
self.Am.name = f"{name} - TaucLorentz Am"
541+
self.C.name = f"{name} - TaucLorentz C"
542+
self.En.name = f"{name} - TaucLorentz En"
543+
528544
self._parameters.extend([self.Am, self.C, self.En, self.Einf, self.Eg])
529545

530546
@property
@@ -539,16 +555,14 @@ def epsilon(self, energy):
539555
C = np.array(self.C)[:, None]
540556
Ei = np.array(self.En)[:, None]
541557
Eg = self.Eg.value
542-
energies = np.asfarray(energy)
558+
energies = np.asarray(energy, np.float64)
543559

544560
a_ln = (
545561
(Eg**2 - Ei**2) * energies**2
546562
+ Eg**2 * C**2
547563
- Ei**2 * (Ei**2 + 3 * Eg**2)
548564
)
549-
a_atan = (energies**2 - Ei**2) * (
550-
Ei**2 + Eg**2
551-
) + Eg**2 * C**2
565+
a_atan = (energies**2 - Ei**2) * (Ei**2 + Eg**2) + Eg**2 * C**2
552566
alpha = np.sqrt(4 * Ei**2 - C**2)
553567
gamma = np.sqrt(Ei**2 - C**2 / 2)
554568
zeta4 = (energies**2 - gamma**2) ** 2 + 0.25 * alpha**2 * C**2
@@ -563,8 +577,7 @@ def epsilon(self, energy):
563577
/ alpha
564578
/ Ei
565579
* np.log(
566-
(Ei**2 + Eg**2 + alpha * Eg)
567-
/ (Ei**2 + Eg**2 - alpha * Eg)
580+
(Ei**2 + Eg**2 + alpha * Eg) / (Ei**2 + Eg**2 - alpha * Eg)
568581
)
569582
)
570583
e1 -= (

‎refellips/materials/__init__.py

Whitespace-only changes.

‎refellips/reflect_modelSE.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
""""""
2+
23
"""
34
Calculates the ellipsometry parameters Δ and Ψ from a stratified series of
45
layers.
@@ -119,7 +120,7 @@ def coh_tmm(n_list, d_list, th_0, lam_vac):
119120
"""
120121
# Convert lists to numpy arrays if they're not already.
121122
n_list = np.asarray(n_list)
122-
d_list = np.asfarray(d_list)
123+
d_list = np.asarray(d_list, np.float64)
123124
num_layers = n_list.size
124125

125126
th_0, lam_vac = [np.array(a) for a in np.broadcast_arrays(th_0, lam_vac)]
@@ -257,7 +258,7 @@ def Delta_Psi_TMM(AOI, layers, wavelength, delta_offset, reflect_delta=False):
257258
258259
259260
"""
260-
AOI = np.asfarray(AOI)
261+
AOI = np.asarray(AOI, np.float64)
261262
AOI = AOI * (np.pi / 180)
262263

263264
layers[0, 2] = 0 # infinate medium cannot have an extinction coeff

‎refellips/structureSE.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
""""""
2+
23
"""
34
BSD 3-Clause License
45

‎refellips/tests/__init__.py

Whitespace-only changes.

‎setup.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,12 @@ def get_version_info():
8080
GIT_REVISION = git_version()
8181
elif os.path.exists("refellips/version.py"):
8282
# must be a source distribution, use existing version file
83-
# load it as a separate module to not load refellips/__init__.py
84-
import imp
85-
86-
version = imp.load_source("refellips.version", "refellips/version.py")
87-
GIT_REVISION = version.git_revision
83+
# load it as a separate module to not load refnx/__init__.py
84+
import importlib.util
85+
spec = importlib.util.spec_from_file_location("version", "refellips/version.py")
86+
module = importlib.util.module_from_spec(spec)
87+
spec.loader.exec_module(module)
88+
GIT_REVISION = module.git_revision
8889
else:
8990
GIT_REVISION = "Unknown"
9091

‎testimonials.bib

+74
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,78 @@ @article{ibrahim2023structural
4646
publisher={Cold Spring Harbor Laboratory}
4747
}
4848

49+
@article{Gresham2024,
50+
author = {Gresham, Isaac J and Johnson, Edwin C and Robertson, Hayden and Willott, Joshua D and Webber, Grant B and Wanless, Erica J and Nelson, Andrew R J and Prescott, Stuart W},
51+
doi = {10.1016/j.jcis.2023.10.101},
52+
issn = {0021-9797},
53+
journal = {Journal of Colloid And Interface Science},
54+
keywords = {Electrolyte,Poly(N-isopropylacrylamide),Polymer brushes,Responsive polymers,Sodium dodecylsulfate,Surfactants,n -isopropylacrylamide,poly},
55+
number = {September 2023},
56+
pages = {262--272},
57+
publisher = {Elsevier Inc.},
58+
title = {{Comparing polymer-surfactant complexes to polyelectrolytes}},
59+
url = {https://doi.org/10.1016/j.jcis.2023.10.101},
60+
volume = {655},
61+
year = {2024}
62+
}
63+
64+
@article{D3CP02206D,
65+
abstract = {Hypersaline environments are ubiquitous in nature and are found in myriad technological processes. Recent empirical studies have revealed a significant discrepancy between predicted and observed screening lengths at high salt concentrations{,} a phenomenon referred to as underscreening. Herein we investigate underscreening using a cationic polyelectrolyte brush as an exemplar. Poly(2-(methacryloyloxy)ethyl)trimethylammonium (PMETAC) brushes were synthesised and their internal structural changes and swelling response was monitored with neutron reflectometry and spectroscopic ellipsometry. Both techniques revealed a monotonic brush collapse as the concentration of symmetric monovalent electrolyte increased. However{,} a non-monotonic change in brush thickness was observed in all multivalent electrolytes at higher concentrations{,} known as re-entrant swelling; indicative of underscreening. For all electrolytes{,} numerical self-consistent field theory predictions align with experimental studies in the low-to-moderate salt concentration regions. Analysis suggests that the classical theory of electrolytes is insufficient to describe the screening lengths observed at high salt concentrations and that the re-entrant polyelectrolyte brush swelling seen herein is consistent with the so-called regular underscreening phenomenon.},
66+
author = {Robertson, Hayden and Elliott, Gareth R and Nelson, Andrew R J and {Le Brun}, Anton P and Webber, Grant B and Prescott, Stuart W and Craig, Vincent S J and Wanless, Erica J and Willott, Joshua D},
67+
doi = {10.1039/D3CP02206D},
68+
journal = {Physical Chemistry Chemical Physics},
69+
number = {36},
70+
pages = {24770--24782},
71+
publisher = {The Royal Society of Chemistry},
72+
title = {{Underscreening in concentrated electrolytes: re-entrant swelling in polyelectrolyte brushes}},
73+
url = {http://dx.doi.org/10.1039/D3CP02206D},
74+
volume = {25},
75+
year = {2023}
76+
}
77+
78+
@article{Robertson2024,
79+
abstract = {Pertinent to cryopreservation as well as energy storage and batteries, nonaqueous electrolytes and their mixtures with water were investigated. In particular, specific ion-induced effects on the modulation of a poly(N-isopropylacrylamide) (PNIPAM) brush were investigated in various dimethyl sulfoxide (DMSO)–water solvent mixtures. Spectroscopic ellipsometry and neutron reflectometry were employed to probe changes in brush swelling and structure, respectively. In water-rich solvents (i.e., pure water and 6 mol % DMSO), PNIPAM undergoes a swollen to collapsed thermotransition with increasing temperature, whereby a forward Hofmeister series was noted; K+ and Li+ electrolytes composed of SCN– and I– salted-in (stabilized) PNIPAM chains, and electrolytes of Cl– and Br– salted-out (destabilized) the polymer. The cation was seen to play a lesser role than that of the anion, merely modulating the magnitude of the anion effect. In 70 mol % DMSO, a collapsed to swollen thermotransition was noted for PNIPAM. Here, concentration-dependent specific ion effects were observed; a forward series was observed in 0.2 mol % electrolytes, whereas increasing the electrolyte concentration to 0.9 mol % led to a series reversal. While no thermotransition was observed in pure DMSO, a solvent-induced specific ion series reversal was noted; SCN– destabilized the brush and Cl– stabilized the brush. Both series reversals are attributed to the delicate balance of interactions between the solvent, solute (ion), and substrate (brush). Namely, the stability of the solvent clusters was hypothesized to drive polymer solvation.},
80+
author = {Robertson, Hayden and Gresham, Isaac J and Nelson, Andrew R J and Gregory, Kasimir P and Johnson, Edwin C and Willott, Joshua D and Prescott, Stuart W and Webber, Grant B and Wanless, Erica J},
81+
doi = {10.1021/acs.langmuir.3c02596},
82+
issn = {0743-7463},
83+
journal = {Langmuir},
84+
month = {jan},
85+
number = {1},
86+
pages = {335--347},
87+
publisher = {American Chemical Society},
88+
title = {{Solvent-Modulated Specific Ion Effects: Poly(N-isopropylacrylamide) Brushes in Nonaqueous Electrolytes}},
89+
url = {https://doi.org/10.1021/acs.langmuir.3c02596},
90+
volume = {40},
91+
year = {2024}
92+
}
93+
94+
@article{Robertson2023,
95+
abstract = {Cosolvents play an integral role in polymer solubility, with myriad applications in drug delivery and energy storage. In particular, dimethyl sulfoxide (DMSO) has received substantial attention to date due to its cryoprotective properties and interesting nonideal mixing behaviour. Here, for the first time, we probe the fundamentals of DMSO–water solvent structuring using a thermoresponsive poly(N-isopropoylacrylamide) (PNIPAM) brush as an exemplar. Spectroscopic ellipsometry and neutron reflectometry were employed to monitor changes in brush swelling and conformation as a function of temperature and solvent composition, whereby changes in solvent structure can be deduced. Importantly, unlike free polymer, grafted polymers permit measurements across the entire solvent composition space, including ‘poor' solvent conditions, permitting the characterisation of polymers in complex media for future technologies. In the water-rich regime, the prevalent hydrogen-bond network resulted in the PNIPAM brush exhibiting a lower critical solution temperature (LCST) up to DMSO mole fractions of 0.10 (xD = 0.10), which decreased with increasing xD; DMSO is a chaotropic cosolvent. This region was adjacent to a cononsolvency region. Interestingly, reentrant swelling was observed for above approximately xD = 0.2. In DMSO-rich regimes, non-site-specific dipole–dipole interactions resulted in the PNIPAM brush exhibiting an uppercritical solution temperature (UCST), whereby the periphery of the swollen brush was more diffuse than at low xD. At all temperatures, pure DMSO is a good solvent for PNIPAM and no thermoresponse was observed. Herein we demonstrate how the structure and swelling of a polymer brush film can be modulated by tuning solvent composition by mixing two ‘good' solvents.},
96+
author = {Robertson, Hayden and Nelson, Andrew R J and Prescott, Stuart W and Webber, Grant B and Wanless, Erica J},
97+
doi = {10.1039/D2PY01487D},
98+
issn = {1759-9954},
99+
journal = {Polymer Chemistry},
100+
number = {13},
101+
pages = {1526--1535},
102+
publisher = {The Royal Society of Chemistry},
103+
title = {{Cosolvent effects on the structure and thermoresponse of a polymer brush: PNIPAM in DMSO–water mixtures}},
104+
url = {http://dx.doi.org/10.1039/D2PY01487D},
105+
volume = {14},
106+
year = {2023}
107+
}
108+
109+
@article{ROBERTSON2024103238,
110+
title = {Illuminating the nanostructure of diffuse interfaces: Recent advances and future directions in reflectometry techniques},
111+
journal = {Advances in Colloid and Interface Science},
112+
pages = {103238},
113+
year = {2024},
114+
issn = {0001-8686},
115+
doi = {https://doi.org/10.1016/j.cis.2024.103238},
116+
url = {https://www.sciencedirect.com/science/article/pii/S0001868624001611},
117+
author = {Hayden Robertson and Isaac J. Gresham and Andrew R.J. Nelson and Stuart W. Prescott and Grant B. Webber and Erica J. Wanless},
118+
keywords = {Solvated interfaces, Diffuse interfaces, Soft matter, Polymer brushes, Monolayers, Reflectometry techniques, X-ray reflectometry, Neutron reflectometry, Ellipsometry, Interfacial phenomena, Nanoscale characterisation},
119+
abstract = {Diffuse soft matter interfaces take many forms, from end-tethered polymer brushes or adsorbed surfactants to self-assembled layers of lipids. These interfaces play crucial roles across a multitude of fields, including materials science, biophysics, and nanotechnology. Understanding the nanostructure and properties of these interfaces is fundamental for optimising their performance and designing novel functional materials. In recent years, reflectometry techniques, in particular neutron reflectometry, have emerged as powerful tools for elucidating the intricate nanostructure of soft matter interfaces with remarkable precision and depth. This review provides an overview of selected recent developments in reflectometry and their applications for illuminating the nanostructure of diffuse interfaces. We explore various principles and methods of neutron and X-ray reflectometry, as well as ellipsometry, and discuss advances in their experimental setups and data analysis approaches. Improvements to experimental neutron reflectometry methods have enabled greater time resolution in kinetic measurements and elucidation of diffuse structure under shear or confinement, while innovation in analysis protocols has significantly reduced data processing times, facilitated co-refinement of reflectometry data from multiple instruments and provided greater-than-ever confidence in proposed structural models. Furthermore, we highlight some significant research findings enabled by these techniques, revealing the organisation, dynamics, and interfacial phenomena at the nanoscale. We also discuss future directions and potential advancements in reflectometry techniques. By shedding light on the nanostructure of diffuse interfaces, reflectometry techniques enable the rational design and tailoring of interfaces with enhanced properties and functionalities.}
120+
}
121+
122+
49123
@Comment{jabref-meta: databaseType:bibtex;}

‎tools/plottools.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def plot_ellipsdata(
9696
ax.plot(np.ones_like(psi) * wavelength, psi, color="r")
9797
axt.plot(np.ones_like(delta) * wavelength, delta, color="b")
9898

99-
xlab = "Wavelength (nm)"
99+
xlab = "Wavelength (nm)"
100100

101101
p = ax.scatter(x, data.psi, color="r")
102102
d = axt.scatter(x, data.delta, color="b")

0 commit comments

Comments
 (0)
Please sign in to comment.