Skip to content

Commit

Permalink
initial version of the update pdffit2 interface
Browse files Browse the repository at this point in the history
  • Loading branch information
rozyczko committed Nov 24, 2024
1 parent 02b4a3a commit 19f18f6
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 30 deletions.
17 changes: 17 additions & 0 deletions easydiffraction/Interfaces/pdffit2.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from easydiffraction import Lattice
from easydiffraction import Phases
from easydiffraction import Phase
from easydiffraction import Site
from easydiffraction import SpaceGroup
from easydiffraction.calculators.pdffit2 import Pdffit2 as Pdffit2_calc
Expand Down Expand Up @@ -140,6 +141,12 @@ def create(self, model) -> List[ItemContainer]:
self._phase = model
self.calculator.phases = model

elif issubclass(t_, Phase):
self._phase = model
if self.calculator.phases is None:
self.calculator.phases = Phases()
self.calculator.phases.append(model)

elif issubclass(t_, Sample):
self.updateCif()

Expand Down Expand Up @@ -180,6 +187,16 @@ def updateCif(self, *args, **kwargs):
self.calculator.cif_string = str(self._phase.cif)
pass

def updateModelCif(self, cif_string: str):
self.calculator.cif_string = cif_string

def add_phase(self, phases_obj: Phases, phase_obj: Phase) -> None:
"""
Add a phase to the phases object.
"""
self.calculator.phases = phases_obj
self.calculator.phases[0].scale = phase_obj.scale.raw_value

@staticmethod
def __identify(obj):
return obj.unique_name
Expand Down
12 changes: 11 additions & 1 deletion easydiffraction/Job.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
from easydiffraction.Profiles.P1D import Instrument1DTOFParameters
from easydiffraction.Profiles.P1D import PolPowder1DParameters
from easydiffraction.Profiles.P1D import Powder1DParameters
from easydiffraction.Profiles.P1D import PDFParameters

# from easydiffraction.Profiles.Sample import Sample
from easydiffraction.sample import Sample

