Repository navigation
feat: Add ConstantWavelengthInstrument and change CI to get pyobjcryst from main - #8
Conversation
|
@sbillinge ready for review. please merge #7 first. Here's a usage code snippet from pathlib import Path
import numpy as np
from pyobjcryst.crystal import create_crystal_from_cif
from pyobjcryst.powderpattern import PowderPattern
from diffpy.cmirietveld.instruments import ConstantWavelengthInstrument
# A pyobjcryst pattern for PbSO4 on a 16-110 degree 2theta grid
crystal = create_crystal_from_cif(str(Path("tests/testdata/PbSO4-Wyckoff.cif")))
two_theta = np.arange(16.0, 110.0, 0.025)
pattern = PowderPattern()
pattern.SetPowderPatternX(np.radians(two_theta))
pattern.SetPowderPatternObs(np.zeros_like(two_theta))
diffraction = pattern.AddPowderPatternDiffraction(crystal)
# Settings: a lab Cu source with a polarized beam
instrument = ConstantWavelengthInstrument()
instrument.set_xray_source("Cu")
instrument.set_polarization(0.95)
# Parameters: refinable values, here set by hand
instrument.zero.set_value(0.02)
instrument.wavelength.set_value(1.5419)
# Apply the settings, then push the Parameters before calculating
instrument.install(pattern, diffraction)
instrument.update(pattern, diffraction)
pattern.Prepare()
calculated_intensity = np.array(pattern.GetPowderPatternCalc()) |
|
sure. #7 is failing tests. Is it waiting on something else to merge first? |
|
One thing here is that there is some "magic" (things resetting behind the scenes when other things are set). The logic is perfect (set a tube resets a polarization) so I am ok with it, but it would be great if there was some kind of log or warning to the user when things like this happens so they don't spend hours figuring out why something they set magically changed its value. Not sure the best way to do that, but I just want to minimize witchcraft. |
ConstantWavelengthInstrumentConstantWavelengthInstrument and change CI to get pyobjcryst from main
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8 +/- ##
===========================================
+ Coverage 50.00% 97.94% +47.94%
===========================================
Files 2 5 +3
Lines 18 535 +517
===========================================
+ Hits 9 524 +515
- Misses 9 11 +2
🚀 New features to boost your workflow:
|
Warning teststest_setter_warns_wavelength_replaced
test_setter_warns_doublet_replaced
test_polarization_warns_without_xrays
test_setter_without_warning
test_install_kalpha2_ratio_kept
Non-warning teststest_parameter_names
test_pattern_parameter_values_and_bounds
test_wavelength_before_set
test_validate_before_wavelength_set
test_wavelength_after_setter
test_settings_version_after_setter
test_update_pattern_parameters
test_update_wavelength
test_install_shared_instrument
test_install_neutron_radiation
test_install_radiation_type
test_install_neutrons_after_tube
test_install_polarization_ratio
test_install_after_polarization_change
test_install_tube_set_after_polarization
test_install_polarization_rate_at_range_edges
test_install_single_wavelength_after_tube
test_install_xray_source
test_install_xray_wavelengths
test_set_xray_source_unknown_element
test_set_wavelength_outside_limits
test_set_xray_wavelengths_kalpha2_not_longer
test_set_doublet_with_neutron_radiation
test_set_radiation_type_with_doublet
test_set_radiation_type_unknown_type
test_set_polarization_outside_range
|
|
@sbillinge ready for review. Once again, please merge #7 first. I added warnings for several different cases. I recognize some of them are edge cases, but including them doesn't complicate the code too much. Above i have summarized the cases for each tests. I also changed CI on here such that it it downloads |
Please merge #7 first. This branch is stacked on it.
What problem does this PR address?
This adds
ConstantWavelengthInstrument, the instrument of a constant-wavelength x-ray, neutron or electron diffractometer. It is the first instrument component, and it is built on theComponenttargets and settings counter from #7.Parameters (refinable, with ObjCryst's defaults and limits as bounds):
zero,displacement,transparencyandmu_r, which belong to the pattern.wavelength, which belongs to the pattern's radiation. For a Kα1/Kα2 doublet it is the intensity-weighted mean. It is a Parameter so that it can be refined, for example to calibrate against a standard.Settings (applied by
install; each one bumpssettings_version, so every generator holding the instrument installs it again):set_radiation_type("X" | "N" | "E")set_wavelength(wavelength)set_xray_source(element, kalpha2_ratio=0.5)set_xray_wavelengths(kalpha1, kalpha2, kalpha2_ratio=0.5)set_polarization(polarization_rate)Design choices to review:
wavelengthisNoneuntil one of the setters gives it a value. Until then,_validateraises a two-partSrFitError, andFitRecipealready validates before a fit.update. They check:ObjCryst behaviour worked around (each workaround has a test, and each will get an upstream issue):
installtherefore sets the wavelength or tube first, then the rate, then callsPrepare().SetWavelength(wavelength)after a tube keeps the doublet.installsets the wavelength type to monochromatic.set_xray_sourcechecks that the wavelength changed. ObjCryst has wavelengths for Ag, Co, Cr, Cu, Fe and Mo only.installsets the ratio throughSetWavelength(element, ratio), which bypasses the limit.set_wavelengthraises an error for these, so electron support is limited for now.Tests use plain pyobjcryst PbSO4 patterns, as in #6, and compare each result with the same setting made directly in pyobjcryst. They check that:
updatepushes each Parameter.wavelengthand bumpssettings_version.Also in this PR:
mark_settings_changeddocstring example incomponent.pynow usesset_xray_source.CI will fail, as on the previous PRs, because the tests need pyobjcryst
main.