From 05fd1b457a9e06bcae3ff800c7f8b0ff97fe82c5 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 26 Aug 2024 03:07:48 -0400 Subject: [PATCH 1/4] provide info in doc and write an example page --- doc/examples/Ni_calculation.py | 25 --- doc/source/examples.rst | 151 ++++++++++++++++++ doc/{ => source}/examples/Ni-xray.gr | 0 doc/{ => source}/examples/Ni.stru | 0 .../examples/Ni_calculation.py} | 19 +-- doc/{ => source}/examples/Ni_refinement.py | 24 +-- doc/source/index.rst | 46 +++++- 7 files changed, 216 insertions(+), 49 deletions(-) delete mode 100755 doc/examples/Ni_calculation.py create mode 100644 doc/source/examples.rst rename doc/{ => source}/examples/Ni-xray.gr (100%) rename doc/{ => source}/examples/Ni.stru (100%) rename doc/{examples/Ni_plot_pdf.py => source/examples/Ni_calculation.py} (65%) rename doc/{ => source}/examples/Ni_refinement.py (83%) diff --git a/doc/examples/Ni_calculation.py b/doc/examples/Ni_calculation.py deleted file mode 100755 index fd789c56..00000000 --- a/doc/examples/Ni_calculation.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python - -"""Calculate PDF of FCC nickel. Save data to Ni_calculation.cgr. -""" - -from diffpy.pdffit2 import PdfFit - -# create new PDF calculator object -P = PdfFit() - -# load structure file in PDFFIT or DISCUS format -P.read_struct("Ni.stru") - -radiation_type = "X" # x-rays -qmax = 30.0 # Q-cutoff used in PDF calculation in 1/A -qdamp = 0.01 # instrument Q-resolution factor, responsible for PDF decay -rmin = 0.01 # minimum r-value -rmax = 30.0 # maximum r-value -npts = 3000 # number of points in the r-grid - -# allocate and configure PDF calculation -P.alloc(radiation_type, qmax, qdamp, rmin, rmax, npts) -P.calc() - -P.save_pdf(1, "Ni_calculation.cgr") diff --git a/doc/source/examples.rst b/doc/source/examples.rst new file mode 100644 index 00000000..00342582 --- /dev/null +++ b/doc/source/examples.rst @@ -0,0 +1,151 @@ +.. _examples: + +Examples +######## + +Welcome! This guide offers several examples to help you effectively utilize this package. + +Files needed: + + 1. :download:`Ni-xray.gr ` - experimental X-ray PDF data + 2. :download:`Ni.stru ` - Ni f.c.c. structure in PDFfit format + +====================================== +Example 1: Calculate PDF of FCC nickel +====================================== + +The first example shows how to calculates the PDF for FCC nickel and saves the resulting data to a file and plot it using matplotlib. + +1. Imports the PdfFit class from the diffpy.pdffit2 module:: + + from diffpy.pdffit2 import PdfFit + +2. Create a PDF calculator object and assigned to the variable ``P``. Make sure the ``Ni.stru`` file is in the same directory as the script and you've cd to the directory, load structure file. Then allocate and configure PDF calculation and run the calculation:: + + # create new PDF calculator object + P = PdfFit() + + # load structure file in PDFFIT or DISCUS format + P.read_struct("Ni.stru") + + radiation_type = "X" # x-rays + qmax = 30.0 # Q-cutoff used in PDF calculation in 1/A + qdamp = 0.01 # instrument Q-resolution factor, responsible for PDF decay + rmin = 0.01 # minimum r-value + rmax = 30.0 # maximum r-value + npts = 3000 # number of points in the r-grid + + # allocate and configure PDF calculation + P.alloc(radiation_type, qmax, qdamp, rmin, rmax, npts) + P.calc() + +3. Save the refined result:: + + P.save_pdf(1, "Ni_calculation.cgr") + +4. We can also plot it using matplotlib:: + + import matplotlib.pyplot as plt + + # obtain list of r-points and corresponding G values + r = P.getR() + G = P.getpdf_fit() + + # matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. + plt.plot(r, G) + pylab.xlabel("r (Å)") + pylab.ylabel("G (Å$^{-2}$)") + pylab.title("x-ray PDF of nickel simulated at Qmax = %g" % qmax) + + # display plot window, this must be the last command in the script + pylab.show() + +The scripts can be downloaded :download:`here `. + +======================================= +Example 2: Performing simple refinement +======================================= + +The second example shows how to perform simple refinement of Ni structure to the experimental x-ray PDF. The example uses the same data files as the first example. + +1. Imports the PdfFit class from the diffpy.pdffit2 module:: + + from diffpy.pdffit2 import PdfFit + +2. Load experimental x-ray PDF data and nickel structure file:: + + # Load experimental x-ray PDF data + qmax = 30.0 # Q-cutoff used in PDF calculation in 1/A + qdamp = 0.01 # instrument Q-resolution factor, responsible for PDF decay + pf.read_data("Ni-xray.gr", "X", qmax, qdamp) + + # Load nickel structure, must be in PDFFIT or DISCUS format + pf.read_struct("Ni.stru") + +3. Configure refinement and refine:: + + # Refine lattice parameters a, b, c. + # Make them all equal to parameter @1. + pf.constrain(pf.lat(1), "@1") + pf.constrain(pf.lat(2), "@1") + pf.constrain(pf.lat(3), "@1") + # set initial value of parameter @1 + pf.setpar(1, pf.lat(1)) + + # Refine phase scale factor. Right side can have formulas. + pf.constrain("pscale", "@20 * 2") + pf.setpar(20, pf.getvar(pf.pscale) / 2.0) + + # Refine PDF damping due to instrument Q-resolution. + # Left side can be also passed as a reference to PdfFit object + pf.constrain(pf.qdamp, "@21") + pf.setpar(21, 0.03) + + # Refine sharpening factor for correlated motion of close atoms. + pf.constrain(pf.delta2, 22) + pf.setpar(22, 0.0003) + + # Set all temperature factors isotropic and equal to @4 + for idx in range(1, 5): + pf.constrain(pf.u11(idx), "@4") + pf.constrain(pf.u22(idx), "@4") + pf.constrain(pf.u33(idx), "@4") + pf.setpar(4, pf.u11(1)) + + # Refine all parameters + pf.pdfrange(1, 1.5, 19.99) + pf.refine() + +4. Save the refined result:: + + pf.save_pdf(1, "Ni_refinement.fgr") + pf.save_struct(1, "Ni_refinement.rstr") + pf.save_res("Ni_refinement.res") + +5. We can also plot it using matplotlib:: + + import matplotlib.pyplot as plt + import numpy + + # matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. + # obtain data from PdfFit calculator object + r = pf.getR() + Gobs = pf.getpdf_obs() + Gfit = pf.getpdf_fit() + + # calculate difference curve + Gdiff = numpy.array(Gobs) - numpy.array(Gfit) + Gdiff_baseline = -10 + + plt.plot(r, Gobs, "ko") + plt.plot(r, Gfit, "b-") + plt.plot(r, Gdiff + Gdiff_baseline, "r-") + + plt.xlabel("r (Å)") + plt.ylabel("G (Å$^{-2}$)") + plt.title("Fit of nickel to x-ray experimental PDF") + + # display plot window, this must be the last command in the script + plt.show() + +The scripts can be downloaded :download:`here `. diff --git a/doc/examples/Ni-xray.gr b/doc/source/examples/Ni-xray.gr similarity index 100% rename from doc/examples/Ni-xray.gr rename to doc/source/examples/Ni-xray.gr diff --git a/doc/examples/Ni.stru b/doc/source/examples/Ni.stru similarity index 100% rename from doc/examples/Ni.stru rename to doc/source/examples/Ni.stru diff --git a/doc/examples/Ni_plot_pdf.py b/doc/source/examples/Ni_calculation.py similarity index 65% rename from doc/examples/Ni_plot_pdf.py rename to doc/source/examples/Ni_calculation.py index 603c65c9..84539b7b 100755 --- a/doc/examples/Ni_plot_pdf.py +++ b/doc/source/examples/Ni_calculation.py @@ -1,10 +1,9 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- -"""Calculate PDF of FCC nickel and plot it using matplotlib. +"""Calculate PDF of FCC nickel. Save data to Ni_calculation.cgr and plot it using matplotlib. """ -import pylab +import matplotlib.pyplot as plt from diffpy.pdffit2 import PdfFit @@ -25,15 +24,17 @@ P.alloc(radiation_type, qmax, qdamp, rmin, rmax, npts) P.calc() +P.save_pdf(1, "Ni_calculation.cgr") + # obtain list of r-points and corresponding G values r = P.getR() G = P.getpdf_fit() -# pylab is matplotlib interface with MATLAB-like plotting commands -pylab.plot(r, G) -pylab.xlabel("r (Å)") -pylab.ylabel("G (Å$^{-2}$)") -pylab.title("x-ray PDF of nickel simulated at Qmax = %g" % qmax) +# matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. +plt.plot(r, G) +plt.xlabel("r (Å)") +plt.ylabel("G (Å$^{-2}$)") +plt.title("x-ray PDF of nickel simulated at Qmax = %g" % qmax) # display plot window, this must be the last command in the script -pylab.show() +plt.show() diff --git a/doc/examples/Ni_refinement.py b/doc/source/examples/Ni_refinement.py similarity index 83% rename from doc/examples/Ni_refinement.py rename to doc/source/examples/Ni_refinement.py index 665e92f4..3551023e 100755 --- a/doc/examples/Ni_refinement.py +++ b/doc/source/examples/Ni_refinement.py @@ -5,7 +5,8 @@ Save fitted curve, refined structure and results summary. """ -import pylab +import matplotlib.pyplot as plt +import numpy from diffpy.pdffit2 import PdfFit @@ -65,24 +66,23 @@ # Plot results --------------------------------------------------------------- -# pylab is matplotlib interface with MATLAB-like plotting commands +# matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. # obtain data from PdfFit calculator object r = pf.getR() Gobs = pf.getpdf_obs() Gfit = pf.getpdf_fit() -# calculate difference curve, with pylab arrays it can be done -# without for loop -Gdiff = pylab.array(Gobs) - pylab.array(Gfit) +# calculate difference curve +Gdiff = numpy.array(Gobs) - numpy.array(Gfit) Gdiff_baseline = -10 -pylab.plot(r, Gobs, "ko") -pylab.plot(r, Gfit, "b-") -pylab.plot(r, Gdiff + Gdiff_baseline, "r-") +plt.plot(r, Gobs, "ko") +plt.plot(r, Gfit, "b-") +plt.plot(r, Gdiff + Gdiff_baseline, "r-") -pylab.xlabel("r (Å)") -pylab.ylabel("G (Å$^{-2}$)") -pylab.title("Fit of nickel to x-ray experimental PDF") +plt.xlabel("r (Å)") +plt.ylabel("G (Å$^{-2}$)") +plt.title("Fit of nickel to x-ray experimental PDF") # display plot window, this must be the last command in the script -pylab.show() +plt.show() diff --git a/doc/source/index.rst b/doc/source/index.rst index bc6f0043..3ff032fe 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,21 +4,60 @@ .. |title| replace:: diffpy.pdffit2 documentation -diffpy.pdffit2 - PDFfit2 - real space structure refinement program.. +diffpy.pdffit2 - PDFfit2 - real space structure refinement program. | Software version |release|. | Last updated |today|. +The diffpy.pdffit2 package provides functions for calculation and +refinement of atomic Pair Distribution Function (PDF) from crystal +structure model. It is used as a computational engine by PDFgui. All +refinements possible in PDFgui can be done with diffpy.pdffit2, +although less conveniently and with a fair knowledge of Python. +The package includes an extension for the interactive `IPython +`_ shell, which tries to mimic the old PDFFIT +program. To start IPython with this extension and also with plotting +functions enabled, use :: + + ipython --ext=diffpy.pdffit2.ipy_ext --pylab + +The IPython extension is suitable for interactive use, however +refinement scripts should be preferably written as a standard +Python code. This is more reliable and needs only a few extra +statements. + ======= Authors ======= -diffpy.pdffit2 is developed by Billinge Group -and its community contributors. +This code was derived from the first PDFFIT program by Thomas Proffen. +The sources were converted to C++ by Jacques Bloch and then extensively hacked, +extended and purged from most glaring bugs by Chris Farrow and Pavol Juhas. +This code is currently maintained as part of the DiffPy project to create +python modules for structure investigations from diffraction data. + +The DiffPy team is located in the Billinge-group at the Applied Physics +and Applied Mathematics Department of the Columbia University in New York. +Previous significant contributors to this code were + + Pavol Juhas, Chris Farrow, Jacques Bloch, Wenduo Zhou For a detailed list of contributors see https://github.com/diffpy/diffpy.pdffit2/graphs/contributors. + +========= +Reference +========= + +If you use this program for a scientific research that leads to publication, +we ask that you acknowledge use of the program by citing the following paper +in your publication: + + C. L. Farrow, P. Juhás, J. W. Liu, D. Bryndin, E. S. Božin, J. Bloch, Th. Proffen + and S. J. L. Billinge, PDFfit2 and PDFgui: computer programs for studying nanostructure + in crystals (https://stacks.iop.org/0953-8984/19/335219), *J. Phys.: Condens. Matter*, 19, 335219 (2007) + ============ Installation ============ @@ -34,6 +73,7 @@ Table of contents license release + examples Package API ======= From 953325bfc50df7ff9b6244089859d4baca01bd8b Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 27 Aug 2024 22:55:17 -0400 Subject: [PATCH 2/4] remove matplotlib comment --- doc/source/examples.rst | 2 -- doc/source/examples/Ni_calculation.py | 13 ++++++++++++- doc/source/examples/Ni_refinement.py | 1 - 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 00342582..5424382d 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -51,7 +51,6 @@ The first example shows how to calculates the PDF for FCC nickel and saves the r r = P.getR() G = P.getpdf_fit() - # matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. plt.plot(r, G) pylab.xlabel("r (Å)") pylab.ylabel("G (Å$^{-2}$)") @@ -127,7 +126,6 @@ The second example shows how to perform simple refinement of Ni structure to the import matplotlib.pyplot as plt import numpy - # matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. # obtain data from PdfFit calculator object r = pf.getR() Gobs = pf.getpdf_obs() diff --git a/doc/source/examples/Ni_calculation.py b/doc/source/examples/Ni_calculation.py index 84539b7b..dfd26adc 100755 --- a/doc/source/examples/Ni_calculation.py +++ b/doc/source/examples/Ni_calculation.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- """Calculate PDF of FCC nickel. Save data to Ni_calculation.cgr and plot it using matplotlib. """ @@ -10,9 +11,13 @@ # create new PDF calculator object P = PdfFit() +# Load data ------------------------------------------------------------------ + # load structure file in PDFFIT or DISCUS format P.read_struct("Ni.stru") +# Configure calculation ------------------------------------------------------ + radiation_type = "X" # x-rays qmax = 30.0 # Q-cutoff used in PDF calculation in 1/A qdamp = 0.01 # instrument Q-resolution factor, responsible for PDF decay @@ -22,15 +27,21 @@ # allocate and configure PDF calculation P.alloc(radiation_type, qmax, qdamp, rmin, rmax, npts) + +# Calculate ------------------------------------------------------------------- + P.calc() +# Save results --------------------------------------------------------------- + P.save_pdf(1, "Ni_calculation.cgr") +# Plot results --------------------------------------------------------------- + # obtain list of r-points and corresponding G values r = P.getR() G = P.getpdf_fit() -# matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. plt.plot(r, G) plt.xlabel("r (Å)") plt.ylabel("G (Å$^{-2}$)") diff --git a/doc/source/examples/Ni_refinement.py b/doc/source/examples/Ni_refinement.py index 3551023e..8c81cf1b 100755 --- a/doc/source/examples/Ni_refinement.py +++ b/doc/source/examples/Ni_refinement.py @@ -66,7 +66,6 @@ # Plot results --------------------------------------------------------------- -# matplotlib.pyplot is an matplotlib interface with an MATLAB-like way of plotting. # obtain data from PdfFit calculator object r = pf.getR() Gobs = pf.getpdf_obs() From 13ba9d398ebc62ce1e45877495584759738f2c6e Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 29 Aug 2024 10:29:49 -0400 Subject: [PATCH 3/4] update examples.rst pyplot --- doc/source/examples.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 5424382d..0a963ee2 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -52,12 +52,12 @@ The first example shows how to calculates the PDF for FCC nickel and saves the r G = P.getpdf_fit() plt.plot(r, G) - pylab.xlabel("r (Å)") - pylab.ylabel("G (Å$^{-2}$)") - pylab.title("x-ray PDF of nickel simulated at Qmax = %g" % qmax) + plt.xlabel("r (Å)") + plt.ylabel("G (Å$^{-2}$)") + plt.title("x-ray PDF of nickel simulated at Qmax = %g" % qmax) # display plot window, this must be the last command in the script - pylab.show() + plt.show() The scripts can be downloaded :download:`here `. From 3bb7a1ea4b5e5067ce3bb1b23ab4ad8cbf9a12e9 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 30 Aug 2024 08:47:45 -0400 Subject: [PATCH 4/4] correct rst code --- doc/source/examples.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 0a963ee2..f793e585 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -71,7 +71,10 @@ The second example shows how to perform simple refinement of Ni structure to the from diffpy.pdffit2 import PdfFit -2. Load experimental x-ray PDF data and nickel structure file:: +2. Create a PDF calculator object and assigned to the variable ``pf``. Load experimental x-ray PDF data and nickel structure file:: + + # Create new PDF calculator object. + pf = PdfFit() # Load experimental x-ray PDF data qmax = 30.0 # Q-cutoff used in PDF calculation in 1/A