Skip to content

Commit c73c59f

Browse files
committed
Refactors ExperimentType initialization to use default values and updates experiment handling in factory methods
1 parent b3fa0d8 commit c73c59f

File tree

7 files changed

+71
-51
lines changed

7 files changed

+71
-51
lines changed

src/easydiffraction/experiments/categories/experiment_type.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ class ExperimentType(CategoryItem):
3232
def __init__(
3333
self,
3434
*,
35-
sample_form: str,
36-
beam_mode: str,
37-
radiation_probe: str,
38-
scattering_type: str,
35+
sample_form=None,
36+
beam_mode=None,
37+
radiation_probe=None,
38+
scattering_type=None,
3939
):
4040
super().__init__()
4141

src/easydiffraction/experiments/experiment/factory.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ def _make_experiment_type(cls, kwargs):
5050
"""Helper to construct an ExperimentType from keyword arguments,
5151
using defaults as needed.
5252
"""
53+
# TODO: Defaults are already in the experiment type...
54+
# TODO: Merging with experiment_type_from_block from
55+
# io.cif.parse
5356
return ExperimentType(
5457
sample_form=kwargs.get('sample_form', SampleFormEnum.default()),
5558
beam_mode=kwargs.get('beam_mode', BeamModeEnum.default()),
@@ -66,17 +69,20 @@ def _create_from_gemmi_block(
6669
"""Build a model instance from a single CIF block."""
6770
name = name_from_block(block)
6871

69-
# TODO: experiment type need to be read from CIF block
70-
kwargs = {'beam_mode': BeamModeEnum.CONSTANT_WAVELENGTH}
71-
expt_type = cls._make_experiment_type(kwargs)
72+
# TODO: move to io.cif.parse?
73+
expt_type = ExperimentType()
74+
for param in expt_type.parameters:
75+
param.from_cif(block)
7276

7377
# Create experiment instance of appropriate class
78+
# TODO: make helper method to create experiment from type
7479
scattering_type = expt_type.scattering_type.value
7580
sample_form = expt_type.sample_form.value
7681
expt_class = cls._SUPPORTED[scattering_type][sample_form]
7782
expt_obj = expt_class(name=name, type=expt_type)
7883

7984
# Read all categories from CIF block
85+
# TODO: move to io.cif.parse?
8086
for category in expt_obj.categories:
8187
category.from_cif(block)
8288

src/easydiffraction/io/cif/parse.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ def name_from_block(block: gemmi.cif.Block) -> str:
2323
"""Extract a model name from the CIF block name."""
2424
# TODO: Need validator or normalization?
2525
return block.name
26+
27+
28+
# def experiment_type_from_block(
29+
# exp_type: ExperimentType,
30+
# block: gemmi.cif.Block,
31+
# ) -> dict:
32+
# """Extract experiment type information from a CIF block."""
33+
# for param in exp_type.parameters:
34+
# param.from_cif(block)

src/easydiffraction/io/cif/serialize.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ def datastore_from_cif(
316316
) -> None:
317317
"""Populate a datastore from a CIF block."""
318318
# TODO: Make datastore category collection with cif names, etc.
319+
# We need multiple datastores for different experiment types.
320+
# Similar to e.g. background or instrument or peak categories.
321+
# Then, datastore will be automatically handled like other
322+
# categories and this method can be removed.
319323
x_name = '_pd_meas.2theta_scan'
320324
y_name = '_pd_meas.intensity_total'
321325
sy_name = '_pd_meas.intensity_total_su'

tmp/_read_cif.py

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@
1818

1919
# %% [markdown]
2020
# ## Import Library
21-
#
22-
# import gemmi
23-
# d = gemmi.cif.read_string("data_x\n_a 1\n")
24-
# b = d.sole_block()
25-
# do nothing else
2621

2722
# %%
2823
import easydiffraction as ed
@@ -32,7 +27,6 @@
3227
Logger.configure(
3328
level=Logger.Level.INFO,
3429
mode=Logger.Mode.COMPACT,
35-
#mode=Logger.Mode.VERBOSE,
3630
reaction=Logger.Reaction.WARN,
3731
)
3832

@@ -52,10 +46,11 @@
5246
project.sample_models.show_names()
5347

5448
# %%
55-
sample_model = project.sample_models['lbco']
49+
# Create an alias for easier access
50+
lbco = project.sample_models['lbco']
5651

5752
# %%
58-
sample_model.show_as_cif()
53+
lbco.show_as_cif()
5954

6055
# %% [markdown]
6156
# ## Step 3: Define Experiment
@@ -64,40 +59,47 @@
6459
project.experiments.add_from_cif_path("data/hrpt.cif")
6560

6661
# %%
67-
experiment = project.experiments['hrpt']
62+
project.experiments.show_names()
6863

6964
# %%
70-
project.experiments.show_names()
65+
# Create an alias for easier access
66+
hrpt = project.experiments['hrpt']
7167

7268
# %%
73-
experiment.show_as_cif()
69+
hrpt.show_as_cif()
7470

7571
# %% [markdown]
7672
# ## Step 4: Perform Analysis
7773

7874
# %%
79-
sample_model.cell.length_a.free = True
75+
# Select sample model parameters to refine
76+
lbco.cell.length_a.free = True
8077

81-
sample_model.atom_sites['La'].b_iso.free = True
82-
sample_model.atom_sites['Ba'].b_iso.free = True
83-
sample_model.atom_sites['Co'].b_iso.free = True
84-
sample_model.atom_sites['O'].b_iso.free = True
78+
#lbco.atom_sites['La'].b_iso.free = True
79+
#lbco.atom_sites['Ba'].b_iso.free = True
80+
#lbco.atom_sites['Co'].b_iso.free = True
81+
#lbco.atom_sites['O'].b_iso.free = True
82+
for atom_site in lbco.atom_sites:
83+
atom_site.b_iso.free = True
8584

8685
# %%
87-
experiment.instrument.calib_twotheta_offset.free = True
86+
# Select experiment parameters to refine
87+
hrpt.linked_phases['lbco'].scale.free = True
8888

89-
experiment.peak.broad_gauss_u.free = True
90-
experiment.peak.broad_gauss_v.free = True
91-
experiment.peak.broad_gauss_w.free = True
92-
experiment.peak.broad_lorentz_y.free = True
89+
hrpt.instrument.calib_twotheta_offset.free = True
9390

94-
#experiment.background['10'].y.free = True
95-
#experiment.background['30'].y.free = True
96-
#experiment.background['50'].y.free = True
97-
#experiment.background['110'].y.free = True
98-
#experiment.background['165'].y.free = True
91+
hrpt.peak.broad_gauss_u.free = True
92+
hrpt.peak.broad_gauss_v.free = True
93+
hrpt.peak.broad_gauss_w.free = True
94+
hrpt.peak.broad_lorentz_y.free = True
9995

100-
experiment.linked_phases['lbco'].scale.free = True
96+
#hrpt.background['10'].y.free = True
97+
#hrpt.background['30'].y.free = True
98+
#hrpt.background['50'].y.free = True
99+
#hrpt.background['110'].y.free = True
100+
#hrpt.background['165'].y.free = True
101+
for line_segment in hrpt.background:
102+
line_segment.y.free = True
101103

102104
# %%
103105
project.analysis.fit()

tmp/data/hrpt.cif

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,23 @@ _instr.wavelength 1.494
1515
_instr.2theta_offset 0.6
1616

1717
loop_
18-
_pd_phase_block.id
19-
_pd_phase_block.scale
20-
lbco 10.0
18+
_pd_phase_block.id
19+
_pd_phase_block.scale
20+
lbco 10.0
2121

22+
loop_
23+
_pd_background_line_segment_X
24+
_pd_background_line_segment_intensity
25+
10 170
26+
30 170
27+
50 170
28+
110 170
29+
165 170
2230

23-
24-
loop_
25-
_pd_background.line_segment_X
26-
_pd_background.line_segment_intensity
27-
10 170
28-
30 170
29-
50 170
30-
110 170
31-
165 170
32-
33-
loop_
34-
_pd_meas.2theta_scan
35-
_pd_meas.intensity_total
36-
_pd_meas.intensity_total_su
31+
loop_
32+
_pd_meas.2theta_scan
33+
_pd_meas.intensity_total
34+
_pd_meas.intensity_total_su
3735
10.00 167.00 12.60
3836
10.05 157.00 12.50
3937
10.10 187.00 13.30

tmp/data/lbco.cif

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@
3434
10.15 197.0 14.0
3535
10.2 164.0 12.5
3636
10.25 171.0 13.0
37+

0 commit comments

Comments
 (0)