{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "0", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:47.278602Z", "iopub.status.busy": "2026-06-30T22:41:47.278398Z", "iopub.status.idle": "2026-06-30T22:41:47.284346Z", "shell.execute_reply": "2026-06-30T22:41:47.283860Z" }, "tags": [ "hide-in-docs" ] }, "outputs": [], "source": [ "# Check whether easydiffraction is installed; install it if needed.\n", "# Required for remote environments such as Google Colab.\n", "import importlib.util\n", "\n", "if importlib.util.find_spec('easydiffraction') is None:\n", " %pip install easydiffraction==0.19.1" ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "# Structure Refinement: PbSO4, NPD + XRD\n", "\n", "This example demonstrates a more advanced use of the EasyDiffraction\n", "library by explicitly creating and configuring structures and\n", "experiments before adding them to a project. It could be more suitable\n", "for users who are interested in creating custom workflows. This\n", "tutorial provides minimal explanation and is intended for users\n", "already familiar with EasyDiffraction.\n", "\n", "The tutorial covers a Rietveld refinement of PbSO4 crystal structure\n", "based on the joint fit of both X-ray and neutron diffraction data." ] }, { "cell_type": "markdown", "id": "2", "metadata": {}, "source": [ "## πŸ› οΈ Import Library" ] }, { "cell_type": "code", "execution_count": 2, "id": "3", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:47.286571Z", "iopub.status.busy": "2026-06-30T22:41:47.286393Z", "iopub.status.idle": "2026-06-30T22:41:50.460374Z", "shell.execute_reply": "2026-06-30T22:41:50.459521Z" } }, "outputs": [], "source": [ "from easydiffraction import ExperimentFactory\n", "from easydiffraction import Project\n", "from easydiffraction import StructureFactory\n", "from easydiffraction import download_data" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "## 🧩 Define Structure\n", "\n", "This section shows how to add structures and modify their\n", "parameters.\n", "\n", "### Create Structure" ] }, { "cell_type": "code", "execution_count": 3, "id": "5", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.464743Z", "iopub.status.busy": "2026-06-30T22:41:50.464383Z", "iopub.status.idle": "2026-06-30T22:41:50.474988Z", "shell.execute_reply": "2026-06-30T22:41:50.473844Z" } }, "outputs": [], "source": [ "struct = StructureFactory.from_scratch(name='pbso4')" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "### Set Space Group" ] }, { "cell_type": "code", "execution_count": 4, "id": "7", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.476887Z", "iopub.status.busy": "2026-06-30T22:41:50.476695Z", "iopub.status.idle": "2026-06-30T22:41:50.487873Z", "shell.execute_reply": "2026-06-30T22:41:50.485117Z" } }, "outputs": [], "source": [ "struct.space_group.name_h_m = 'P n m a'" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "### Set Unit Cell" ] }, { "cell_type": "code", "execution_count": 5, "id": "9", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.489645Z", "iopub.status.busy": "2026-06-30T22:41:50.489438Z", "iopub.status.idle": "2026-06-30T22:41:50.493967Z", "shell.execute_reply": "2026-06-30T22:41:50.492965Z" } }, "outputs": [], "source": [ "struct.cell.length_a = 8.47\n", "struct.cell.length_b = 5.39\n", "struct.cell.length_c = 6.95" ] }, { "cell_type": "markdown", "id": "10", "metadata": {}, "source": [ "### Set Atom Sites" ] }, { "cell_type": "code", "execution_count": 6, "id": "11", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.496837Z", "iopub.status.busy": "2026-06-30T22:41:50.496513Z", "iopub.status.idle": "2026-06-30T22:41:50.517775Z", "shell.execute_reply": "2026-06-30T22:41:50.516576Z" } }, "outputs": [], "source": [ "struct.atom_sites.create(\n", " id='Pb',\n", " type_symbol='Pb',\n", " fract_x=0.1876,\n", " fract_y=0.25,\n", " fract_z=0.167,\n", " adp_type='Biso',\n", " adp_iso=1.37,\n", ")\n", "struct.atom_sites.create(\n", " id='S',\n", " type_symbol='S',\n", " fract_x=0.0654,\n", " fract_y=0.25,\n", " fract_z=0.684,\n", " adp_type='Biso',\n", " adp_iso=0.3796,\n", ")\n", "struct.atom_sites.create(\n", " id='O1',\n", " type_symbol='O',\n", " fract_x=0.9082,\n", " fract_y=0.25,\n", " fract_z=0.5954,\n", " adp_type='Biso',\n", " adp_iso=1.9840,\n", ")\n", "struct.atom_sites.create(\n", " id='O2',\n", " type_symbol='O',\n", " fract_x=0.1935,\n", " fract_y=0.25,\n", " fract_z=0.5432,\n", " adp_type='Biso',\n", " adp_iso=1.4383,\n", ")\n", "struct.atom_sites.create(\n", " id='O3',\n", " type_symbol='O',\n", " fract_x=0.0811,\n", " fract_y=0.0272,\n", " fract_z=0.8086,\n", " adp_type='Biso',\n", " adp_iso=1.2808,\n", ")" ] }, { "cell_type": "markdown", "id": "12", "metadata": {}, "source": [ "## πŸ”¬ Define Experiments\n", "\n", "This section shows how to add experiments, configure their parameters,\n", "and link the structures defined in the previous step.\n", "\n", "### Experiment 1: npd\n", "\n", "#### Download Data" ] }, { "cell_type": "code", "execution_count": 7, "id": "13", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.519482Z", "iopub.status.busy": "2026-06-30T22:41:50.519278Z", "iopub.status.idle": "2026-06-30T22:41:50.804005Z", "shell.execute_reply": "2026-06-30T22:41:50.803200Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mGetting data\u001b[0m\u001b[1;36m...\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Data \u001b[32m'meas-pbso4-d1a'\u001b[0m: PbSO4, D1A \u001b[1m(\u001b[0mILL\u001b[1m)\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "βœ… Data \u001b[32m'meas-pbso4-d1a'\u001b[0m downloaded to \u001b[32m'../../../data/meas-pbso4-d1a.xys'\u001b[0m\n" ] } ], "source": [ "data_path1 = download_data('meas-pbso4-d1a', destination='data')" ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "#### Create Experiment" ] }, { "cell_type": "code", "execution_count": 8, "id": "15", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:50.807660Z", "iopub.status.busy": "2026-06-30T22:41:50.807459Z", "iopub.status.idle": "2026-06-30T22:41:51.386017Z", "shell.execute_reply": "2026-06-30T22:41:51.385129Z" } }, "outputs": [], "source": [ "expt1 = ExperimentFactory.from_data_path(\n", " name='npd',\n", " data_path=data_path1,\n", " radiation_probe='neutron',\n", ")" ] }, { "cell_type": "markdown", "id": "16", "metadata": {}, "source": [ "#### Set Instrument" ] }, { "cell_type": "code", "execution_count": 9, "id": "17", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.388021Z", "iopub.status.busy": "2026-06-30T22:41:51.387809Z", "iopub.status.idle": "2026-06-30T22:41:51.393079Z", "shell.execute_reply": "2026-06-30T22:41:51.392251Z" } }, "outputs": [], "source": [ "expt1.instrument.setup_wavelength = 1.91\n", "expt1.instrument.calib_twotheta_offset = -0.1018" ] }, { "cell_type": "markdown", "id": "18", "metadata": {}, "source": [ "#### Set Peak Profile" ] }, { "cell_type": "code", "execution_count": 10, "id": "19", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.396453Z", "iopub.status.busy": "2026-06-30T22:41:51.396243Z", "iopub.status.idle": "2026-06-30T22:41:51.412471Z", "shell.execute_reply": "2026-06-30T22:41:51.410074Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "⚠️ Switching peak profile type adds these settings with defaults: \n", " β€’ asym_beba_a0=0.0 \n", " β€’ asym_beba_a1=0.0 \n", " β€’ asym_beba_b0=0.0 \n", " β€’ asym_beba_b1=0.0 \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mPeak profile type for experiment \u001b[0m\u001b[32m'npd'\u001b[0m\u001b[1;36m changed to\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "pseudo-voigt + berar-baldinozzi asymmetry\n" ] } ], "source": [ "expt1.peak.type = 'pseudo-voigt + berar-baldinozzi asymmetry'" ] }, { "cell_type": "code", "execution_count": 11, "id": "20", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.416216Z", "iopub.status.busy": "2026-06-30T22:41:51.414315Z", "iopub.status.idle": "2026-06-30T22:41:51.424174Z", "shell.execute_reply": "2026-06-30T22:41:51.423482Z" } }, "outputs": [], "source": [ "expt1.peak.broad_gauss_u = 0.1678\n", "expt1.peak.broad_gauss_v = -0.4636\n", "expt1.peak.broad_gauss_w = 0.4168\n", "expt1.peak.broad_lorentz_x = 0\n", "expt1.peak.broad_lorentz_y = 0.0879\n", "\n", "expt1.peak.asym_beba_a0 = -0.4327\n", "expt1.peak.asym_beba_b0 = -0.0182\n", "expt1.peak.asym_beba_a1 = 0.1976\n", "expt1.peak.asym_beba_b1 = -0.0575\n", "\n", "expt1.peak.cutoff_fwhm = 6" ] }, { "cell_type": "markdown", "id": "21", "metadata": {}, "source": [ "#### Set Background" ] }, { "cell_type": "markdown", "id": "22", "metadata": {}, "source": [ "Select the background type." ] }, { "cell_type": "code", "execution_count": 12, "id": "23", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.426291Z", "iopub.status.busy": "2026-06-30T22:41:51.426004Z", "iopub.status.idle": "2026-06-30T22:41:51.432882Z", "shell.execute_reply": "2026-06-30T22:41:51.432483Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mBackground type for experiment \u001b[0m\u001b[32m'npd'\u001b[0m\u001b[1;36m already set to\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "line-segment\n" ] } ], "source": [ "expt1.background.type = 'line-segment'" ] }, { "cell_type": "markdown", "id": "24", "metadata": {}, "source": [ "Add background points." ] }, { "cell_type": "code", "execution_count": 13, "id": "25", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.435146Z", "iopub.status.busy": "2026-06-30T22:41:51.434891Z", "iopub.status.idle": "2026-06-30T22:41:51.439680Z", "shell.execute_reply": "2026-06-30T22:41:51.439038Z" } }, "outputs": [], "source": [ "for id, x, y in [\n", " ('1', 11.0, 206.4940),\n", " ('2', 15.0, 194.7316),\n", " ('3', 20.0, 194.5190),\n", " ('4', 30.0, 188.3431),\n", " ('5', 50.0, 207.7130),\n", " ('6', 70.0, 201.6635),\n", " ('7', 120.0, 244.1902),\n", " ('8', 153.0, 226.3376),\n", "]:\n", " expt1.background.create(id=id, position=x, intensity=y)" ] }, { "cell_type": "markdown", "id": "26", "metadata": {}, "source": [ "#### Set Linked Structures" ] }, { "cell_type": "code", "execution_count": 14, "id": "27", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.441548Z", "iopub.status.busy": "2026-06-30T22:41:51.441404Z", "iopub.status.idle": "2026-06-30T22:41:51.444155Z", "shell.execute_reply": "2026-06-30T22:41:51.443557Z" } }, "outputs": [], "source": [ "expt1.linked_structures.create(structure_id='pbso4', scale=1.5)" ] }, { "cell_type": "markdown", "id": "28", "metadata": {}, "source": [ "### Experiment 2: xrd\n", "\n", "#### Download Data" ] }, { "cell_type": "code", "execution_count": 15, "id": "29", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.445360Z", "iopub.status.busy": "2026-06-30T22:41:51.445210Z", "iopub.status.idle": "2026-06-30T22:41:51.451289Z", "shell.execute_reply": "2026-06-30T22:41:51.450591Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mGetting data\u001b[0m\u001b[1;36m...\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Data \u001b[32m'meas-pbso4-xray'\u001b[0m: PbSO4, laboratory X-ray\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "βœ… Data \u001b[32m'meas-pbso4-xray'\u001b[0m already present at \u001b[32m'../../../data/meas-pbso4-xray.xys'\u001b[0m. Keeping existing.\n" ] } ], "source": [ "data_path2 = download_data('meas-pbso4-xray', destination='data')" ] }, { "cell_type": "markdown", "id": "30", "metadata": {}, "source": [ "#### Create Experiment" ] }, { "cell_type": "code", "execution_count": 16, "id": "31", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:51.452518Z", "iopub.status.busy": "2026-06-30T22:41:51.452377Z", "iopub.status.idle": "2026-06-30T22:41:52.239300Z", "shell.execute_reply": "2026-06-30T22:41:52.238409Z" } }, "outputs": [], "source": [ "expt2 = ExperimentFactory.from_data_path(\n", " name='xrd',\n", " data_path=data_path2,\n", " radiation_probe='xray',\n", ")" ] }, { "cell_type": "markdown", "id": "32", "metadata": {}, "source": [ "#### Set Instrument" ] }, { "cell_type": "code", "execution_count": 17, "id": "33", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.241276Z", "iopub.status.busy": "2026-06-30T22:41:52.241072Z", "iopub.status.idle": "2026-06-30T22:41:52.244606Z", "shell.execute_reply": "2026-06-30T22:41:52.243928Z" } }, "outputs": [], "source": [ "expt2.instrument.setup_wavelength = 1.540560\n", "expt2.instrument.setup_wavelength_2 = 1.544400\n", "expt2.instrument.setup_wavelength_2_to_1_ratio = 0.5\n", "\n", "expt2.instrument.setup_polarization_coefficient = 0.58\n", "expt2.instrument.setup_monochromator_twotheta = 28\n", "\n", "expt2.instrument.calib_twotheta_offset = -0.0292" ] }, { "cell_type": "markdown", "id": "34", "metadata": {}, "source": [ "#### Set Peak Profile" ] }, { "cell_type": "code", "execution_count": 18, "id": "35", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.246367Z", "iopub.status.busy": "2026-06-30T22:41:52.246214Z", "iopub.status.idle": "2026-06-30T22:41:52.252799Z", "shell.execute_reply": "2026-06-30T22:41:52.252088Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "⚠️ Switching peak profile type adds these settings with defaults: \n", " β€’ asym_beba_a0=0.0 \n", " β€’ asym_beba_a1=0.0 \n", " β€’ asym_beba_b0=0.0 \n", " β€’ asym_beba_b1=0.0 \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mPeak profile type for experiment \u001b[0m\u001b[32m'xrd'\u001b[0m\u001b[1;36m changed to\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "pseudo-voigt + berar-baldinozzi asymmetry\n" ] } ], "source": [ "expt2.peak.type = 'pseudo-voigt + berar-baldinozzi asymmetry'" ] }, { "cell_type": "code", "execution_count": 19, "id": "36", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.254523Z", "iopub.status.busy": "2026-06-30T22:41:52.254371Z", "iopub.status.idle": "2026-06-30T22:41:52.257906Z", "shell.execute_reply": "2026-06-30T22:41:52.257086Z" } }, "outputs": [], "source": [ "expt2.peak.broad_gauss_u = 0.0197\n", "expt2.peak.broad_gauss_v = -0.0185\n", "expt2.peak.broad_gauss_w = 0.0079\n", "expt2.peak.broad_lorentz_y = 0.0645\n", "\n", "expt2.peak.asym_beba_a0 = -0.2188\n", "expt2.peak.asym_beba_b0 = -0.0301\n", "\n", "expt2.peak.cutoff_fwhm = 6" ] }, { "cell_type": "markdown", "id": "37", "metadata": {}, "source": [ "#### Set Excluded Regions" ] }, { "cell_type": "code", "execution_count": 20, "id": "38", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.259328Z", "iopub.status.busy": "2026-06-30T22:41:52.259176Z", "iopub.status.idle": "2026-06-30T22:41:52.262404Z", "shell.execute_reply": "2026-06-30T22:41:52.261768Z" } }, "outputs": [], "source": [ "expt2.excluded_regions.create(id='1', start=0, end=15)\n", "expt2.excluded_regions.create(id='2', start=160, end=180)" ] }, { "cell_type": "markdown", "id": "39", "metadata": {}, "source": [ "#### Set Background" ] }, { "cell_type": "markdown", "id": "40", "metadata": {}, "source": [ "Select background type." ] }, { "cell_type": "code", "execution_count": 21, "id": "41", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.263991Z", "iopub.status.busy": "2026-06-30T22:41:52.263835Z", "iopub.status.idle": "2026-06-30T22:41:52.268430Z", "shell.execute_reply": "2026-06-30T22:41:52.267684Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mBackground type for experiment \u001b[0m\u001b[32m'xrd'\u001b[0m\u001b[1;36m changed to\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "chebyshev\n" ] } ], "source": [ "expt2.background.type = 'chebyshev'" ] }, { "cell_type": "markdown", "id": "42", "metadata": {}, "source": [ "Add Chebyshev background terms." ] }, { "cell_type": "code", "execution_count": 22, "id": "43", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.269871Z", "iopub.status.busy": "2026-06-30T22:41:52.269710Z", "iopub.status.idle": "2026-06-30T22:41:52.273959Z", "shell.execute_reply": "2026-06-30T22:41:52.273301Z" } }, "outputs": [], "source": [ "for id, x, y in [\n", " ('1', 0, 153.17),\n", " ('2', 1, 62.93),\n", " ('3', 2, 9.86),\n", " ('4', 3, 10.81),\n", " ('5', 4, -6.61),\n", " ('6', 5, -7.12),\n", "]:\n", " expt2.background.create(id=id, order=x, coef=y)" ] }, { "cell_type": "markdown", "id": "44", "metadata": {}, "source": [ "#### Set Linked Structures" ] }, { "cell_type": "code", "execution_count": 23, "id": "45", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.275580Z", "iopub.status.busy": "2026-06-30T22:41:52.275425Z", "iopub.status.idle": "2026-06-30T22:41:52.278260Z", "shell.execute_reply": "2026-06-30T22:41:52.277569Z" } }, "outputs": [], "source": [ "expt2.linked_structures.create(structure_id='pbso4', scale=0.001)" ] }, { "cell_type": "markdown", "id": "46", "metadata": {}, "source": [ "## πŸ“¦ Define Project\n", "\n", "The project object is used to manage structures, experiments, and\n", "analysis.\n", "\n", "### Create Project" ] }, { "cell_type": "code", "execution_count": 24, "id": "47", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.279529Z", "iopub.status.busy": "2026-06-30T22:41:52.279371Z", "iopub.status.idle": "2026-06-30T22:41:52.518228Z", "shell.execute_reply": "2026-06-30T22:41:52.517458Z" } }, "outputs": [], "source": [ "project = Project(name='pbso4_joint')" ] }, { "cell_type": "markdown", "id": "48", "metadata": {}, "source": [ "### Add Structure" ] }, { "cell_type": "code", "execution_count": 25, "id": "49", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.520416Z", "iopub.status.busy": "2026-06-30T22:41:52.520242Z", "iopub.status.idle": "2026-06-30T22:41:52.523347Z", "shell.execute_reply": "2026-06-30T22:41:52.522697Z" } }, "outputs": [], "source": [ "project.structures.add(struct)" ] }, { "cell_type": "markdown", "id": "50", "metadata": {}, "source": [ "### Add Experiments" ] }, { "cell_type": "code", "execution_count": 26, "id": "51", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.525127Z", "iopub.status.busy": "2026-06-30T22:41:52.524960Z", "iopub.status.idle": "2026-06-30T22:41:52.527566Z", "shell.execute_reply": "2026-06-30T22:41:52.526896Z" } }, "outputs": [], "source": [ "project.experiments.add(expt1)\n", "project.experiments.add(expt2)" ] }, { "cell_type": "markdown", "id": "52", "metadata": {}, "source": [ "## πŸš€ Perform Analysis\n", "\n", "This section outlines the analysis process, including how to configure\n", "calculation and fitting engines.\n", "\n", "### Set Fit Mode" ] }, { "cell_type": "code", "execution_count": 27, "id": "53", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.528988Z", "iopub.status.busy": "2026-06-30T22:41:52.528822Z", "iopub.status.idle": "2026-06-30T22:41:52.533663Z", "shell.execute_reply": "2026-06-30T22:41:52.532793Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mFitting mode changed to\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "joint\n" ] } ], "source": [ "project.analysis.fitting_mode.type = 'joint'" ] }, { "cell_type": "markdown", "id": "54", "metadata": {}, "source": [ "### Set Free Parameters\n", "\n", "Set structure parameters to be optimized." ] }, { "cell_type": "code", "execution_count": 28, "id": "55", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.535038Z", "iopub.status.busy": "2026-06-30T22:41:52.534889Z", "iopub.status.idle": "2026-06-30T22:41:52.538186Z", "shell.execute_reply": "2026-06-30T22:41:52.537488Z" } }, "outputs": [], "source": [ "struct.cell.length_a.free = True\n", "struct.cell.length_b.free = True\n", "struct.cell.length_c.free = True\n", "\n", "for atom_id in ('Pb', 'S', 'O1', 'O2', 'O3'):\n", " atom = struct.atom_sites[atom_id]\n", " atom.adp_iso.free = True" ] }, { "cell_type": "markdown", "id": "56", "metadata": {}, "source": [ "Set experiment parameters to be optimized." ] }, { "cell_type": "code", "execution_count": 29, "id": "57", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.539622Z", "iopub.status.busy": "2026-06-30T22:41:52.539476Z", "iopub.status.idle": "2026-06-30T22:41:52.542309Z", "shell.execute_reply": "2026-06-30T22:41:52.541592Z" } }, "outputs": [], "source": [ "expt1.linked_structures['pbso4'].scale.free = True\n", "expt1.instrument.calib_twotheta_offset.free = True\n", "expt1.instrument.setup_wavelength.free = True" ] }, { "cell_type": "code", "execution_count": 30, "id": "58", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.543609Z", "iopub.status.busy": "2026-06-30T22:41:52.543476Z", "iopub.status.idle": "2026-06-30T22:41:52.546231Z", "shell.execute_reply": "2026-06-30T22:41:52.545460Z" } }, "outputs": [], "source": [ "expt2.linked_structures['pbso4'].scale.free = True\n", "expt2.instrument.calib_twotheta_offset.free = True" ] }, { "cell_type": "markdown", "id": "59", "metadata": {}, "source": [ "### Run Fitting" ] }, { "cell_type": "code", "execution_count": 31, "id": "60", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:41:52.547549Z", "iopub.status.busy": "2026-06-30T22:41:52.547408Z", "iopub.status.idle": "2026-06-30T22:42:42.856204Z", "shell.execute_reply": "2026-06-30T22:42:42.855498Z" } }, "outputs": [ { "data": { "text/html": [], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function() {\n", " const button = document.getElementById('ed-fit-stop-7366e713dab345cfa8434f6636a14c89-button');\n", " const status = document.getElementById('ed-fit-stop-7366e713dab345cfa8434f6636a14c89-status');\n", " const kernelId = '';\n", " if (!button) {\n", " return;\n", " }\n", "\n", " function setStatus(text) {\n", " if (status) {\n", " status.textContent = text;\n", " }\n", " }\n", "\n", " function pageConfig() {\n", " const element = document.getElementById('jupyter-config-data');\n", " if (!element || !element.textContent) {\n", " return {};\n", " }\n", " try {\n", " return JSON.parse(element.textContent);\n", " } catch (error) {\n", " return {};\n", " }\n", " }\n", "\n", " function baseUrl(config) {\n", " const configured = config.baseUrl || config.base_url ||\n", " (window.Jupyter && Jupyter.notebook && Jupyter.notebook.base_url);\n", " if (configured) {\n", " return configured.endsWith('/') ? configured : configured + '/';\n", " }\n", " const markers = ['/lab/', '/notebooks/', '/tree/'];\n", " for (const marker of markers) {\n", " const index = window.location.pathname.indexOf(marker);\n", " if (index >= 0) {\n", " return window.location.pathname.slice(0, index + 1);\n", " }\n", " }\n", " return '/';\n", " }\n", "\n", " function token(config) {\n", " return config.token || new URLSearchParams(window.location.search).get('token') || '';\n", " }\n", "\n", " function cookie(name) {\n", " const prefix = name + '=';\n", " for (const part of document.cookie.split(';')) {\n", " const trimmed = part.trim();\n", " if (trimmed.startsWith(prefix)) {\n", " return decodeURIComponent(trimmed.slice(prefix.length));\n", " }\n", " }\n", " return '';\n", " }\n", "\n", " function notebookPath() {\n", " const decoded = decodeURIComponent(window.location.pathname);\n", " const markers = ['/lab/tree/', '/notebooks/', '/tree/'];\n", " for (const marker of markers) {\n", " const index = decoded.indexOf(marker);\n", " if (index >= 0) {\n", " return decoded.slice(index + marker.length);\n", " }\n", " }\n", " return '';\n", " }\n", "\n", " async function kernelFromSessions(config) {\n", " const url = new URL(baseUrl(config) + 'api/sessions', window.location.origin);\n", " const authToken = token(config);\n", " if (authToken) {\n", " url.searchParams.set('token', authToken);\n", " }\n", " const response = await fetch(url, {credentials: 'same-origin'});\n", " if (!response.ok) {\n", " return '';\n", " }\n", " const sessions = await response.json();\n", " const path = notebookPath();\n", " const session = sessions.find((item) => item.path === path) || sessions[0];\n", " return session && session.kernel ? session.kernel.id : '';\n", " }\n", "\n", " async function interruptKernel(config, resolvedKernelId) {\n", " const url = new URL(\n", " baseUrl(config) + 'api/kernels/' + resolvedKernelId + '/interrupt',\n", " window.location.origin\n", " );\n", " const authToken = token(config);\n", " if (authToken) {\n", " url.searchParams.set('token', authToken);\n", " }\n", " const xsrfToken = cookie('_xsrf');\n", " const headers = {};\n", " if (xsrfToken) {\n", " headers['X-XSRFToken'] = xsrfToken;\n", " }\n", " const response = await fetch(url, {\n", " method: 'POST',\n", " credentials: 'same-origin',\n", " headers: headers\n", " });\n", " return response.ok;\n", " }\n", "\n", " button.addEventListener('click', async function() {\n", " button.disabled = true;\n", " setStatus('Stopping...');\n", " const config = pageConfig();\n", " try {\n", " const resolvedKernelId = kernelId || await kernelFromSessions(config);\n", " if (!resolvedKernelId) {\n", " throw new Error('Could not resolve the current kernel id.');\n", " }\n", " const interrupted = await interruptKernel(config, resolvedKernelId);\n", " if (!interrupted) {\n", " throw new Error('Jupyter Server rejected the interrupt request.');\n", " }\n", " setStatus('Interrupt sent...');\n", " } catch (error) {\n", " button.disabled = false;\n", " setStatus('Use Kernel > Interrupt to stop this fit.');\n", " }\n", " });\n", "})();\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mUsing all experiments πŸ”¬ \u001b[0m\u001b[1;36m[\u001b[0m\u001b[32m'npd'\u001b[0m\u001b[1;36m, \u001b[0m\u001b[32m'xrd'\u001b[0m\u001b[1;36m]\u001b[0m\u001b[1;36m for \u001b[0m\u001b[32m'joint'\u001b[0m\u001b[1;36m fitting\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "πŸš€ Starting fit process with \u001b[32m'lmfit \u001b[0m\u001b[32m(\u001b[0m\u001b[32mleastsq\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m\u001b[33m...\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "πŸ“ˆ Goodness-of-fit progress:\n" ] }, { "data": { "text/html": [ "
iterationtime (s)χ²change / status
110.7661.19
2166.0461.19
3176.2626.6256.5% ↓
43110.4817.6133.9% ↓
54514.6710.4240.8% ↓
65919.264.5256.6% ↓
77323.543.5621.2% ↓
88727.833.521.1% ↓
910332.843.51
1011937.853.51
1113542.863.51
1215248.073.51
1315849.863.51
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "πŸ† Best goodness-of-fit \u001b[1m(\u001b[0mreduced χ²\u001b[1m)\u001b[0m is \u001b[1;36m3.51\u001b[0m at iteration \u001b[1;36m143\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "βœ… Fitting complete.\n" ] } ], "source": [ "project.analysis.fit()" ] }, { "cell_type": "code", "execution_count": 32, "id": "61", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:42.857729Z", "iopub.status.busy": "2026-06-30T22:42:42.857582Z", "iopub.status.idle": "2026-06-30T22:42:43.521300Z", "shell.execute_reply": "2026-06-30T22:42:43.520565Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "βš™οΈ Settings used:\n" ] }, { "data": { "text/html": [ "
NameValueDescription
1max_iterations1000Maximum solver iterations.
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "πŸ“‹ Least-squares fit results:\n" ] }, { "data": { "text/html": [ "
MetricValue
1πŸ§ͺ Minimizerlmfit (leastsq)
2βœ… Overall statussuccess
3⏱️ Fitting time (seconds)49.86
4πŸ” Iterations155
5πŸ“ Goodness-of-fit (reduced χ²)3.51
6πŸ“ R-factor (Rf, %)5.67
7πŸ“ R-factor squared (RfΒ², %)6.17
8πŸ“ Weighted R-factor (wR, %)5.40
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "πŸ“ˆ Refined parameters:\n" ] }, { "data": { "text/html": [ "
datablockcategoryentryparameterunitsstartvalues.u.change
1pbso4celllength_aΓ…8.47008.48120.00010.13 % ↑
2pbso4celllength_bΓ…5.39005.39880.00000.16 % ↑
3pbso4celllength_cΓ…6.95006.96050.00010.15 % ↑
4pbso4atom_sitePbadp_isoΓ…Β²1.37001.37470.00870.34 % ↑
5pbso4atom_siteSadp_isoΓ…Β²0.37960.44400.032716.97 % ↑
6pbso4atom_siteO1adp_isoΓ…Β²1.98401.95070.02821.68 % ↓
7pbso4atom_siteO2adp_isoΓ…Β²1.43831.41370.02641.71 % ↓
8pbso4atom_siteO3adp_isoΓ…Β²1.28081.24600.01682.72 % ↓
9npdlinked_structurepbso4scale1.50001.46730.00332.18 % ↓
10npdinstrumentwavelengthΓ…1.91001.91290.00000.15 % ↑
11npdinstrumenttwotheta_offsetdeg-0.1018-0.10120.00080.63 % ↓
12xrdlinked_structurepbso4scale0.00100.00100.00000.02 % ↑
13xrdinstrumenttwotheta_offsetdeg-0.0292-0.02900.00030.65 % ↓
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
β€’ start = parameter value before refinement
β€’ value = refined value from least-squares minimization
β€’ s.u. = standard uncertainty (one sigma), from the covariance matrix
β€’ change = relative change from start, in %; ↑ = increase, ↓ = decrease
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "project.display.fit.results()" ] }, { "cell_type": "markdown", "id": "62", "metadata": {}, "source": [ "#### Display Correlations" ] }, { "cell_type": "code", "execution_count": 33, "id": "63", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:43.522880Z", "iopub.status.busy": "2026-06-30T22:42:43.522697Z", "iopub.status.idle": "2026-06-30T22:42:43.563890Z", "shell.execute_reply": "2026-06-30T22:42:43.563058Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
Loading plot…
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "project.display.fit.correlations()" ] }, { "cell_type": "markdown", "id": "64", "metadata": {}, "source": [ "### Display Pattern" ] }, { "cell_type": "code", "execution_count": 34, "id": "65", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:43.565542Z", "iopub.status.busy": "2026-06-30T22:42:43.565383Z", "iopub.status.idle": "2026-06-30T22:42:43.633406Z", "shell.execute_reply": "2026-06-30T22:42:43.632561Z" } }, "outputs": [ { "data": { "text/html": [ "
Loading plot…
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "project.display.pattern(expt_name='npd')" ] }, { "cell_type": "code", "execution_count": 35, "id": "66", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:43.637851Z", "iopub.status.busy": "2026-06-30T22:42:43.637529Z", "iopub.status.idle": "2026-06-30T22:42:43.710797Z", "shell.execute_reply": "2026-06-30T22:42:43.709982Z" } }, "outputs": [ { "data": { "text/html": [ "
Loading plot…
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "project.display.pattern(expt_name='xrd')" ] }, { "cell_type": "markdown", "id": "67", "metadata": {}, "source": [ "### Display Structure" ] }, { "cell_type": "code", "execution_count": 36, "id": "68", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:43.718117Z", "iopub.status.busy": "2026-06-30T22:42:43.717915Z", "iopub.status.idle": "2026-06-30T22:42:43.747710Z", "shell.execute_reply": "2026-06-30T22:42:43.746947Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mStructure 🧩 \u001b[0m\u001b[32m'pbso4'\u001b[0m\u001b[1;36m \u001b[0m\u001b[1;36m(\u001b[0m\u001b[1;36mAtom view type: \u001b[0m\u001b[32m'covalent'\u001b[0m\u001b[1;36m)\u001b[0m\n" ] }, { "data": { "text/html": [ "
\n", "
\n", "
Loading plot…
\n", "
\n", "
\n", "
\n", "
drag = rotate
wheel = zoom
right-drag = pan
\n", "
\n", "
\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "project.display.structure(struct_name='pbso4')" ] }, { "cell_type": "markdown", "id": "69", "metadata": {}, "source": [ "## πŸ’Ύ Save Project" ] }, { "cell_type": "code", "execution_count": 37, "id": "70", "metadata": { "execution": { "iopub.execute_input": "2026-06-30T22:42:43.749177Z", "iopub.status.busy": "2026-06-30T22:42:43.748996Z", "iopub.status.idle": "2026-06-30T22:42:44.954911Z", "shell.execute_reply": "2026-06-30T22:42:44.954253Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1;36mSaving project πŸ“¦ \u001b[0m\u001b[32m'pbso4_joint'\u001b[0m\u001b[1;36m to \u001b[0m\u001b[32m'../../../projects/refine-pbso4-joint'\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”œβ”€β”€ πŸ“„ project.edi\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”œβ”€β”€ πŸ“ structures/\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”‚ └── πŸ“„ pbso4.edi\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”œβ”€β”€ πŸ“ experiments/\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”‚ └── πŸ“„ npd.edi\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”‚ └── πŸ“„ xrd.edi\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”œβ”€β”€ πŸ“ analysis/\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "β”‚ └── πŸ“„ analysis.edi\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "└── πŸ“ reports/\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " └── πŸ“„ pbso4_joint.html\n" ] } ], "source": [ "project.save_as(dir_path='projects/refine-pbso4-joint')" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.5" } }, "nbformat": 4, "nbformat_minor": 5 }