Commit afbd67fe by Cyril Guilloud

### extract energy handling functions to physics module. + tests and doc

parent 8b3ff773
Pipeline #11556 passed with stages
in 32 minutes and 15 seconds
 ... ... @@ -14,6 +14,9 @@ Bliss controller for 5-motors spectrometer test bench in EH1 from bliss.controllers.motor import CalcController import math from bliss.physics import spectroscopy # GLOBAL VARIABLES # HC = 1.2398418743309972e-06 # eV * m ALAT_SI = 5.431065 # Ang at 25C ... ... @@ -26,17 +29,6 @@ CRYST_ALPHA = 0.0 # miscut angle in degrees CRYST_R = 1000. # analyser bending radius in mm (=2*Rm) # UTILITY FUNCTIONS # def kev2wlen(energy): """ convert photon energy (E, keV) to wavelength (\$\lambda\$, \AA\$^{-1}\$)""" return (HC / energy) * 1e7 def wlen2kev(wlen): """ convert photon wavelength (\$\lambda\$, \AA\$^{-1}\$) to energy (E, keV)""" return (HC / wlen) * 1e7 def sqrt1over(d2m): if d2m == 0: return 0 ... ... @@ -52,9 +44,11 @@ def d_cubic(a, hkl): def theta_b(ene, d): """Bragg angle (rad) given energy (keV) and d-spacing (\AA)""" """Bragg angle (rad) given energy (keV) and d-spacing (Angstroms)""" if not (d == 0): return math.asin((kev2wlen(ene)) / (2 * d)) return math.asin( (spectroscopy.energy_kev_to_wavelength_angstrom(ene)) / (2 * d) ) else: print("ERROR: d-spacing is 0") return ... ... @@ -62,7 +56,9 @@ def theta_b(ene, d): def bragg_kev(theta, d): """energy (keV) given Bragg angle (deg) and d-spacing (\AA)""" return wlen2kev(2 * d * math.sin(math.radians(theta))) return spectroscopy.wavelength_angstrom_to_energy_kev( 2 * d * math.sin(math.radians(theta)) ) def get_dspacing(mat, hkl): ... ...
 ... ... @@ -27,8 +27,9 @@ Author: Mauro Rovezzi (mauro.rovezzi@esrf.eu) from bliss.controllers.motor import CalcController import math from bliss.physics import spectroscopy # GLOBAL VARIABLES # HC = 1.2398418743309972e-06 # eV * m ALAT_SI = 5.431065 # Ang at 25C ALAT_GE = 5.6579060 # Ang at 25C ... ... @@ -38,16 +39,6 @@ CRYST_HKL = [4, 4, 4] # analyser crystal reflection [h,k,l] CRYST_ALPHA = 0.0 # miscut angle in degrees CRYST_R = 1000. # analyser bending radius in mm (=2*Rm) # UTILITY FUNCTIONS # def kev2wlen(energy): """ convert photon energy (E, keV) to wavelength (\$\lambda\$, \AA\$^{-1}\$)""" return (HC / energy) * 1e7 def wlen2kev(wlen): """ convert photon wavelength (\$\lambda\$, \AA\$^{-1}\$) to energy (E, keV)""" return (HC / wlen) * 1e7 def sqrt1over(d2m): if d2m == 0: ... ... @@ -66,7 +57,9 @@ def d_cubic(a, hkl): def theta_b(ene, d): """Bragg angle (rad) given energy (keV) and d-spacing (\AA)""" if not (d == 0): return math.asin((kev2wlen(ene)) / (2 * d)) return math.asin( (spectroscopy.energy_kev_to_wavelength_angstrom(ene)) / (2 * d) ) else: print("ERROR: d-spacing is 0") return ... ... @@ -74,7 +67,9 @@ def theta_b(ene, d): def bragg_kev(theta, d): """energy (keV) given Bragg angle (deg) and d-spacing (\AA)""" return wlen2kev(2 * d * math.sin(math.radians(theta))) return spectroscopy.wavelength_angstrom_to_energy_kev( 2 * d * math.sin(math.radians(theta)) ) def get_dspacing(mat, hkl): ... ...
 ... ... @@ -50,3 +50,33 @@ def wavevector_to_energy(edge_energy, k): khbar = k * (1.0 * ur("hbar")) result = (khbar * khbar) / (2.0 * ur("electron_mass")) return result + edge_energy # same kind of functions, but usable is user code: def energy_kev_to_wavelength_angstrom(ene_kev): """ Converts photon energy in keV to wavelength in angstroms i.e: 1e7 * HC / ene Parameters: * : energy in keV (float) Returns: * wavelength in angstroms (float) """ energy_kev = ene_kev * ur.eV * 1000 wavelength = ur.c * ur.h / energy_kev return wavelength.to(ur.angstrom).magnitude def wavelength_angstrom_to_energy_kev(wl_angstrom): """ Converts wavelength in angstroms to photon energy in keV Parameters: * : wavelength in angstroms (float) Returns: * energy in keV (float) """ wavelength_angstrom = wl_angstrom * ur.angstrom energy_kev = ur.c * ur.h / wavelength_angstrom return energy_kev.to(ur.eV).magnitude / 1000
 ... ... @@ -88,13 +88,16 @@ units which are SI units. Failure to comply will result in unexpected values. ### Example import bliss.physics.diffraction from bliss.physics.units import ur mass = 0.1 * ur.mg E = mass * ur.c**2 print( E.to(ur.kJ) ) >>> 8987551.78737 kilojoule Example to convert 0.1 miligram in Kjoules with unknown formula. ```python import bliss.physics.diffraction from bliss.physics.units import ur mass = 0.1 * ur.mg E = mass * ur.c**2 print( E.to(ur.kJ) ) >>> 8987551.78737 kilojoule ``` ## Example of usage ... ... @@ -103,11 +106,12 @@ units which are SI units. Failure to comply will result in unexpected values. `mendeleev.elements` usage example: from mendeleev import elements Si = elements.Si print("Atomic number of {} is {}.".format(Si.name, Si.atomic_number)) >>> Atomic number of Silicon is 14. ```python from mendeleev import elements Si = elements.Si print("Atomic number of {} is {}.".format(Si.name, Si.atomic_number)) >>> Atomic number of Silicon is 14. ``` ### Crystal ... ... @@ -187,3 +191,24 @@ plane when the angle is 25.6 degrees: print( energy.to(ur.keV).magnitude ) >>> 17.5618627264 ### spectroscopy `energy_to_wavevector(edge_energy, energy)`: `wavevector_to_energy(edge_energy, k)`: user-friendly functions: ```python from bliss.physics import spectroscopy spectroscopy.energy_kev_to_wavelength_angstrom(7.5) # 1.6531226083801578 spectroscopy.wavelength_angstrom_to_energy_kev(1.653122) # 7.500002760141831 ```
 ... ... @@ -17,6 +17,9 @@ from bliss.physics.diffraction import CrystalPlane, MultiPlane from bliss.physics.diffraction import string_to_crystal_plane from bliss.physics.diffraction import distance_lattice_diffraction_plane import bliss.physics.diffraction as diff import bliss.physics.spectroscopy as spectro # Patch default 1e-12 default value for abs approx = partial(approx, rel=1e-3, abs=0.) ... ... @@ -148,3 +151,11 @@ def test_multi_plane(): assert multi.bragg_angle(b_energy) == approx(b_theta) assert multi.bragg_energy(b_thetas) == approx(b_energies) assert multi.bragg_angle(b_energies) == approx(b_thetas) def test_w2e_e2w(): # 7.5 keV ≈ 1.65 angstrom assert spectro.energy_kev_to_wavelength_angstrom(7.5) == approx(1.653122) # 1.653122 angstrom ≈ 7.5 keV assert spectro.wavelength_angstrom_to_energy_kev(1.653122) == approx(7.5)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment