def test_pychop_let(self): variants = ['High flux', 'Intermediate', 'High resolution'] res = [] flux = [] for inc, variant in enumerate(variants): chopobj = PyChop2('LET', variant) # Checks that initialisations instanciates the correct submodule # which does the actual calculations. PyChop2 is just a wrapper. self.assertTrue('ISISDisk' in chopobj.getObject().__module__) # Checks that it instanciates the correct variant self.assertTrue(variant in chopobj.getChopper()) # Code should give an error if the chopper settings and Ei have # not been set. self.assertRaises(ValueError, chopobj.getResolution) chopobj.setFrequency(200) chopobj.setEi(18) rr, ff = chopobj.getResFlux(np.linspace(0,17,10)) res.append(rr) flux.append(ff) # Checks that the flux should be highest for 'High flux', then 'Intermediate', 'High resolution' self.assertTrue(flux[0] > flux[1]) self.assertTrue(flux[1] >= flux[2]) # Checks that the resolution should be best for 'High resolution', then 'Intermediate', 'High flux' self.assertTrue(res[2][0] <= res[1][0]) self.assertTrue(res[1][0] <= res[0][0]) # Now tests the standalone function for inc, variant in enumerate(variants): rr, ff = PyChop2.calculate('LET', variant, 200, 18, 0) self.assertAlmostEqual(rr[0], res[inc][0], places=7) self.assertAlmostEqual(ff, flux[inc], places=7)
def test_pychop_fermi(self): instnames = ['maps', 'mari', 'merlin'] res = [] flux = [] for inc, instname in enumerate(instnames): chopobj = PyChop2(instname) # Code should give an error if the chopper settings and Ei have # not been set. self.assertRaises(ValueError, chopobj.getResolution) chopobj.setChopper('s', 200) chopobj.setEi(18) rr, ff = chopobj.getResFlux(np.linspace(0, 17, 10)) res.append(rr) flux.append(ff) # Checks that the flux should be highest for MERLIN, MARI and MAPS in that order self.assertTrue(flux[2] > flux[1]) # Note that MAPS has been upgraded so now should have higher flux than MARI. self.assertTrue(flux[0] > flux[1]) # Checks that the resolution should be best for MARI, MAPS and MERLIN in that order self.assertTrue(res[1][0] < res[0][0]) self.assertTrue(res[0][0] < res[2][0]) # Now tests the standalone function for inc, instname in enumerate(instnames): rr, ff = PyChop2.calculate(instname, 's', 200, 18, 0) self.assertAlmostEqual(rr[0], res[inc][0], places=7) self.assertAlmostEqual(ff, flux[inc], places=7)
def test_pychop_fermi(self): instnames = ['maps', 'mari', 'merlin'] res = [] flux = [] for inc, instname in enumerate(instnames): chopobj = PyChop2(instname) # Checks that initialisations instanciates the correct submodule # which does the actual calculations. PyChop2 is just a wrapper. self.assertTrue('ISISFermi' in chopobj.getObject().__module__) # Code should give an error if the chopper settings and Ei have # not been set. self.assertRaises(ValueError, chopobj.getResolution) chopobj.setChopper('s', 200) chopobj.setEi(18) rr, ff = chopobj.getResFlux(np.linspace(0,17,10)) res.append(rr) flux.append(ff) # Checks that the flux should be highest for MERLIN, MARI and MAPS in that order self.assertTrue(flux[2] > flux[1]) self.assertTrue(flux[1] > flux[0]) # Checks that the resolution should be best for MARI, MAPS and MERLIN in that order self.assertTrue(res[1][0] < res[0][0]) self.assertTrue(res[0][0] < res[2][0]) # Now tests the standalone function for inc, instname in enumerate(instnames): rr, ff = PyChop2.calculate(instname, 's', 200, 18, 0) self.assertAlmostEqual(rr[0], res[inc][0], places=7) self.assertAlmostEqual(ff, flux[inc], places=7)
def test_pychop_fermi(self): instnames = ['maps', 'mari', 'merlin'] res = [] flux = [] for inc, instname in enumerate(instnames): chopobj = PyChop2(instname) # Code should give an error if the chopper settings and Ei have # not been set. self.assertRaises(ValueError, chopobj.getResolution) chopobj.setChopper('s', 200) chopobj.setEi(18) rr, ff = chopobj.getResFlux(np.linspace(0,17,10)) res.append(rr) flux.append(ff) # Checks that the flux should be highest for MERLIN, MARI and MAPS in that order self.assertTrue(flux[2] > flux[1]) # Note that MAPS has been upgraded so now should have higher flux than MARI. self.assertTrue(flux[0] > flux[1]) # Checks that the resolution should be best for MARI, MAPS, and MERLIN in that order # actually MAPS and MARI resolutions are very close self.assertTrue(res[1][0] < res[0][0]) self.assertTrue(res[0][0] < res[2][0]) # Now tests the standalone function for inc, instname in enumerate(instnames): rr, ff = PyChop2.calculate(instname, 's', 200, 18, 0) self.assertAlmostEqual(rr[0], res[inc][0], places=7) self.assertAlmostEqual(ff, flux[inc], places=7)
def _getModel(path, chopper, chopper_freq): key = path, chopper, chopper_freq if key not in model_cache: model = PyChop2(path, chopper, chopper_freq) model_cache[key] = model else: model = model_cache[key] return model
def _getModel(path, chopper): key = path, chopper if key not in model_cache: model = PyChop2(path) model.setChopper(chopper) model_cache[key] = model else: model = model_cache[key] return model
def test_pychop_invalid_ei(self): chopobj = PyChop2('MARI', 'G', 400.) chopobj.setEi(120) with warnings.catch_warnings(record=True) as w: res = chopobj.getResolution(130.) assert len(w) == 1 assert issubclass(w[0].category, UserWarning) assert "Cannot calculate for energy transfer greater than Ei" in str( w[0].message) assert np.isnan(res[0])
from CrystalField import CrystalField, CrystalFieldFit, Background, Function, ResolutionModel from PyChop import PyChop2 # load the data data_ws1 = Load('MER38435_10p22meV.txt') data_ws2 = Load('MER38436_10p22meV.txt') # Sets up a resolution function merlin = PyChop2('MERLIN', 'G', 250.) merlin.setEi(10.) resmod = ResolutionModel(merlin.getResolution, xstart=-10, xend=9.0, accuracy=0.01) Kelvin_to_meV = 1. / 11.6 # Parameters from https://doi.org/10.1016/0921-4526(91)90575-Y lit_par = { 'B20': -.27, 'B22': -.34, 'B40': 1e-6, 'B42': 0.04158, 'B44': 0.01369, 'B60': 0.112e-3, 'B62': 0.4185e-3, 'B64': -0.555e-3, 'B66': 0.588e-3 } # K for parameter in lit_par.keys(): lit_par[parameter] *= Kelvin_to_meV
import os, sys, glob, numpy as np sys.path.insert(0, "/SNS/users/lj7/dv") from PyChop import PyChop2 instrument = PyChop2('cncs.yaml') instrument.moderator.mod_pars = [0, 0, 0] instrument.setChopper('High Resolution') print instrument.getResFlux(Etrans=0, Ei_in=80)
def elastic_res_flux(chopper='ARCS-100-1.5-SMI', chopper_freq=600., Ei=100.): instrument = PyChop2(yamlpath, chopper, chopper_freq) res, flux = instrument.getResFlux(Etrans=0., Ei_in=Ei) return res[0], flux[0]*scale_flux
def res_vs_E(E, chopper='ARCS-100-1.5-SMI', chopper_freq=600., Ei=100.): instrument = PyChop2(yamlpath, chopper, chopper_freq) res, flux = instrument.getResFlux(Etrans=E, Ei_in=Ei) return res
def runTest(self): from CrystalField import CrystalField, CrystalFieldFit, CrystalFieldMultiSite, Background, Function, ResolutionModel cf = CrystalField('Ce', 'C2v') cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770) cf['B40'] = -0.031 b = cf['B40'] # Calculate and return the Hamiltonian matrix as a 2D numpy array. h = cf.getHamiltonian() print(h) # Calculate and return the eigenvalues of the Hamiltonian as a 1D numpy array. e = cf.getEigenvalues() print(e) # Calculate and return the eigenvectors of the Hamiltonian as a 2D numpy array. w = cf.getEigenvectors() print(w) # Using the keyword argument cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44) # Using the property cf.Temperature = 44 print(cf.getPeakList()) #[[ 0.00000000e+00 2.44006198e+01 4.24977124e+01 1.80970926e+01 -2.44006198e+01] # [ 2.16711565e+02 8.83098530e+01 5.04430056e+00 1.71153708e-01 1.41609425e-01]] cf.ToleranceIntensity = 1 print(cf.getPeakList()) #[[ 0. 24.40061976 42.49771237] # [ 216.71156467 88.30985303 5.04430056]] cf.PeakShape = 'Gaussian' cf.FWHM = 0.9 sp = cf.getSpectrum() print(cf.function) CrystalField_Ce = CreateWorkspace(*sp) print(CrystalField_Ce) # If the peak shape is Gaussian cf.peaks.param[1]['Sigma'] = 2.0 cf.peaks.param[2]['Sigma'] = 0.01 # If the peak shape is Lorentzian cf.PeakShape = 'Lorentzian' cf.peaks.param[1]['FWHM'] = 2.0 cf.peaks.param[2]['FWHM'] = 0.01 cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=44.0, FWHM=1.1) cf.background = Background(peak=Function('Gaussian', Height=10, Sigma=1), background=Function('LinearBackground', A0=1.0, A1=0.01)) h = cf.background.peak.param['Height'] a1 = cf.background.background.param['A1'] print(h) print(a1) cf.ties(B20=1.0, B40='B20/2') cf.constraints('1 < B22 <= 2', 'B22 < 4') print(cf.function[1].getTies()) print(cf.function[1].getConstraints()) cf.background.peak.ties(Height=10.1) cf.background.peak.constraints('Sigma > 0') cf.background.background.ties(A0=0.1) cf.background.background.constraints('A1 > 0') print(cf.function[0][0].getConstraints()) print(cf.function[0][1].getConstraints()) print(cf.function.getTies()) print(cf.function.getConstraints()) cf.peaks.ties({'f2.FWHM': '2*f1.FWHM', 'f3.FWHM': '2*f2.FWHM'}) cf.peaks.constraints('f0.FWHM < 2.2', 'f1.FWHM >= 0.1') cf.PeakShape = 'Gaussian' cf.peaks.tieAll('Sigma=0.1', 3) cf.peaks.constrainAll('0 < Sigma < 0.1', 4) cf.peaks.tieAll('Sigma=f0.Sigma', 1, 3) cf.peaks.ties({ 'f1.Sigma': 'f0.Sigma', 'f2.Sigma': 'f0.Sigma', 'f3.Sigma': 'f0.Sigma' }) rm = ResolutionModel(([1, 2, 3, 100], [0.1, 0.3, 0.35, 2.1])) cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44.0, ResolutionModel=rm) rm = ResolutionModel(self.my_func, xstart=0.0, xend=24.0, accuracy=0.01) cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44.0, ResolutionModel=rm) marires = PyChop2('MARI') marires.setChopper('S') marires.setFrequency(250) marires.setEi(30) rm = ResolutionModel(marires.getResolution, xstart=0.0, xend=29.0, accuracy=0.01) cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44.0, ResolutionModel=rm) cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44.0, ResolutionModel=rm, FWHMVariation=0.1) # --------------------------- cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=[44.0, 50], FWHM=[1.1, 0.9]) cf.PeakShape = 'Lorentzian' cf.peaks[0].param[0]['FWHM'] = 1.11 cf.peaks[1].param[1]['FWHM'] = 1.12 cf.background = Background(peak=Function('Gaussian', Height=10, Sigma=0.3), background=Function('FlatBackground', A0=1.0)) cf.background[1].peak.param['Sigma'] = 0.8 cf.background[1].background.param['A0'] = 1.1 # The B parameters are common for all spectra - syntax doesn't change cf.ties(B20=1.0, B40='B20/2') cf.constraints('1 < B22 <= 2', 'B22 < 4') # Backgrounds and peaks are different for different spectra - must be indexed cf.background[0].peak.ties(Height=10.1) cf.background[0].peak.constraints('Sigma > 0.1') cf.background[1].peak.ties(Height=20.2) cf.background[1].peak.constraints('Sigma > 0.2') cf.peaks[1].tieAll('FWHM=2*f1.FWHM', 2, 5) cf.peaks[0].constrainAll('FWHM < 2.2', 1, 4) rm = ResolutionModel([self.my_func, marires.getResolution], 0, 100, accuracy=0.01) cf.ResolutionModel = rm # Calculate second spectrum, use the generated x-values sp = cf.getSpectrum(1) # Calculate second spectrum, use the first spectrum of a workspace sp = cf.getSpectrum(1, 'CrystalField_Ce') # Calculate first spectrum, use the i-th spectrum of a workspace i = 0 sp = cf.getSpectrum(0, 'CrystalField_Ce', i) print(cf.function) cf.Temperature = [5, 50, 150] print() print(cf.function) ws = 'CrystalField_Ce' ws1 = 'CrystalField_Ce' ws2 = 'CrystalField_Ce' cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=5) # In case of a single spectrum (ws is a workspace) fit = CrystalFieldFit(Model=cf, InputWorkspace=ws) # Or for multiple spectra fit = CrystalFieldFit(Model=cf, InputWorkspace=[ws1, ws2]) cf.Temperature = [5, 50] fit.fit() params = { 'B20': 0.377, 'B22': 3.9, 'B40': -0.03, 'B42': -0.116, 'B44': -0.125, 'Temperature': [44.0, 50], 'FWHM': [1.1, 0.9] } cf1 = CrystalField('Ce', 'C2v', **params) cf2 = CrystalField('Pr', 'C2v', **params) cfms = cf1 + cf2 cf = 2 * cf1 + cf2 cfms = CrystalFieldMultiSite(Ions=['Ce', 'Pr'], Symmetries=['C2v', 'C2v'], Temperatures=[44.0], FWHMs=[1.1]) cfms['ion0.B40'] = -0.031 cfms['ion1.B20'] = 0.37737 b = cfms['ion0.B22'] print(b) print(cfms.function) cfms = CrystalFieldMultiSite(Ions=['Ce', 'Pr'], Symmetries=['C2v', 'C2v'], Temperatures=[44.0], FWHMs=[1.1], parameters={ 'ion0.B20': 0.37737, 'ion0.B22': 3.9770, 'ion1.B40': -0.031787, 'ion1.B42': -0.11611, 'ion1.B44': -0.12544 }) cfms = CrystalFieldMultiSite( Ions='Ce', Symmetries='C2v', Temperatures=[20], FWHMs=[1.0], Background= 'name=Gaussian,Height=0,PeakCentre=1,Sigma=0;name=LinearBackground,A0=0,A1=0' ) cfms = CrystalFieldMultiSite(Ions=['Ce'], Symmetries=['C2v'], Temperatures=[50], FWHMs=[0.9], Background=LinearBackground(A0=1.0), BackgroundPeak=Gaussian(Height=10, Sigma=0.3)) cfms = CrystalFieldMultiSite(Ions='Ce', Symmetries='C2v', Temperatures=[20], FWHMs=[1.0], Background=Gaussian(PeakCentre=1) + LinearBackground()) cfms = CrystalFieldMultiSite(Ions=['Ce', 'Pr'], Symmetries=['C2v', 'C2v'], Temperatures=[44, 50], FWHMs=[1.1, 0.9], Background=FlatBackground(), BackgroundPeak=Gaussian(Height=10, Sigma=0.3), parameters={ 'ion0.B20': 0.37737, 'ion0.B22': 3.9770, 'ion1.B40': -0.031787, 'ion1.B42': -0.11611, 'ion1.B44': -0.12544 }) cfms.ties({'sp0.bg.f0.Height': 10.1}) cfms.constraints('sp0.bg.f0.Sigma > 0.1') cfms.constraints('ion0.sp0.pk1.FWHM < 2.2') cfms.ties({ 'ion0.sp1.pk2.FWHM': '2*ion0.sp1.pk1.FWHM', 'ion1.sp1.pk3.FWHM': '2*ion1.sp1.pk2.FWHM' }) # -------------------------- params = { 'ion0.B20': 0.37737, 'ion0.B22': 3.9770, 'ion1.B40': -0.031787, 'ion1.B42': -0.11611, 'ion1.B44': -0.12544 } cf = CrystalFieldMultiSite(Ions=['Ce', 'Pr'], Symmetries=['C2v', 'C2v'], Temperatures=[44.0, 50.0], FWHMs=[1.0, 1.0], ToleranceIntensity=6.0, ToleranceEnergy=1.0, FixAllPeaks=True, parameters=params) cf.fix('ion0.BmolX', 'ion0.BmolY', 'ion0.BmolZ', 'ion0.BextX', 'ion0.BextY', 'ion0.BextZ', 'ion0.B40', 'ion0.B42', 'ion0.B44', 'ion0.B60', 'ion0.B62', 'ion0.B64', 'ion0.B66', 'ion0.IntensityScaling', 'ion1.BmolX', 'ion1.BmolY', 'ion1.BmolZ', 'ion1.BextX', 'ion1.BextY', 'ion1.BextZ', 'ion1.B40', 'ion1.B42', 'ion1.B44', 'ion1.B60', 'ion1.B62', 'ion1.B64', 'ion1.B66', 'ion1.IntensityScaling', 'sp0.IntensityScaling', 'sp1.IntensityScaling') chi2 = CalculateChiSquared(str(cf.function), InputWorkspace=ws1, InputWorkspace_1=ws2)[1] fit = CrystalFieldFit(Model=cf, InputWorkspace=[ws1, ws2], MaxIterations=10) fit.fit() print(chi2) cfms = CrystalFieldMultiSite(Ions='Ce', Symmetries='C2', Temperatures=[25], FWHMs=[1.0], PeakShape='Gaussian', BmolX=1.0, B40=-0.02) print(str(cfms.function).split(',')[0]) # -------------------------- # Create some crystal field data origin = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=44.0, FWHM=1.1) x, y = origin.getSpectrum() ws = makeWorkspace(x, y) # Define a CrystalField object with parameters slightly shifted. cf = CrystalField('Ce', 'C2v', B20=0, B22=0, B40=0, B42=0, B44=0, Temperature=44.0, FWHM=1.0, ResolutionModel=([0, 100], [1, 1]), FWHMVariation=0) # Set any ties on the field parameters. cf.ties(B20=0.37737) # Create a fit object fit = CrystalFieldFit(cf, InputWorkspace=ws) # Find initial values for the field parameters. # You need to define the energy splitting and names of parameters to estimate. # Optionally additional constraints can be set on tied parameters (eg, peak centres). fit.estimate_parameters( EnergySplitting=50, Parameters=['B22', 'B40', 'B42', 'B44'], Constraints='20<f1.PeakCentre<45,20<f2.PeakCentre<45', NSamples=1000) print('Returned', fit.get_number_estimates(), 'sets of parameters.') # The first set (the smallest chi squared) is selected by default. # Select a different parameter set if required fit.select_estimated_parameters(3) print(cf['B22'], cf['B40'], cf['B42'], cf['B44']) # Run fit fit.fit() # -------------------------- from CrystalField import PointCharge axial_pc_model = PointCharge([[-2, 0, 0, -4], [-2, 0, 0, 4]], 'Nd') axial_blm = axial_pc_model.calculate() print(axial_blm) from CrystalField import PointCharge from mantid.geometry import CrystalStructure perovskite_structure = CrystalStructure( '4 4 4 90 90 90', 'P m -3 m', 'Ce 0 0 0 1 0; Al 0.5 0.5 0.5 1 0; O 0.5 0.5 0 1 0') cubic_pc_model = PointCharge(perovskite_structure, 'Ce', Charges={ 'Ce': 3, 'Al': 3, 'O': -2 }, MaxDistance=7.5) cubic_pc_model = PointCharge(perovskite_structure, 'Ce', Charges={ 'Ce': 3, 'Al': 3, 'O': -2 }, Neighbour=2) print(cubic_pc_model) cif_pc_model = PointCharge('Sm2O3.cif') print(cif_pc_model.getIons()) cif_pc_model.Charges = { 'O1': -2, 'O2': -2, 'Sm1': 3, 'Sm2': 3, 'Sm3': 3 } cif_pc_model.IonLabel = 'Sm2' cif_pc_model.Neighbour = 1 cif_blm = cif_pc_model.calculate() print(cif_blm) bad_pc_model = PointCharge('Sm2O3.cif', MaxDistance=7.5, Neighbour=2) print(bad_pc_model.Neighbour) print(bad_pc_model.MaxDistance) cif_pc_model.Charges = {'O': -2, 'Sm': 3} cif_blm = cif_pc_model.calculate() print(cif_blm) cf = CrystalField('Sm', 'C2', Temperature=5, FWHM=10, **cif_pc_model.calculate()) fit = CrystalFieldFit(cf, InputWorkspace=ws) fit = CrystalFieldFit(cf, InputWorkspace=ws) fit.fit() # -------------------------- cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, Temperature=44.0) Cv = cf.getHeatCapacity( ) # Calculates Cv(T) for 1<T<300K in 1K steps (default) T = np.arange(1, 900, 5) Cv = cf.getHeatCapacity( T ) # Calculates Cv(T) for specified values of T (1 to 900K in 5K steps here) # Temperatures from a single spectrum workspace ws = CreateWorkspace(T, T, T) Cv = cf.getHeatCapacity( ws) # Use the x-values of a workspace as the temperatures ws_cp = CreateWorkspace(*Cv) # Temperatures from a multi-spectrum workspace ws = CreateWorkspace(T, T, T, NSpec=2) Cv = cf.getHeatCapacity( ws, 1) # Uses the second spectrum's x-values for T (e.g. 450<T<900) chi_v = cf.getSusceptibility(T, Hdir=[1, 1, 1]) chi_v_powder = cf.getSusceptibility(T, Hdir='powder') chi_v_cgs = cf.getSusceptibility(T, Hdir=[1, 1, 0], Unit='SI') chi_v_bohr = cf.getSusceptibility(T, Unit='bohr') print(type([chi_v, chi_v_powder, chi_v_cgs, chi_v_bohr])) moment_t = cf.getMagneticMoment( Temperature=T, Hdir=[1, 1, 1], Hmag=0.1) # Calcs M(T) with at 0.1T field||[111] H = np.linspace(0, 30, 121) moment_h = cf.getMagneticMoment( Hmag=H, Hdir='powder', Temperature=10) # Calcs M(H) at 10K for powder sample moment_SI = cf.getMagneticMoment( H, [1, 1, 1], Unit='SI') # M(H) in Am^2/mol at 1K for H||[111] moment_cgs = cf.getMagneticMoment( 100, Temperature=T, Unit='cgs') # M(T) in emu/mol in a field of 100G || [001] print(type([moment_t, moment_h, moment_SI, moment_cgs])) # -------------------------- from CrystalField import CrystalField, CrystalFieldFit, PhysicalProperties # Fits a heat capacity dataset - you must have subtracted the phonon contribution by some method already # and the data must be in J/mol/K. cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, PhysicalProperty=PhysicalProperties('Cv')) fitcv = CrystalFieldFit(Model=cf, InputWorkspace=ws) fitcv.fit() params = { 'B20': 0.37737, 'B22': 3.9770, 'B40': -0.031787, 'B42': -0.11611, 'B44': -0.12544 } cf = CrystalField('Ce', 'C2v', **params) cf.PhysicalProperty = PhysicalProperties('Cv') fitcv = CrystalFieldFit(Model=cf, InputWorkspace=ws) fitcv.fit() # Fits a susceptibility dataset. Data is the volume susceptibility in SI units cf = CrystalField('Ce', 'C2v', **params) cf.PhysicalProperty = PhysicalProperties('susc', Hdir='powder', Unit='SI') fit_chi = CrystalFieldFit(Model=cf, InputWorkspace=ws) fit_chi.fit() # Fits a magnetisation dataset. Data is in emu/mol, and was measured at 5K with the field || [111]. cf = CrystalField('Ce', 'C2v', **params) cf.PhysicalProperty = PhysicalProperties('M(H)', Temperature=5, Hdir=[1, 1, 1], Unit='cgs') fit_mag = CrystalFieldFit(Model=cf, InputWorkspace=ws) fit_mag.fit() # Fits a magnetisation vs temperature dataset. Data is in Am^2/mol, measured with a 0.1T field || [110] cf = CrystalField('Ce', 'C2v', **params) cf.PhysicalProperty = PhysicalProperties('M(T)', Hmag=0.1, Hdir=[1, 1, 0], Unit='SI') fit_moment = CrystalFieldFit(Model=cf, InputWorkspace=ws) fit_moment.fit() # -------------------------- # Pregenerate the required workspaces for tt in [10, 44, 50]: cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=tt, FWHM=0.5) x, y = cf.getSpectrum() self.my_create_ws('ws_ins_' + str(tt) + 'K', x, y) ws_ins_10K = mtd['ws_ins_10K'] ws_ins_44K = mtd['ws_ins_44K'] ws_ins_50K = mtd['ws_ins_50K'] ws_cp = self.my_create_ws('ws_cp', *cf.getHeatCapacity()) ws_chi = self.my_create_ws( 'ws_chi', *cf.getSusceptibility(np.linspace(1, 300, 100), Hdir='powder', Unit='cgs')) ws_mag = self.my_create_ws( 'ws_mag', *cf.getMagneticMoment(Hmag=np.linspace(0, 30, 100), Hdir=[1, 1, 1], Unit='bohr', Temperature=5)) # -------------------------- # Fits an INS spectrum (at 10K) and the heat capacity simultaneously cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544) cf.Temperature = 10 cf.FWHM = 1.5 cf.PhysicalProperty = PhysicalProperties('Cv') fit = CrystalFieldFit(Model=cf, InputWorkspace=[ws_ins_10K, ws_cp]) fit.fit() # Fits two INS spectra (at 44K and 50K) and the heat capacity, susceptibility and magnetisation simultaneously. PPCv = PhysicalProperties('Cv') PPchi = PhysicalProperties('susc', 'powder', Unit='cgs') PPMag = PhysicalProperties('M(H)', [1, 1, 1], 5, 'bohr') cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544, Temperature=[44.0, 50], FWHM=[1.1, 0.9], PhysicalProperty=[PPCv, PPchi, PPMag]) fit = CrystalFieldFit( Model=cf, InputWorkspace=[ws_ins_44K, ws_ins_50K, ws_cp, ws_chi, ws_mag]) fit.fit()