try:
Expand Down Expand Up @@ -148,6 +148,10 @@ def __init__(
self._kwargs['_parameters'] = self.sample.parameters
self._kwargs['_pattern'] = self.sample.pattern

# set the appropriate calculator, if needed
if self.type.is_pdf:
self.calculator = "Pdffit2"


@property
def sample(self) -> Sample:
Expand All @@ -169,6 +173,9 @@ def sample(self, value: Union[Sample, None]) -> None:
parameters = Instrument1DCWParameters()
elif self.type.is_tof:
parameters = Instrument1DTOFParameters()
# special experiment type
if self.type.is_pdf:
parameters = PDFParameters()
self._sample = Sample("Sample", parameters=parameters, pattern=pattern)

@property
Expand Down Expand Up @@ -420,6 +427,9 @@ def add_experiment_from_file(self, file_url: str) -> None:
# check the extension first and then call the appropriate method
if file_url.endswith(".xye"):
self.experiment.from_xye_file(file_url)
elif file_url.endswith(".gr"):
# PDF data
self.experiment.from_gr_file(file_url)
else:
self.experiment.from_cif_file(file_url)

Expand Down
8 changes: 8 additions & 0 deletions easydiffraction/Profiles/Analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ def fit(self, x: Union[xr.DataArray, np.ndarray],
return None
return res

@property
def calculator(self):
return self.interface.current_interface_name

@calculator.setter
def calculator(self, value: str):
self.interface.switch(value)

@property
def available_minimizers(self) -> list:
"""
Expand Down
21 changes: 21 additions & 0 deletions easydiffraction/Profiles/Experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from easyscience.Objects.ObjectClasses import Descriptor
from easyscience.Objects.ObjectClasses import Parameter
from gemmi import cif
from easydiffraction.Interfaces.pdffit2 import readGRData

from easydiffraction.elements.Backgrounds.Point import BackgroundPoint
from easydiffraction.elements.Backgrounds.Point import PointBackground
Expand All @@ -20,6 +21,7 @@
from easydiffraction.Profiles.P1D import Instrument1DTOFParameters
from easydiffraction.Profiles.P1D import PolPowder1DParameters
from easydiffraction.Profiles.P1D import Powder1DParameters
from easydiffraction.Profiles.P1D import PDFParameters

_DEFAULT_DATA_BLOCK_NO_MEAS_PD_CWL = """data_pnd
Expand Down Expand Up @@ -326,7 +328,26 @@ def data_from_cif_block(self, block, experiment_name):
data_x = data['x']
data_y = data['y']
data_e = data['e']
self.assign_data(data_x, data_y, data_e, experiment_name)

def from_gr_file(self, file_url, experiment_name=None):
"""
Load a GR file into the experiment.
"""
data = readGRData(file_url)
data_x = data[:, 0]
data_y = [data[:, 1]]
data_e = [data[:, 3]]
self.parameters = PDFParameters()
if experiment_name is None:
experiment_name = 'pdf'
self.name = experiment_name
self.assign_data(data_x, data_y, data_e, experiment_name)

def assign_data(self, data_x, data_y, data_e, experiment_name):
"""
Assign data to the experiment store.
"""
coord_name = self.job_name + "_" + experiment_name + "_" + self._x_axis_name

self._datastore.store.easyscience.add_coordinate(coord_name, data_x)
Expand Down
20 changes: 18 additions & 2 deletions easydiffraction/Profiles/JobType.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ class JobType():
polarized: pol
longitudinal polarized: lpa
spherical polarimetry: snp
special experiment type:
PDF: pdf
String-based specification can be provided in any order, in any combination.
Example:
a = JobType("pd-cwl-unp-1d-xray")
b = JobType("cwl-unp-neut")
c = JobType("tof")
d = JobType("pdf")
"""
# Sample type
STR_POWDER = "pd"
Expand All @@ -49,6 +51,8 @@ class JobType():
STR_UPOL = "unp"
STR_LPOL = "lpa"
STR_SPOL = "snp"
# Special experiment type
STR_PDF = "pdf"

# Default values
DEFAULT_TYPE = "pd-cwl-unp-1d-neut"
Expand Down Expand Up @@ -86,7 +90,7 @@ def init_flags(self):
self._is_unp = False
self._is_lpa = False
self._is_snp = False

self._is_pdf = False
@property
def is_pd(self):
return self._is_pd
Expand Down Expand Up @@ -207,6 +211,15 @@ def is_snp(self, value):
self._is_lpa = not value
self.validate()

@property
def is_pdf(self):
return self._is_pdf

@is_pdf.setter
def is_pdf(self, value):
self._is_pdf = value
self.validate()

def parse_job_type(self, job_type: str):
# this will parse the substrings of the job type
# and amend the existing job type
Expand Down Expand Up @@ -238,6 +251,9 @@ def to_typestr(self) -> None:
elif self._is_snp:
pol_flag = self.STR_SPOL
self.type_str = f"{sample_flag}-{beam_flag}-{pol_flag}-{dim_flag}-{radiation_flag}"
# special experiment type
if self._is_pdf:
self.type_str = f"{self.STR_PDF}"

def validate(self):
"""
Expand Down
42 changes: 15 additions & 27 deletions examples_old/PDF2/Ni_fitting.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@

import os

from easyCore.Fitting.Fitting import Fitter
from easyDiffractionLib import Phases
from easyDiffractionLib.Jobs import Powder1DCW
from easyDiffractionLib.interface import InterfaceFactory as Calculator
from easyDiffractionLib.Profiles.P1D import PDFParameters
from easyDiffractionLib.Interfaces.pdffit2 import readGRData
import easydiffraction as ed


# data_fname = "D:\\projects\\easyScience\\easyDiffractionLib\\examples\\PDF\\Ni-xray.gr"
data_fname = os.path.realpath('Ni-xray.gr')
data = readGRData(data_fname)
job = ed.Job(type='pdf')

# phase_cif_name = "D:\\projects\\easyScience\\easyDiffractionLib\\examples\\PDF\\Ni.cif"
phase_cif_name = "Ni.cif"
phases = Phases.from_cif_file(phase_cif_name)
data_fname = r"C:\projects\easy\test\EasyDiffractionLib\examples_old\PDF2\Ni-xray.gr"
job.add_experiment_from_file(data_fname)

parameters = PDFParameters()
phase_cif_name = r"C:\projects\easy\test\EasyDiffractionLib\examples_old\PDF2\\Ni.cif"
job.add_sample_from_file(phase_cif_name)

calculator = Calculator()
calculator.switch("Pdffit2")

job = Powder1DCW('Ni', parameters=parameters, phases=phases, interface=calculator)

fitter = Fitter(job, calculator.fit_func)

parameters = job.parameters
# initial values to not be too far from optimized ones
Expand All @@ -44,8 +31,6 @@
job.phases[0].scale = 0.366013
job.phases[0].cell.length_a = 3.52

x_data = data[:, 0]

# define params to optimize
job.phases[0].cell.length_a.fixed = False
job.phases[0].scale.fixed = False
Expand All @@ -58,20 +43,23 @@

fit_parameters = job.get_fit_parameters()

result = fitter.fit(x_data, data[:, 1],
method='least_squares', minimizer_kwargs={'diff_step': 1e-5})
calc_y_pdffit = job.calculate_profile()

job.fit()


print("The fit has been successful: {}".format(result.success))
print("The gooodness of fit (chi2) is: {}".format(result.reduced_chi))
print("The fit has been successful: {}".format(job.fitting_results.success))
print("The gooodness of fit (chi2) is: {}".format(job.fitting_results.reduced_chi))

print("The optimized parameters are:")
for param in fit_parameters:
print("{}: {}".format(param.name, param.raw_value))

y_data = calculator.fit_func(x_data)
y_data = job.calculate_profile()

# obtain data from PdfFit calculator object
Gobs = data[:, 1]
x_data = job.experiment.x
Gobs = job.experiment.y
Gfit = y_data
Gdiff = Gobs - Gfit
Gdiff_baseline = -10
Expand Down

0 comments on commit 19f18f6

Please sign in to comment.