{ "cells": [ { "cell_type": "markdown", "id": "75303862", "metadata": {}, "source": [ "# Simple forward model\n", "Now we have some crystallographic functions and we can handle the detector geometry, we can perform a basic forward model of a single crystal to reassure ourselves that this wasn't all for nothing!" ] }, { "cell_type": "code", "execution_count": null, "id": "ce20acf9", "metadata": {}, "outputs": [], "source": [ "import jax\n", "jax.config.update(\"jax_enable_x64\", True)\n", "import jax.numpy as jnp\n", "from jax.scipy.spatial.transform import Rotation as jR\n", "from matplotlib import pyplot as plt\n", "\n", "import anri\n", "\n", "import time\n", "\n", "start = time.time()" ] }, { "cell_type": "markdown", "id": "bb412121", "metadata": {}, "source": [ "In `Anri`, all fundamental functions and transforms are written for single vectors. \n", "This was written to significantly simplify the functions themselves, keeping them easy to understand. \n", "Additonally, when forward simulating many grains or voxels, you will likely have more complicated array shapes, so it makes sense to leave the broadcasting to the user or another part of the program for now. \n", "I'm currently still grappling with the best way to expose vmapped functions in the API, so for now I will manually declare them here:" ] }, { "cell_type": "code", "execution_count": 2, "id": "aa3b1501", "metadata": {}, "outputs": [], "source": [ "# easy example: many hkls, single B matrix, so we vmap over hkls only, giving us [0, None]\n", "omega_solns_vec = jax.vmap(anri.diffract.omega_solns, in_axes=[0, None, None])\n", "sample_to_lab_vec = jax.vmap(anri.geom.sample_to_lab, in_axes=[0, 0, None, None, None, None])\n", "q_lab_to_k_out_vec = jax.vmap(anri.diffract.q_lab_to_k_out, in_axes=[0, None])\n", "raytrace_to_det_vec = jax.vmap(anri.geom.raytrace_to_det, in_axes=[0, None, None, None, None])\n", "q_lab_to_tth_eta_vec = jax.vmap(anri.diffract.q_lab_to_tth_eta, in_axes=[0, None])" ] }, { "cell_type": "markdown", "id": "76f1dbc4", "metadata": {}, "source": [ "## Crystallography" ] }, { "cell_type": "markdown", "id": "f799e94f", "metadata": {}, "source": [ "Let's take a simple Fe CIF file" ] }, { "cell_type": "code", "execution_count": null, "id": "ae8d4d5b", "metadata": {}, "outputs": [], "source": [ "struc = anri.crystal.Structure.from_cif(\"../../../tests/data/cif/Fe.cif\")" ] }, { "cell_type": "markdown", "id": "9af46d0a", "metadata": {}, "source": [ "We generate some hkls:" ] }, { "cell_type": "code", "execution_count": 4, "id": "270ebc9a", "metadata": {}, "outputs": [], "source": [ "dsmax = 2.0\n", "wavelength = 0.3\n", "struc.make_hkls(dsmax=dsmax, wavelength=wavelength)" ] }, { "cell_type": "code", "execution_count": 5, "id": "d55e03b6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
| h | k | l | tth | ds | intensity | ring_id |
|---|---|---|---|---|---|---|
| i64 | i64 | i64 | f64 | f64 | f64 | u32 |
| -1 | 1 | 0 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| -1 | 0 | 1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| -1 | 0 | -1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| 0 | -1 | -1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| 0 | -1 | 1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| … | … | … | … | … | … | … |
| 1 | 0 | -1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| -1 | -1 | 0 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| 1 | 0 | 1 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| 1 | 1 | 0 | 8.498266 | 0.493956 | 1363.448082 | 0 |
| 1 | -1 | 0 | 8.498266 | 0.493956 | 1363.448082 | 0 |