{ "cells": [ { "cell_type": "markdown", "id": "3f1e3cd5-a642-4f2b-991a-85f97a10e080", "metadata": {}, "source": [ "# MX Calibrate\n", "\n", "Calibrate a translation table from a set of powder diffraction images taken at various sample-detector distances.\n", "\n", "This is a notebook replacement of the `MX-calibrate` tool from pyFAI with advanced features.\n", "\n", "## Start with some constant definition:" ] }, { "cell_type": "code", "execution_count": 1, "id": "890831db-9c69-4a3f-a7c6-8e5f486d17e4", "metadata": {}, "outputs": [], "source": [ "calibrant_name = \"CeO2\"\n", "detector_name = \"Pilatus 2M\"\n", "file_pattern = \"massif1/test-powder*.cbf\"\n", "result_file = \"MX-calibrate.json\"\n", "wavelength = None # set a value to override the one in the headers" ] }, { "cell_type": "code", "execution_count": 2, "id": "f19c5ce7-5822-4526-9025-fc2d0447c30a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--2024-09-12 12:30:57-- http://www.silx.org/pub/pyFAI/massif1.tar.bz2\n", "Resolving www.silx.org (www.silx.org)... 195.154.237.27\n", "Connecting to www.silx.org (www.silx.org)|195.154.237.27|:80... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 6784503 (6.5M) [application/x-bzip2]\n", "Saving to: ‘massif1.tar.bz2.1’\n", "\n", "massif1.tar.bz2.1 100%[===================>] 6.47M 22.4MB/s in 0.3s \n", "\n", "2024-09-12 12:30:57 (22.4 MB/s) - ‘massif1.tar.bz2.1’ saved [6784503/6784503]\n", "\n", "massif1/\n", "massif1/test-powder_5_0001.poni\n", "massif1/test-powder_4_0001.cbf\n", "massif1/test-powder_6_0001.poni\n", "massif1/test-powder_8_0001.cbf\n", "massif1/test-powder_7_0001.cbf\n", "massif1/test-powder_7_0001.poni\n", "massif1/test-powder_3_0001.cbf\n", "massif1/test-powder_1_0001.poni\n", "massif1/test-powder_4_0001.poni\n", "massif1/test-powder_8_0001.poni\n", "massif1/test-powder_2_0001.poni\n", "massif1/test-powder_6_0001.cbf\n", "massif1/test-powder_2_0001.cbf\n", "massif1/test-powder_5_0001.cbf\n", "massif1/test-powder_3_0001.poni\n", "massif1/test-powder_1_0001.cbf\n" ] } ], "source": [ "!wget http://www.silx.org/pub/pyFAI/massif1.tar.bz2\n", "!tar -xvjf massif1.tar.bz2" ] }, { "cell_type": "code", "execution_count": 3, "id": "7df9ad23-f82d-4ea1-b7cf-f42f0f56b02d", "metadata": {}, "outputs": [], "source": [ "%matplotlib widget \n", "#inline2" ] }, { "cell_type": "code", "execution_count": 4, "id": "c59931d3-5964-4af1-b68d-85c45cd7fac2", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:pyFAI.gui.matplotlib:matplotlib already loaded, setting its backend may not work\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Running pyFAI version 2024.9.0-dev0\n" ] } ], "source": [ "import os\n", "import glob\n", "import logging\n", "import numpy\n", "from matplotlib.pyplot import subplots\n", "from scipy.stats import linregress\n", "import fabio\n", "import pyFAI\n", "from pyFAI.gui import jupyter\n", "import pyFAI.calibrant\n", "from pyFAI.gui.jupyter.calib import Calibration\n", "from pyFAI.goniometer import GeometryTransformation, GoniometerRefinement\n", "from pyFAI.gui.cli_calibration import AbstractCalibration\n", "import pyFAI.gui.mpl_calib\n", "pyFAI.gui.mpl_calib.logger.setLevel(logging.ERROR)\n", "print(f\"Running pyFAI version {pyFAI.version}\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "99ed0d6d-1107-4c32-a7d2-87d05b3bf120", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "input files: massif1/test-powder_1_0001.cbf massif1/test-powder_2_0001.cbf massif1/test-powder_3_0001.cbf massif1/test-powder_4_0001.cbf massif1/test-powder_5_0001.cbf massif1/test-powder_6_0001.cbf massif1/test-powder_7_0001.cbf massif1/test-powder_8_0001.cbf\n" ] } ], "source": [ "detector = pyFAI.detector_factory(detector_name)\n", "calibrant = pyFAI.calibrant.get_calibrant(calibrant_name)\n", "files = sorted(glob.glob(file_pattern))\n", "print(\"input files: \"+\" \".join(files))" ] }, { "cell_type": "code", "execution_count": 6, "id": "06a094b3-f243-4280-a318-71960bce9e59", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Silicon': 0.00045,\n", " 'Pixel_size': 0.000172,\n", " 'N_oscillations': 1,\n", " 'Chi': 0.0,\n", " 'Phi': 0.0,\n", " 'Kappa': 0.0,\n", " 'Alpha': 0.0,\n", " 'Polarization': 0.99,\n", " 'Detector_2theta': 0.0,\n", " 'Angle_increment': 1.0,\n", " 'Transmission': 100.0,\n", " 'Flux': 436215830143.2828,\n", " 'Detector_Voffset': 0.0,\n", " 'Detector_distance': 0.126474,\n", " 'Wavelength': 0.965459,\n", " 'N_excluded_pixels:': 321,\n", " 'Threshold_setting': 6421,\n", " 'Count_cutoff': 1048500,\n", " 'Tau': 0,\n", " 'Exposure_period': 0.02115,\n", " 'Exposure_time': 0.02,\n", " 'Start_angle': 0.0}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "first = fabio.open(files[0])\n", "\n", "def get_dectris_headers(fimg):\n", " \"\"\"return the dectris headers from a Pilatus detector\"\"\"\n", " res = {}\n", " for line in fimg.header.get(\"_array_data.header_contents\", \"\").split(\"\\n\"):\n", " words = line.split()\n", " if len(words)>=3:\n", " key = words[1]\n", " for v in words[2:]:\n", " try:\n", " vf = float(v)\n", " except:\n", " continue\n", " if not(\".\" in v or \"e\" in v):\n", " vf = int(v)\n", " res[key] = vf\n", " return res\n", "\n", "get_dectris_headers(first)" ] }, { "cell_type": "code", "execution_count": 7, "id": "7524c738-c41f-4e0d-b3c8-30075d1ed51f", "metadata": {}, "outputs": [], "source": [ "if wavelength is None:\n", " wavelength = get_dectris_headers(first)[\"Wavelength\"] * 1e-10\n", "calibrant.wavelength = wavelength" ] }, { "cell_type": "code", "execution_count": 8, "id": "f0ebe605-aa0d-497e-8955-979ab9b20dac", "metadata": {}, "outputs": [], "source": [ "#apply mask to the detector\n", "mask = numpy.logical_or(detector.mask, first.data<0)\n", "detector.mask = mask" ] }, { "cell_type": "markdown", "id": "6e0c4d70-2e9c-492e-bb91-4933f1354ba7", "metadata": {}, "source": [ "## Manual calibration of the first image" ] }, { "cell_type": "code", "execution_count": 9, "id": "a27cf042-4443-44a0-8655-1bffbb7b1b89", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "eca73a55c90d454887e3bc321e84d2fb", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(Output(), HBox(children=(Button(description='Refine', style=ButtonStyle(), tooltip='switch to r…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3019c08372154fcba5b1d0931a8cef0a", "version_major": 2, "version_minor": 0 }, "image/png": "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AAAYhgAIAABgGAIgAACAYQiAAAAAhiEAAgAAGIYACAAAYBgCIAAAgGEIgAAAAIYhAAIAABiGAAgAgAtLSUlRaGiofH19FR0drV27dl23/5w5c3THHXeoTp06Cg4O1pgxY3TlypUaqhY1hQAIAICLWrFihRITEzVx4kTt3btX4eHhiouL09mzZ8vtv2zZMo0bN04TJ07UoUOHtGDBAq1YsUIvvfRSDVeO6kYArKTk5GR16tRJ9evXV9OmTdW3b19lZ2eX6nPlyhUlJCSocePGqlevnvr376/c3FybKgYAmG7WrFkaNmyYhgwZojZt2ig1NVV169bVwoULy+2/fft2devWTY8++qhCQ0PVs2dPPfLII/921hA3HgJgJW3dulUJCQnasWOHNm/erOLiYvXs2VMFBQXOPmPGjNH69eu1atUqbd26VadPn1a/fv1srBoAYKqioiJlZWUpNjbW2ebu7q7Y2FhlZmaWu07Xrl2VlZXlDHzfffedNm3apD//+c81UjNqjqfdBdwo0tLSSj1evHixmjZtqqysLN19993Ky8vTggULtGzZMt13332SpEWLFql169basWOHunTpYkfZAABDnT9/XiUlJQoICCjVHhAQoMOHD5e7zqOPPqrz58/rzjvvlGVZunr1qp5++unrngIuLCxUYWGh83F+fn7VvABUK2YAf6e8vDxJUqNGjSRJWVlZKi4uLnWk1apVK4WEhFR4pFVYWKj8/PxSCwAAdsnIyNDUqVP19ttva+/evfroo4+0ceNGTZ48ucJ1kpOT5e/v71yCg4NrsGL8XgTA38HhcGj06NHq1q2b2rZtK0nKycmRt7e3GjRoUKpvQECAcnJyyt0OfzQAgOrSpEkTeXh4lPksem5urgIDA8tdZ8KECRo0aJCefPJJtWvXTn/96181depUJScny+FwlLvO+PHjlZeX51xOnjxZ5a8FVY8A+DskJCTo4MGDWr58+X+0Hf5oAADVxdvbWx07dlR6erqzzeFwKD09XTExMeWuc/nyZbm7l44GHh4ekiTLsspdx8fHR35+fqUW1H58BvA3GjlypDZs2KBt27bplltucbYHBgaqqKhIFy9eLDULeL0jLR8fH/n4+FR3yQAAQyUmJio+Pl5RUVHq3Lmz5syZo4KCAg0ZMkSSNHjwYDVv3lzJycmSpN69e2vWrFmKjIxUdHS0jh49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MTEx3L3CAC59Crhhw4bOz9WlpaU5r9C1LOu69zT6vWbPnq0HHnhA/fv31913363AwEB99NFHVb4fAACA/4RLzwD269dPjz76qFq2bKkffvhB999/vyRp3759uv322//j7f/6yMnX11cpKSlKSUn5j7cNAABQXVw6AM6ePVuhoaE6efKkZsyYoXr16kmSzpw5oxEjRthcHQAAgD1cOgB6eXnp+eefL9M+ZswYG6oBAACoHVwuAK5bt67Sff/yl79UYyUAAAC1k8sFwL59+1aqn5ubW7VcCAIAAFDbuVwA/Ne7lwMAAKAsl74NzL+6cuWK3SUAAADUCi4dAEtKSjR58mQ1b95c9erV03fffSdJmjBhghYsWGBzdQAAAPZw6QA4ZcoULV68WDNmzCj1JdZt27bVe++9Z2NlAAAA9nHpAPj+++/r3Xff1cCBA+Xh4eFsDw8P1+HDh22sDAAAwD4uHQBPnTpV7jd+OBwOFRcX21ARAACA/Vw6ALZp00ZffPFFmfbVq1crMjLShooAAADs53K3gflXSUlJio+P16lTp+RwOPTRRx8pOztb77//vjZs2GB3eQAAALZw6RnAPn36aP369frss8900003KSkpSYcOHdL69ev1pz/9ye7yAAAAbOHSM4CSdNddd2nz5s1l2i3Lkpubmw0VAQAA2MulZwAff/xxFRQUlGk/fvy47r77bhsqAgAAsJ9LB8ADBw6offv2yszMdLYtWbJE4eHhatKkiY2VAQAA2MelTwHv2rVLL730ku655x4999xzOnr0qD755BPNmjVLw4YNs7s8AAAAW7h0APTy8tLrr7+uunXravLkyfL09NTWrVsVExNjd2kAAAC2celTwMXFxXruuec0ffp0jR8/XjExMerXr582bdpkd2kAAAC2cekZwKioKF2+fFkZGRnq0qWLLMvSjBkz1K9fPw0dOlRvv/223SUCAADUOJeeAYyKitL+/fvVpUsXSZKbm5vGjh2rzMxMbdu2zebqAAAA7OHSM4ALFiwotz0yMlJZWVk1XA0AAEDt4HIBMD8/X35+fs6fr8fHx6cmSgIAAKhVXC4ANmzYUGfOnFHTpk3VoEGDcr/t49q3gJSUlNhQIQAAgL1cLgB+/vnnatSokSRpy5YtNlcDAABQ+7hcAOzevXu5PwMAAOAXLhcAf+3ChQtasGCBDh06JElq06aN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9Gip53766SdNmjRJ/fr1K7Oer69vmbYOHTro2LFj+uSTT/TZZ5/poYceUmxsrFavXl2lNQPAjYQZQMAQRUVFeuyxxzRgwABNnjxZTz755L+duasqO3bscP589epVZWVlqXXr1hX2f/3113X48GFt3bpVaWlpWrRokfO5Dh06KDs7W7fffnuZxd29/P/S/Pz8NGDAAM2fP18rVqzQhx9+qB9//LHqXiAA3GCYAQQM8fLLLysvL09z585VvXr1tGnTJg0dOlQbNmyo9n2npKSoZcuWat26tWbPnq0LFy5UePHIvn37lJSUpNWrV6tbt26aNWuWRo0ape7du+vWW29VUlKSHnjgAYWEhOjBBx+Uu7u7Dhw4oIMHD+q1114rs71Zs2YpKChIkZGRcnd316pVqxQYGKgGDRpU86sGgNqLGUDAABkZGZozZ44++OAD+fn5yd3dXR988IG++OILzZs3r9r3P23aNE2bNk3h4eH68ssvtW7dunJvMH3lyhU99thjevzxx9W7d29J0lNPPaV7771XgwYNUklJieLi4rRhwwZ9+umn6tSpk7p06aLZs2erRYsW5e67fv36mjFjhqKiotSpUycdP35cmzZtqnC2EABM4GZZlmV3EQBc0/HjxxUWFqZ9+/YpIiLC7nIAAP8fh8AAAACGIQACAAAYhlPAAAAAhmEGEAAAwDAEQAAAAMMQAAEAAAxDAAQAADAMARAAAMAwBEAAAADDEAABAAAMQwAEAAAwDAEQAADAMP8P81fu1vIwF4gAAAAASUVORK5CYII=", "text/html": [ "\n", "