{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basic XRayLabTool Examples\n", "\n", "This notebook demonstrates basic usage of XRayLabTool for X-ray optical property calculations.\n", "\n", "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/imewei/pyXRayLabTool/blob/main/docs/examples/basic_examples.ipynb)\n", "[![nbviewer](https://img.shields.io/badge/nbviewer-view-blue)](https://nbviewer.org/github/imewei/pyXRayLabTool/blob/main/docs/examples/basic_examples.ipynb)\n", "\n", "## Setup and Installation\n", "\n", "First, ensure XRayLabTool is installed:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [ "colab-setup" ] }, "outputs": [], "source": [ "# Colab setup: install XRayLabTool and set paths\n", "import os\n", "from pathlib import Path\n", "import sys\n", "\n", "IN_COLAB = \"google.colab\" in sys.modules\n", "if IN_COLAB and sys.version_info < (3, 12):\n", " raise SystemExit(\n", " \"Please switch the Colab runtime to Python 3.12+ (Runtime → Change runtime type).\"\n", " )\n", "\n", "if IN_COLAB:\n", " %pip install -q xraylabtool\n", "\n", "ROOT = Path(\"/content\") if IN_COLAB else Path.cwd()\n", "DATA_DIR = ROOT / \"data\"\n", "DATA_DIR.mkdir(exist_ok=True)\n", "if IN_COLAB:\n", " os.chdir(ROOT)\n", "print(f\"Working dir: {ROOT}\\nData dir: {DATA_DIR}\\nColab: {IN_COLAB}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", "\n", "import xraylabtool as xrt\n", "\n", "print(f\"XRayLabTool version: {xrt.__version__}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 1: Single Material Calculation\n", "\n", "Calculate X-ray properties for silicon at 8 keV:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Calculate properties for silicon\n", "result = xrt.calculate_single_material_properties(\n", " formula=\"Si\",\n", " density=2.33, # g/cm³\n", " energy=8000, # eV\n", ")\n", "\n", "print(f\"Material: {result.formula}\")\n", "print(f\"Density: {result.density_g_cm3} g/cm³\")\n", "print(f\"Energy: {result.energy_ev} eV\")\n", "print(f\"Wavelength: {result.wavelength_angstrom:.3f} Å\")\n", "print(\"\")\n", "print(\"Refractive index decrement:\")\n", "print(f\" δ (delta): {result.delta:.2e}\")\n", "print(f\" β (beta): {result.beta:.2e}\")\n", "print(\"\")\n", "print(f\"Critical angle: {result.critical_angle_degrees:.3f}°\")\n", "print(f\"Critical angle: {result.critical_angle_mrad:.2f} mrad\")\n", "print(f\"Attenuation length: {result.attenuation_length_cm:.2f} cm\")\n", "print(f\"Linear absorption coefficient: {result.linear_absorption_coefficient:.3f} cm⁻¹\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 2: Compound Materials\n", "\n", "Calculate properties for silicon dioxide (quartz):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Silicon dioxide (quartz)\n", "sio2_result = xrt.calculate_single_material_properties(\n", " formula=\"SiO2\",\n", " density=2.20, # g/cm³ for quartz\n", " energy=8000,\n", ")\n", "\n", "print(f\"Material: {sio2_result.formula}\")\n", "print(f\"Critical angle: {sio2_result.critical_angle_degrees:.3f}°\")\n", "print(f\"Attenuation length: {sio2_result.attenuation_length_cm:.2f} cm\")\n", "\n", "# Compare with pure silicon\n", "print(\"\\nComparison with pure Si:\")\n", "print(f\"Si critical angle: {result.critical_angle_degrees:.3f}°\")\n", "print(f\"SiO2 critical angle: {sio2_result.critical_angle_degrees:.3f}°\")\n", "print(\n", " f\"Difference: {result.critical_angle_degrees - sio2_result.critical_angle_degrees:.3f}°\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 3: Energy Range Analysis\n", "\n", "Study how properties vary with X-ray energy:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Define energy range\n", "energies = np.logspace(3, 4.5, 50) # 1 keV to ~32 keV\n", "\n", "# Calculate properties for each energy\n", "results_si = []\n", "for energy in energies:\n", " result = xrt.calculate_single_material_properties(\"Si\", 2.33, energy)\n", " results_si.append(result)\n", "\n", "# Extract arrays for plotting\n", "critical_angles = [r.critical_angle_mrad for r in results_si]\n", "attenuation_lengths = [r.attenuation_length_cm for r in results_si]\n", "delta_values = [r.delta for r in results_si]\n", "beta_values = [r.beta for r in results_si]\n", "\n", "print(f\"Energy range: {energies[0]:.0f} - {energies[-1]:.0f} eV\")\n", "print(\n", " f\"Critical angle range: {min(critical_angles):.2f} - {max(critical_angles):.2f} mrad\"\n", ")\n", "print(\n", " f\"Attenuation length range: {min(attenuation_lengths):.1f} - {max(attenuation_lengths):.1f} cm\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualization of Energy Dependence" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create subplots\n", "fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))\n", "\n", "# Critical angle vs energy\n", "ax1.loglog(energies, critical_angles, \"b-\", linewidth=2)\n", "ax1.set_xlabel(\"Energy (eV)\")\n", "ax1.set_ylabel(\"Critical Angle (mrad)\")\n", "ax1.set_title(\"Critical Angle vs Energy\")\n", "ax1.grid(True, alpha=0.3)\n", "\n", "# Attenuation length vs energy\n", "ax2.loglog(energies, attenuation_lengths, \"r-\", linewidth=2)\n", "ax2.set_xlabel(\"Energy (eV)\")\n", "ax2.set_ylabel(\"Attenuation Length (cm)\")\n", "ax2.set_title(\"Attenuation Length vs Energy\")\n", "ax2.grid(True, alpha=0.3)\n", "\n", "# Delta vs energy\n", "ax3.loglog(energies, delta_values, \"g-\", linewidth=2)\n", "ax3.set_xlabel(\"Energy (eV)\")\n", "ax3.set_ylabel(\"δ (delta)\")\n", "ax3.set_title(\"Refractive Index Decrement (δ)\")\n", "ax3.grid(True, alpha=0.3)\n", "\n", "# Beta vs energy\n", "ax4.loglog(energies, beta_values, \"m-\", linewidth=2)\n", "ax4.set_xlabel(\"Energy (eV)\")\n", "ax4.set_ylabel(\"β (beta)\")\n", "ax4.set_title(\"Absorption Parameter (β)\")\n", "ax4.grid(True, alpha=0.3)\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 4: Material Comparison\n", "\n", "Compare different materials for X-ray optics applications:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Define materials for comparison\n", "materials = [\n", " {\"name\": \"Silicon\", \"formula\": \"Si\", \"density\": 2.33},\n", " {\"name\": \"Silicon Dioxide\", \"formula\": \"SiO2\", \"density\": 2.20},\n", " {\"name\": \"Aluminum\", \"formula\": \"Al\", \"density\": 2.70},\n", " {\"name\": \"Copper\", \"formula\": \"Cu\", \"density\": 8.96},\n", " {\"name\": \"Gold\", \"formula\": \"Au\", \"density\": 19.32},\n", "]\n", "\n", "energy = 8000 # eV\n", "comparison_results = []\n", "\n", "for material in materials:\n", " result = xrt.calculate_single_material_properties(\n", " material[\"formula\"], material[\"density\"], energy\n", " )\n", " comparison_results.append(\n", " {\n", " \"Material\": material[\"name\"],\n", " \"Formula\": material[\"formula\"],\n", " \"Density (g/cm³)\": material[\"density\"],\n", " \"Critical Angle (°)\": result.critical_angle_degrees,\n", " \"Critical Angle (mrad)\": result.critical_angle_mrad,\n", " \"Attenuation Length (cm)\": result.attenuation_length_cm,\n", " \"δ (×10⁶)\": result.delta * 1e6,\n", " \"β (×10⁶)\": result.beta * 1e6,\n", " }\n", " )\n", "\n", "# Create DataFrame for nice display\n", "df = pd.DataFrame(comparison_results)\n", "print(f\"Material comparison at {energy} eV:\")\n", "print(df.round(3).to_string(index=False))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualization of Material Comparison" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bar plot comparison\n", "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))\n", "\n", "materials_names = [m[\"name\"] for m in materials]\n", "critical_angles_deg = df[\"Critical Angle (°)\"].astype(float).to_numpy()\n", "attenuation_lengths = df[\"Attenuation Length (cm)\"].astype(float).to_numpy()\n", "\n", "# Critical angles\n", "bars1 = ax1.bar(\n", " materials_names,\n", " critical_angles_deg,\n", " color=[\"blue\", \"lightblue\", \"green\", \"orange\", \"gold\"],\n", ")\n", "ax1.set_ylabel(\"Critical Angle (degrees)\")\n", "ax1.set_title(f\"Critical Angles at {energy} eV\")\n", "ax1.tick_params(axis=\"x\", rotation=45)\n", "ax1.grid(True, alpha=0.3)\n", "\n", "# Add value labels on bars\n", "for bar, value in zip(bars1, critical_angles_deg, strict=False):\n", " ax1.text(\n", " bar.get_x() + bar.get_width() / 2,\n", " bar.get_height() + 0.001,\n", " f\"{value:.3f}°\",\n", " ha=\"center\",\n", " va=\"bottom\",\n", " fontsize=9,\n", " )\n", "\n", "# Attenuation lengths (log scale)\n", "bars2 = ax2.bar(\n", " materials_names,\n", " attenuation_lengths,\n", " color=[\"blue\", \"lightblue\", \"green\", \"orange\", \"gold\"],\n", ")\n", "ax2.set_ylabel(\"Attenuation Length (cm)\")\n", "ax2.set_title(f\"Attenuation Lengths at {energy} eV\")\n", "ax2.set_yscale(\"log\")\n", "ax2.tick_params(axis=\"x\", rotation=45)\n", "ax2.grid(True, alpha=0.3)\n", "\n", "# Add value labels on bars\n", "for bar, value in zip(bars2, attenuation_lengths, strict=False):\n", " ax2.text(\n", " bar.get_x() + bar.get_width() / 2,\n", " bar.get_height() * 1.2,\n", " f\"{value:.1f} cm\",\n", " ha=\"center\",\n", " va=\"bottom\",\n", " fontsize=9,\n", " )\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 5: Complex Formulas\n", "\n", "Demonstrate parsing of complex chemical formulas:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Complex formulas\n", "complex_materials = [\n", " {\"formula\": \"Ca5(PO4)3F\", \"density\": 3.18, \"name\": \"Fluorapatite\"},\n", " {\"formula\": \"CuSO4·5H2O\", \"density\": 2.29, \"name\": \"Copper sulfate pentahydrate\"},\n", " {\"formula\": \"Al2(SO4)3·18H2O\", \"density\": 1.69, \"name\": \"Aluminum sulfate hydrate\"},\n", "]\n", "\n", "print(\"Complex formula parsing and calculation:\")\n", "print(\"=\" * 60)\n", "\n", "for material in complex_materials:\n", " # First, let's parse the formula to see the composition\n", " from xraylabtool.utils import parse_formula\n", "\n", " composition = parse_formula(material[\"formula\"])\n", " print(f\"\\n{material['name']}: {material['formula']}\")\n", " print(f\"Elemental composition: {composition}\")\n", "\n", " # Calculate properties\n", " result = xrt.calculate_single_material_properties(\n", " material[\"formula\"], material[\"density\"], 8000\n", " )\n", "\n", " print(f\"Density: {material['density']} g/cm³\")\n", " print(f\"Critical angle: {result.critical_angle_degrees:.3f}°\")\n", " print(f\"Attenuation length: {result.attenuation_length_cm:.2f} cm\")\n", " print(\"-\" * 40)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 6: Batch Processing\n", "\n", "Process multiple materials efficiently:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a list of materials for batch processing\n", "batch_materials = [\n", " {\"formula\": \"Si\", \"density\": 2.33},\n", " {\"formula\": \"SiO2\", \"density\": 2.20},\n", " {\"formula\": \"Al\", \"density\": 2.70},\n", " {\"formula\": \"Al2O3\", \"density\": 3.95},\n", " {\"formula\": \"Cu\", \"density\": 8.96},\n", " {\"formula\": \"Au\", \"density\": 19.32},\n", " {\"formula\": \"C\", \"density\": 2.26}, # Graphite\n", " {\"formula\": \"Fe\", \"density\": 7.87},\n", "]\n", "\n", "# Define energy points (eV)\n", "energy_points = [5000, 8000, 10000, 15000]\n", "\n", "# Batch calculation\n", "formulas_batch = [m[\"formula\"] for m in batch_materials]\n", "densities_batch = [m[\"density\"] for m in batch_materials]\n", "energy_points_kev = [e / 1000.0 for e in energy_points]\n", "batch_results = xrt.calculate_xray_properties(\n", " formulas_batch, energy_points_kev, densities_batch\n", ")\n", "\n", "print(\"Batch processing completed:\")\n", "print(f\"Materials processed: {len(batch_materials)}\")\n", "print(f\"Energy points: {len(energy_points)}\")\n", "calc_count = sum(len(np.atleast_1d(res.energy_ev)) for res in batch_results.values())\n", "print(f\"Total calculations: {calc_count}\")\n", "\n", "# Display sample results (first 10 entries across all materials/energies)\n", "sample_title = \"Sample results (first 10):\"\n", "print(\"\\n\" + sample_title)\n", "flat_results = []\n", "for formula, res in batch_results.items():\n", " energies = np.atleast_1d(res.energy_ev)\n", " criticals = np.atleast_1d(res.critical_angle_degrees)\n", " att_lens = np.atleast_1d(res.attenuation_length_cm)\n", " for energy_ev, critical, att_len in zip(\n", " energies, criticals, att_lens, strict=False\n", " ):\n", " flat_results.append(\n", " (formula, float(energy_ev), float(critical), float(att_len))\n", " )\n", "\n", "for i, (formula, energy_ev, critical, att_len) in enumerate(flat_results[:10]):\n", " print(\n", " f\"{i + 1:2d}. {formula:6s} at {energy_ev:6.0f} eV: \"\n", " f\"θc = {critical:.3f}°, att_len = {att_len:6.2f} cm\"\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example 7: Unit Conversions\n", "\n", "Demonstrate energy-wavelength conversions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from xraylabtool.utils import energy_to_wavelength, wavelength_to_energy\n", "\n", "# Energy to wavelength conversions\n", "energies_kev = [1, 5, 8, 10, 15, 20, 30]\n", "energies_ev = [e * 1000 for e in energies_kev]\n", "\n", "print(\"Energy to Wavelength Conversions:\")\n", "print(\"Energy (keV) Energy (eV) Wavelength (Å)\")\n", "print(\"-\" * 40)\n", "\n", "for kev, ev in zip(energies_kev, energies_ev, strict=False):\n", " wavelength = energy_to_wavelength(ev)\n", " print(f\"{kev:8.0f} {ev:8.0f} {wavelength:10.4f}\")\n", "\n", "# Wavelength to energy conversions\n", "print(\"\\nCommon X-ray lines:\")\n", "xray_lines = [\n", " (\"Cu Kα1\", 1.5406),\n", " (\"Mo Kα1\", 0.7093),\n", " (\"Ag Kα1\", 0.5594),\n", " (\"Cr Kα1\", 2.2909),\n", "]\n", "\n", "print(\"Line Wavelength (Å) Energy (eV) Energy (keV)\")\n", "print(\"-\" * 50)\n", "\n", "for line_name, wavelength in xray_lines:\n", " energy_ev = wavelength_to_energy(wavelength)\n", " energy_kev = energy_ev / 1000\n", " print(f\"{line_name:8s} {wavelength:12.4f} {energy_ev:9.1f} {energy_kev:9.3f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Summary\n", "\n", "This notebook demonstrated:\n", "\n", "1. **Single material calculations** - Basic usage for simple materials\n", "2. **Compound materials** - Parsing complex chemical formulas\n", "3. **Energy dependence** - How properties vary with X-ray energy\n", "4. **Material comparison** - Side-by-side analysis of different materials\n", "5. **Complex formulas** - Handling hydrated compounds and complex stoichiometry\n", "6. **Batch processing** - Efficient calculation for multiple materials\n", "7. **Unit conversions** - Energy-wavelength relationships\n", "\n", "### Key Insights:\n", "\n", "- **Critical angles** are typically small (< 1°) for hard X-rays\n", "- **Heavy elements** (Au, Cu) have larger critical angles than light elements (Si, C)\n", "- **Attenuation lengths** vary dramatically between materials and energies\n", "- **Energy scaling**: Critical angle ∝ E⁻¹, Attenuation length ∝ E³\n", "- **Compounds** have properties intermediate between their constituent elements\n", "\n", "### Next Steps:\n", "\n", "- Explore the CLI interface with `xraylabtool --help`\n", "- Try the synchrotron applications examples\n", "- Investigate material optimization for specific applications\n", "- Learn about the underlying X-ray physics in the documentation" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.12.0" } }, "nbformat": 4, "nbformat_minor": 4 }