{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "emotional-civilian",
   "metadata": {},
   "source": [
    "# Wilson plots generated from sparse datasets\n",
    "\n",
    "The input data comes from the sparsification of the zenodo dataset available at:\n",
    "https://zenodo.org/record/3834335"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "wireless-psychiatry",
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: '/mnt/data/jungfrau'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m filename\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/mnt/data/jungfrau/sparse_512_3_0_2_fit_q2.h5\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mos\u001b[39;00m\u001b[38;5;241m,\u001b[39m \u001b[38;5;21;01mtime\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mchdir\u001b[49m\u001b[43m(\u001b[49m\u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpath\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdirname\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      4\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mperf_counter()\n",
      "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/mnt/data/jungfrau'"
     ]
    }
   ],
   "source": [
    "filename=\"/mnt/data/jungfrau/sparse_512_3_0_2_fit_q2.h5\"\n",
    "import os, time\n",
    "os.chdir(os.path.dirname(filename))\n",
    "start_time = time.perf_counter()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "stopped-illinois",
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib nbagg\n",
    "import json, pyFAI\n",
    "import hdf5plugin\n",
    "import h5py\n",
    "import numpy\n",
    "from ipywidgets import interact, interactive, fixed, interact_manual\n",
    "import ipywidgets as widgets\n",
    "from matplotlib.pyplot import subplots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "laughing-reservoir",
   "metadata": {},
   "outputs": [],
   "source": [
    "root = h5py.File(filename, \"r\")\n",
    "de = root.attrs[\"default\"]\n",
    "entry = root[de]\n",
    "nx_data = entry[entry.attrs[\"default\"]]\n",
    "dict(nx_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "medical-elder",
   "metadata": {},
   "outputs": [],
   "source": [
    "radius = nx_data[\"radius\"]\n",
    "I_bg = nx_data[\"background_avg\"]\n",
    "resolution = 10/numpy.sqrt(radius)\n",
    "resolution[:4],resolution[-4:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "designing-vertical",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = subplots()\n",
    "ax.plot(radius, numpy.log(I_bg[0]))\n",
    "ax.set_ylabel(\"$log(\\overline{I_{bg}})$\")\n",
    "ax.set_xlabel(\"$d^*² (nm^{-2})$\")\n",
    "ax.set_title(\"Wilson-like plot on frame #0\")\n",
    "pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fancy-orleans",
   "metadata": {},
   "outputs": [],
   "source": [
    "frame_ptr = nx_data[\"frame_ptr\"]\n",
    "npix = frame_ptr[1:]-frame_ptr[:-1]\n",
    "fig,ax = subplots()\n",
    "ax.plot(npix)\n",
    "ax.set_xlabel(\"Frame number\")\n",
    "ax.set_ylabel(\"Number of recorded pixels\")\n",
    "ax.set_title(\"Number of peaks per frame\")\n",
    "frame = numpy.argmax(npix)\n",
    "print(f\"Frame index with largest number of pixel recorded: {frame}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "weird-newport",
   "metadata": {},
   "outputs": [],
   "source": [
    "mask = nx_data[\"mask\"]\n",
    "shape = mask.shape\n",
    "size = numpy.prod(shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "weird-dominican",
   "metadata": {},
   "outputs": [],
   "source": [
    "nticks = 7\n",
    "fig, ax = subplots()\n",
    "ax.plot(radius, numpy.log(I_bg[frame]), label=\"Background\")\n",
    "tick_value = numpy.linspace(radius[0], radius[-1], nticks)\n",
    "ax.set_xticks(tick_value)\n",
    "tick_label = [f\"{10/numpy.sqrt(i) if i>0 else numpy.NaN:6.4f}\" for i in tick_value]\n",
    "ax.set_xticklabels(tick_label)\n",
    "ax.set_xlabel(\"Resolution ($\\mathrm{\\AA}$)\")\n",
    "ax.set_ylabel(\"$log(\\overline{I_{bg}})$\")\n",
    "ax.set_title(f\"Wilson-like plot on frame #{frame}\")\n",
    "pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "specialized-pattern",
   "metadata": {},
   "outputs": [],
   "source": [
    "indexes = nx_data[\"index\"][frame_ptr[frame]:frame_ptr[frame+1]]\n",
    "intensities= nx_data[\"intensity\"][frame_ptr[frame]:frame_ptr[frame+1]]\n",
    "signal = numpy.zeros(size)\n",
    "norm = numpy.zeros(size)\n",
    "signal[indexes] = intensities\n",
    "norm[indexes] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "confused-cleaners",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "sparsify = nx_data.parent[\"sparsify\"]\n",
    "config = json.loads(sparsify[\"configuration/data\"][()])\n",
    "ai = pyFAI.load(config[\"geometry\"])\n",
    "engine = ai.setup_sparse_integrator(shape=ai.detector.shape,\n",
    "                      npt=resolution.size, \n",
    "                      mask=numpy.logical_not(numpy.isfinite(mask)), \n",
    "                      unit=\"d*2_nm^-2\",\n",
    "                      split='no',\n",
    "                      algo='CSR',\n",
    "                      scale=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "popular-munich",
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.sparse import csr as csr_module\n",
    "csr = csr_module.csr_matrix(engine.lut, shape=(resolution.size, size))\n",
    "csr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "severe-outreach",
   "metadata": {},
   "outputs": [],
   "source": [
    "nticks = 7\n",
    "fig, ax = subplots()\n",
    "ax.plot(radius, numpy.log(I_bg[frame]), label=\"Background\")\n",
    "tick_value = numpy.linspace(radius[0], radius[-1], nticks)\n",
    "ax.set_xticks(tick_value)\n",
    "tick_label = [f\"{10/numpy.sqrt(i) if i>0 else numpy.NaN:6.4f}\" for i in tick_value]\n",
    "ax.set_xticklabels(tick_label)\n",
    "ax.set_xlabel(\"Resolution ($\\mathrm{\\AA}$)\")\n",
    "#ax.plot(radius, numpy.log(csr.dot(signal)/csr.dot(norm)-I_bg[frame]), label=\"Peaks-Background\")\n",
    "ax.plot(radius, numpy.log(csr.dot(signal)/csr.dot(norm)), label=\"Peaks\")\n",
    "ax.set_ylabel(\"$log(\\overline{I})$\")\n",
    "ax.legend()\n",
    "ax.set_title(f\"Wilson-like plot for frame #{frame}\")\n",
    "pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ecological-press",
   "metadata": {},
   "outputs": [],
   "source": [
    "def update_plot(frame):\n",
    "    ax.set_title(f\"Wilson-like plot for frame #{frame}\")\n",
    "    ax.lines[0].set_data(radius, numpy.log(I_bg[frame]))\n",
    "    signal = numpy.zeros(size)\n",
    "    norm = numpy.zeros(size)\n",
    "    indexes = nx_data[\"index\"][frame_ptr[frame]:frame_ptr[frame+1]]\n",
    "    intensities= nx_data[\"intensity\"][frame_ptr[frame]:frame_ptr[frame+1]]\n",
    "    signal[indexes] = intensities\n",
    "    norm[indexes] = 1\n",
    "    #ax.lines[0].set_data(radius, numpy.log(csr.dot(signal)/csr.dot(norm)-I_bg[frame]))\n",
    "    ax.lines[1].set_data(radius, numpy.log(csr.dot(signal)/csr.dot(norm)))\n",
    "    return frame\n",
    "interact(update_plot, frame=widgets.IntSlider(min=0, max=len(npix)-1, step=1, value=1));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "related-rider",
   "metadata": {},
   "outputs": [],
   "source": [
    "root.close()\n",
    "print(f\"Total execution time: {time.perf_counter()-start_time:6.3f} s\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}