From 5641f0adbd9b592b3c5f6be30f45efdc00a56b09 Mon Sep 17 00:00:00 2001 From: rskoupy Date: Thu, 30 Nov 2023 18:09:59 +0100 Subject: [PATCH] Version 0.11 --- .../ptychoScopy-checkpoint.ipynb | 84 +++++++++++------- calibrations.xlsx | Bin 33365 -> 33405 bytes ptychoScopy.ipynb | 84 +++++++++++------- 3 files changed, 106 insertions(+), 62 deletions(-) diff --git a/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb b/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb index 983261e..48ada80 100644 --- a/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb +++ b/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb @@ -2,19 +2,10 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 41, "id": "7425242d-3c91-4c1e-a424-08625a38ee7a", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\skoupy_r\\Anaconda3\\lib\\site-packages\\scipy\\__init__.py:155: UserWarning: A NumPy version >=1.18.5 and <1.25.0 is required for this version of SciPy (detected version 1.26.1\n", - " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n" - ] - } - ], + "outputs": [], "source": [ "### Initial packages import ###################################################\n", "import numpy as np\n", @@ -24,7 +15,7 @@ "from pandas import read_excel\n", "from IPython.display import display\n", "from plotly.subplots import make_subplots\n", - "from ipywidgets import interactive_output, HBox, VBox, Layout, Label, Valid, ToggleButtons, RadioButtons, Dropdown, IntSlider\n", + "from ipywidgets import interactive_output, HBox, VBox, Layout, Label, Valid, ToggleButtons, RadioButtons, Dropdown, IntSlider, Checkbox\n", "\n", "# print(\"Numpy version \", np.__version__)\n", "# print(\"Pandas version \", pd.__version__)\n", @@ -307,7 +298,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 68, "id": "8055b802-cf83-4250-aea9-54e3e6b73db0", "metadata": {}, "outputs": [], @@ -333,10 +324,23 @@ "dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='Dwell time (μs)', **align, tooltips=['', ''])\n", "\n", "### Small controls ###\n", - "align2 = dict(layout=Layout(width='200px') , style = {'description_width': '100px','button_width': '50px'}, disabled=False,)\n", - "method = ToggleButtons(options=[('Direct','direct'), ('Iterative','iterative')], description='Methods', **align2, button_style='', tooltips=['SSB', 'PIE, MLc, DM'])\n", + "align2 = dict(layout=Layout(width='200px') , style = {'description_width': '100px','button_width': '100px'}, disabled=False,)\n", + "method = ToggleButtons(options=[('Direct methods','direct'), ('Iterative methods','iterative')], description='', **align2, button_style='', tooltips=['SSB', 'PIE, MLc, DM'])\n", "ctf_xaxis = RadioButtons(options=['mrad', 'A'], description='CTF-SSB x-axis:', **align2) \n", - "scans = RadioButtons(options=[4,6,8,10],description='Scan points:',continuous_update=False, **align2)\n", + "scans = RadioButtons(options=[4,6,8,10],description='Beam positions:',continuous_update=False, **align2)\n", + "\n", + "\n", + "cl_check_laa = Checkbox(value=True, description='Low angle approximation', disabled=False, indent=False,) # Low angle approximation check - scattering angle < 10 deg\n", + "cl_check_pix = Checkbox(value=True, description='Ptycho pixel < step size', disabled=False, indent=False,) # Reconstructed pixel size < scanning step size \n", + "cl_check_def = Checkbox(value=True, description='Beam fits in probe window', disabled=False, indent=False,) # Is probe window big enough to accomodate defocused probe?\n", + "cl_check_nbf = Checkbox(value=True, description='Detector cover < 1α', disabled=False, indent=False,) # Detector cover is lower than 1 α; orange\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", "\n", "### Live update ### \n", "beam_res = Label(value = f'Wavelength (pm) '+ str(\"{:.2f}\".format(pty.get_wavelength(beam.value)*1e12)), **to_right2)\n", @@ -363,10 +367,10 @@ "col3 = VBox([Label('Camera length'), cl, HBox([restriction, cl_det_res])], layout=box_layout)\n", "col4 = VBox([Label('Detection'), HBox([camera, camera_res]), pixel_size_res, binning, dwell_time, dwell_time_res], layout=box_layout)\n", "\n", - "small_control = VBox([Label('Graph controls'),method, ctf_xaxis, scans], layout = Layout(border='dashed 0px gray',margin='32px 30px 00px 10px', padding='5px 5px 5px 5px'))\n", + "small_control = VBox([Label('Graph controls'),method, ctf_xaxis, scans, VBox([Label('Camera length check list'), cl_check_laa, cl_check_pix, cl_check_def, cl_check_nbf])], layout = Layout(border='dashed 0px gray',margin='32px 30px 00px 10px', padding='5px 5px 5px 5px'))\n", "controls = HBox([VBox([Label(''), col1, col2, col3, col4]), small_control])\n", "\n", - "def ptycho_interact(beam, aperture, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, scans):\n", + "def ptycho_interact(beam, aperture, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, scans, cl_check_laa, cl_check_pix, cl_check_def, cl_check_nbf):\n", " \n", " ### SINGLE SETTING PARAMETERS ###\n", " wavelength = pty.get_wavelength(beam)*1e12\n", @@ -639,19 +643,36 @@ " for i in range(0,12):\n", " button_style = 'success'\n", " data = tab[:,int(i)] # 0. ptycho pix, 1.det cov 2.det cov a, 3.max def, 4.cl\n", - " \n", - " if data[1] > 1000*np.radians(10):\n", - " button_style = 'danger' \n", - " if data[0] > step_size_corr*10:\n", - " button_style = 'warning'\n", - " if data[3] < defocus:\n", - " button_style = 'danger'\n", - " if data[2] < 1:\n", - " button_style = 'warning' \n", + "\n", + " if cl_check_laa == True:\n", + " if data[1] > 1000*np.radians(10):\n", + " button_style = 'danger' \n", + " \n", + " if cl_check_pix == True: \n", + " if data[0] > step_size_corr*10:\n", + " button_style = 'danger'\n", + " \n", + " if cl_check_def == True: \n", + " if data[3] < defocus:\n", + " button_style = 'danger'\n", + " \n", + " if cl_check_nbf == True: \n", + " if data[2] < 1:\n", + " button_style = 'danger' \n", " \n", " dictionary[i] = ToggleButtons(options=data, description='',button_style=button_style, **align6)\n", " \n", - " legend = ToggleButtons(options=['Ptycho pix. (Å)','Det. cover (mrad)','Det. cover (α)', 'Max. defocus (nm)','Nominal CL (cm)'], description='',button_style='', **align7) \n", + " legend = ToggleButtons(options=['Ptycho pix. (Å)','Det. cover (mrad)','Det. cover (α)', 'Max. defocus (nm)','Nominal CL (cm)'], \n", + " tooltips=['Dependent on: detector, beam energy, camera length',\n", + " 'Dependent on: detector, camera length',\n", + " 'Dependent on: detector, camera length, probe semi-angle',\n", + " 'Dependent on: detector, binning, beam energy, camera length, zero defocus beam diameter, probe semi-angle',\n", + " 'Just nominal camera length',\n", + " ],button_style='', **align7) \n", + " \n", + " \n", + " \n", + " \n", " cltab = HBox([legend,dictionary[0],dictionary[1],dictionary[2],dictionary[3],dictionary[4],dictionary[5],dictionary[6],dictionary[7],dictionary[8],dictionary[9], dictionary[10],dictionary[11]])\n", " cltab = VBox([Label('Chose your reconstructed ptychographic pixe size, check needed defocus and set CL'), cltab])\n", " cltab.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 10px', padding='10px 10px 10px 10px')\n", @@ -668,7 +689,8 @@ " return \n", " \n", "gui = interactive_output(ptycho_interact, {\"beam\": beam, \"aperture\": aperture, \"probe\": probe, \"cl\": cl, \"matrix\": matrix, \"defocus\": defocus, \"mag\": mag, \"camera\": camera,\n", - " \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis, \"scans\": scans}) " + " \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis, \"scans\": scans,\n", + " \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_nbf\": cl_check_nbf}) " ] }, { @@ -701,14 +723,14 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 69, "id": "7937f054-fcd0-4e67-a20f-7696f5903a94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7cc0fdb91d0d4d51a8e99fcbc45fe1ee", + "model_id": "0d132191d4f0427aaa01278a955425f0", "version_major": 2, "version_minor": 0 }, diff --git a/calibrations.xlsx b/calibrations.xlsx index dcbc2c69465ee0e613e6411c679a3e1a1ad1892a..d3589c202a27c71d59c29439c0d12e0e0b3859a5 100644 GIT binary patch delta 15311 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.18.5 and <1.25.0 is required for this version of SciPy (detected version 1.26.1\n", - " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n" - ] - } - ], + "outputs": [], "source": [ "### Initial packages import ###################################################\n", "import numpy as np\n", @@ -24,7 +15,7 @@ "from pandas import read_excel\n", "from IPython.display import display\n", "from plotly.subplots import make_subplots\n", - "from ipywidgets import interactive_output, HBox, VBox, Layout, Label, Valid, ToggleButtons, RadioButtons, Dropdown, IntSlider\n", + "from ipywidgets import interactive_output, HBox, VBox, Layout, Label, Valid, ToggleButtons, RadioButtons, Dropdown, IntSlider, Checkbox\n", "\n", "# print(\"Numpy version \", np.__version__)\n", "# print(\"Pandas version \", pd.__version__)\n", @@ -307,7 +298,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 68, "id": "8055b802-cf83-4250-aea9-54e3e6b73db0", "metadata": {}, "outputs": [], @@ -333,10 +324,23 @@ "dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='Dwell time (μs)', **align, tooltips=['', ''])\n", "\n", "### Small controls ###\n", - "align2 = dict(layout=Layout(width='200px') , style = {'description_width': '100px','button_width': '50px'}, disabled=False,)\n", - "method = ToggleButtons(options=[('Direct','direct'), ('Iterative','iterative')], description='Methods', **align2, button_style='', tooltips=['SSB', 'PIE, MLc, DM'])\n", + "align2 = dict(layout=Layout(width='200px') , style = {'description_width': '100px','button_width': '100px'}, disabled=False,)\n", + "method = ToggleButtons(options=[('Direct methods','direct'), ('Iterative methods','iterative')], description='', **align2, button_style='', tooltips=['SSB', 'PIE, MLc, DM'])\n", "ctf_xaxis = RadioButtons(options=['mrad', 'A'], description='CTF-SSB x-axis:', **align2) \n", - "scans = RadioButtons(options=[4,6,8,10],description='Scan points:',continuous_update=False, **align2)\n", + "scans = RadioButtons(options=[4,6,8,10],description='Beam positions:',continuous_update=False, **align2)\n", + "\n", + "\n", + "cl_check_laa = Checkbox(value=True, description='Low angle approximation', disabled=False, indent=False,) # Low angle approximation check - scattering angle < 10 deg\n", + "cl_check_pix = Checkbox(value=True, description='Ptycho pixel < step size', disabled=False, indent=False,) # Reconstructed pixel size < scanning step size \n", + "cl_check_def = Checkbox(value=True, description='Beam fits in probe window', disabled=False, indent=False,) # Is probe window big enough to accomodate defocused probe?\n", + "cl_check_nbf = Checkbox(value=True, description='Detector cover < 1α', disabled=False, indent=False,) # Detector cover is lower than 1 α; orange\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", "\n", "### Live update ### \n", "beam_res = Label(value = f'Wavelength (pm) '+ str(\"{:.2f}\".format(pty.get_wavelength(beam.value)*1e12)), **to_right2)\n", @@ -363,10 +367,10 @@ "col3 = VBox([Label('Camera length'), cl, HBox([restriction, cl_det_res])], layout=box_layout)\n", "col4 = VBox([Label('Detection'), HBox([camera, camera_res]), pixel_size_res, binning, dwell_time, dwell_time_res], layout=box_layout)\n", "\n", - "small_control = VBox([Label('Graph controls'),method, ctf_xaxis, scans], layout = Layout(border='dashed 0px gray',margin='32px 30px 00px 10px', padding='5px 5px 5px 5px'))\n", + "small_control = VBox([Label('Graph controls'),method, ctf_xaxis, scans, VBox([Label('Camera length check list'), cl_check_laa, cl_check_pix, cl_check_def, cl_check_nbf])], layout = Layout(border='dashed 0px gray',margin='32px 30px 00px 10px', padding='5px 5px 5px 5px'))\n", "controls = HBox([VBox([Label(''), col1, col2, col3, col4]), small_control])\n", "\n", - "def ptycho_interact(beam, aperture, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, scans):\n", + "def ptycho_interact(beam, aperture, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, scans, cl_check_laa, cl_check_pix, cl_check_def, cl_check_nbf):\n", " \n", " ### SINGLE SETTING PARAMETERS ###\n", " wavelength = pty.get_wavelength(beam)*1e12\n", @@ -639,19 +643,36 @@ " for i in range(0,12):\n", " button_style = 'success'\n", " data = tab[:,int(i)] # 0. ptycho pix, 1.det cov 2.det cov a, 3.max def, 4.cl\n", - " \n", - " if data[1] > 1000*np.radians(10):\n", - " button_style = 'danger' \n", - " if data[0] > step_size_corr*10:\n", - " button_style = 'warning'\n", - " if data[3] < defocus:\n", - " button_style = 'danger'\n", - " if data[2] < 1:\n", - " button_style = 'warning' \n", + "\n", + " if cl_check_laa == True:\n", + " if data[1] > 1000*np.radians(10):\n", + " button_style = 'danger' \n", + " \n", + " if cl_check_pix == True: \n", + " if data[0] > step_size_corr*10:\n", + " button_style = 'danger'\n", + " \n", + " if cl_check_def == True: \n", + " if data[3] < defocus:\n", + " button_style = 'danger'\n", + " \n", + " if cl_check_nbf == True: \n", + " if data[2] < 1:\n", + " button_style = 'danger' \n", " \n", " dictionary[i] = ToggleButtons(options=data, description='',button_style=button_style, **align6)\n", " \n", - " legend = ToggleButtons(options=['Ptycho pix. (Å)','Det. cover (mrad)','Det. cover (α)', 'Max. defocus (nm)','Nominal CL (cm)'], description='',button_style='', **align7) \n", + " legend = ToggleButtons(options=['Ptycho pix. (Å)','Det. cover (mrad)','Det. cover (α)', 'Max. defocus (nm)','Nominal CL (cm)'], \n", + " tooltips=['Dependent on: detector, beam energy, camera length',\n", + " 'Dependent on: detector, camera length',\n", + " 'Dependent on: detector, camera length, probe semi-angle',\n", + " 'Dependent on: detector, binning, beam energy, camera length, zero defocus beam diameter, probe semi-angle',\n", + " 'Just nominal camera length',\n", + " ],button_style='', **align7) \n", + " \n", + " \n", + " \n", + " \n", " cltab = HBox([legend,dictionary[0],dictionary[1],dictionary[2],dictionary[3],dictionary[4],dictionary[5],dictionary[6],dictionary[7],dictionary[8],dictionary[9], dictionary[10],dictionary[11]])\n", " cltab = VBox([Label('Chose your reconstructed ptychographic pixe size, check needed defocus and set CL'), cltab])\n", " cltab.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 10px', padding='10px 10px 10px 10px')\n", @@ -668,7 +689,8 @@ " return \n", " \n", "gui = interactive_output(ptycho_interact, {\"beam\": beam, \"aperture\": aperture, \"probe\": probe, \"cl\": cl, \"matrix\": matrix, \"defocus\": defocus, \"mag\": mag, \"camera\": camera,\n", - " \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis, \"scans\": scans}) " + " \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis, \"scans\": scans,\n", + " \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_nbf\": cl_check_nbf}) " ] }, { @@ -701,14 +723,14 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 69, "id": "7937f054-fcd0-4e67-a20f-7696f5903a94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7cc0fdb91d0d4d51a8e99fcbc45fe1ee", + "model_id": "0d132191d4f0427aaa01278a955425f0", "version_major": 2, "version_minor": 0 },