Version 0.15

This commit is contained in:
rskoupy
2023-12-07 15:42:18 +01:00
parent 6fed8b93e6
commit 2a938d2b73
3 changed files with 398 additions and 350 deletions

View File

@ -2,19 +2,10 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 462,
"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",
@ -271,31 +262,23 @@
" \n",
" \n",
" def show_wavelength(self,caller):\n",
" beam_res.value = f'Wavelength (pm) {str(\"{:.2f}\".format(pty.get_wavelength(caller.new)*1e12))}'\n",
" beam_res.value = f'λ (pm) {str(\"{:.1f}\".format(pty.get_wavelength(caller.new)*1e12))}'\n",
" return beam_res.value\n",
" \n",
" def show_detector(self,caller):\n",
" camera_res.value = f'Detector full pixel array {\"{:.0f}\".format(pty.get_det_resolution(caller.new))}'\n",
" return camera_res.value\n",
" \n",
" def show_pixel_size(self,caller):\n",
" pixel_size_res.value = f'Native pixel size (μm) {\"{:.0f}\".format(pty.get_det_orig_pixel_size(caller.new))}' \n",
" return pixel_size_res.value\n",
" \n",
" def show_probe_angle(self,caller):\n",
" aperture_res.value = f'Probe semi angle (mrad) {\"{:.2f}\".format(pty.get_angle(caller.new))}' \n",
" aperture_res.value = f'Probe semi-angle (mrad) {\"{:.1f}\".format(pty.get_angle(caller.new))}' \n",
" return aperture_res.value\n",
" \n",
" def show_corrprobe_angle(self,caller):\n",
" aperture_res2.value = f'Corrected semi angle (mrad) {\"{:.2f}\".format(pty.get_angle_corr(caller.new))}'\n",
" aperture_res2.value = f'corr. {\"{:.2f}\".format(pty.get_angle_corr(caller.new))}'\n",
" return aperture_res2.value\n",
" \n",
" def show_fov(self,caller):\n",
" fov_res.value = f'Field of view (nm) {\"{:.2f}\".format(pty.get_fov(caller.new))}'\n",
" fov_res.value = f'FoV (nm) {\"{:.1f}\".format(pty.get_fov(caller.new))}'\n",
" return fov_res.value\n",
" \n",
" def show_frame_rate(self,caller):\n",
" dwell_time_res.value = f'Frame rate (kHz) {\"{:.2f}\".format(pty.get_aq_frec(caller.new))}' \n",
" dwell_time_res.value = f'Rate (kHz) {\"{:.1f}\".format(pty.get_aq_frec(caller.new))}' \n",
" return dwell_time_res.value\n",
" \n",
" def show_cd_det(self,caller):\n",
@ -308,80 +291,122 @@
},
{
"cell_type": "code",
"execution_count": 36,
"execution_count": 758,
"id": "8055b802-cf83-4250-aea9-54e3e6b73db0",
"metadata": {},
"outputs": [],
"source": [
"### CONTROLS ##########################################\n",
"align_controls = dict(layout=Layout(width='100%'),style = {'description_width': '90px','button_width': '35px'}, button_style='primary',disabled=False,)\n",
"\n",
"# align_controls = dict(layout=Layout(button_width='10%',style = {'description_width': '5%','button_width': '10%'}, button_style='primary',disabled=False,))\n",
"ali = dict(style = {'description_width': '60px','button_width': '33px'}, button_style='',disabled=False)\n",
"ali2 = dict(style = {'description_width': '60px','button_width': '90px'}, button_style='',disabled=False)\n",
"header = Button(description='STEM control panel',layout=Layout(width='auto', grid_area='header'), style=ButtonStyle(button_color='silver'))\n",
"\n",
"# to_right = dict(layout=Layout(display=\"flex\", justify_content=\"flex-end\", width=\"95%\", ))\n",
"beam_set = Button(description='Electron beam settings',layout=Layout(width='auto', grid_area='beam_set'), style=ButtonStyle(button_color='lightsteelblue')) \n",
"beam = ToggleButtons(options=opt.energies(), value=200,description='E (keV)', layout=Layout(width='auto', grid_area='beam_set1'), **ali)\n",
"aperture = ToggleButtons(options=opt.apertures(), value='30um', description='Aperture', layout=Layout(width='auto', grid_area='beam_set2'), **ali)\n",
"probe = ToggleButtons(options=opt.probes(), value='8C', description='Probe', layout=Layout(width='auto', grid_area='beam_set3'), **ali)\n",
"defocus = IntSlider(description='Δf (nm)', value=0, min=0, max=1000, step=1, continuous_update=False, layout=Layout(width='auto', grid_area='beam_set4'), **ali)\n",
"\n",
"# align_small = dict(layout=Layout(width='100%'), style = {'description_width': '60%'}, disabled=False)\n",
"# align_small2 = dict(layout=Layout(width='95%'), disabled=False)\n",
"\n",
"box_layout_controls = Layout(width='100%', border='solid 1px gray') # display='flex'\n",
"scanning_set = Button(description='Scanning parameters',layout=Layout(width='auto', grid_area='scanning_set'),style=ButtonStyle(button_color='lightsteelblue'))\n",
"mag = ToggleButtons(options=opt.magnifications(),value=3,description='Mag. Mx', layout=Layout(width='auto', grid_area='scanning_set1'), **ali)\n",
"matrix = ToggleButtons(options=opt.mappings(), value=2048, description='Matrix', layout=Layout(width='auto', grid_area='scanning_set2'), **ali)\n",
"dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='t (μs)', layout=Layout(width='auto', grid_area='scanning_set3'), **ali)\n",
"\n",
"\n",
"### Main controls ###\n",
"beam = Dropdown(options=opt.energies(),value=200,description='Energy (keV)', **align_controls)\n",
"aperture = ToggleButtons(options=opt.apertures(), value='30um', description='Aperture', **align_controls, tooltips=['', ''])\n",
"probe = ToggleButtons(options=opt.probes(), value='8C', description='Probe', **align_controls, tooltips=['', ''])\n",
"defocus = IntSlider(description='Defocus (nm)', value=0, min=0, max=1000, step=1, continuous_update=False, **align_controls )\n",
"defocus.style.handle_color = 'blue'\n",
"mag = ToggleButtons(options=opt.magnifications(),value=3,description='Mag. (Mx)', **align_controls) \n",
"matrix = ToggleButtons(options=opt.mappings(), value=2048, description='Matrix', **align_controls, tooltips=['', ''])\n",
"cl = ToggleButtons(options=opt.cameralengths(), value=12, description='Nominal (cm)', **align_controls, tooltips=['', ''])\n",
"camera = Dropdown(options=opt.detectors(), description='Detector', **align_controls, tooltips=['', ''])\n",
"restriction = ToggleButtons(options=[('No',False), ('Yes',True)], description='Use PAAR',**align_controls, tooltips=['', ''])\n",
"binning = ToggleButtons(options=[('No',1), ('2x2',2), ('4x4',4)], value=1, description='Binning', **align_controls, tooltips=['Full detector resolution', 'Binning 2x2 - detector resolution /2, pixel size *2', 'Binning 4x4'])\n",
"dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='Dwell time (μs)', **align_controls, tooltips=['', ''])\n",
"\n",
"### Small controls ###\n",
"method = ToggleButtons(options=[('SSB','direct'), ('Iterative recon.','iterative')], description='', tooltips=['SSB', 'PIE, MLc, DM'])\n",
"ctf_xaxis = RadioButtons(options=['α','mrad', 'A'], description='CTF x-axis:', ) \n",
"scans = RadioButtons(options=[4,6,8,10],description='Beam positions:',continuous_update=False,)\n",
"camera_set = Button(description='Detection',layout=Layout(width='auto', grid_area='camera_set'),style=ButtonStyle(button_color='lightsteelblue'))\n",
"cl = ToggleButtons(options=opt.cameralengths(), value=12, description='CL (cm)', layout=Layout(width='auto', grid_area='cl_set1'), **ali)\n",
"camera = ToggleButtons(options=opt.detectors(), description='Detector', layout=Layout(width='auto', grid_area='camera_set1'), **ali2)\n",
"restriction = ToggleButtons(options=[('.',False), ('..',True)], value = False, description='PAAR',icons = ['times','check'], layout=Layout(width='auto', grid_area='camera_set2'), **ali)\n",
"binning = ToggleButtons(options=[('.',1), ('2×2',2), ('4×4',4), ('6×6',6), ('8×8',8)], value=1, description='Binning', icons = ['times','',''], layout=Layout(width='auto', grid_area='camera_set3'), **ali)\n",
"\n",
"cl_check_laa = Checkbox(value=True, description='Low ∠ approx.', indent=False,) # Low angle approximation check - scattering angle < 10 deg\n",
"cl_check_pix = Checkbox(value=True, description='Rec. pix. < step',indent=False,) # Reconstructed pixel size < scanning step size \n",
"cl_check_def = Checkbox(value=True, description='Beam fits in win.', indent=False,) # Is probe window big enough to accomodate defocused probe?\n",
"cl_check_1bf = Checkbox(value=True, description='Detector cover < 1α', indent=False,) # Detector cover is lower than 1 α; orange\n",
"cl_check_nbf = Checkbox(value=True, description='Detector cover > 6α', indent=False,) # Detector cover is lower than 1 α; orange\n",
" \n",
"### Live update ### \n",
"beam_res = Label(value = f'Wavelength (pm) '+ str(\"{:.2f}\".format(pty.get_wavelength(beam.value)*1e12)), )\n",
"beam.observe(inte.show_wavelength, names='value')\n",
"camera_res = Label(value = f'Full pixel array '+ str(\"{:.0f}\".format(pty.get_det_resolution(camera.value))), )\n",
"camera.observe(inte.show_detector, names='value')\n",
"pixel_size_res = Label(value = f'Native pixel size (μm) '+ str(\"{:.0f}\".format(pty.get_det_orig_pixel_size(camera.value))),)\n",
"camera.observe(inte.show_pixel_size, names='value')\n",
"aperture_res = Label(value = f'Probe semi angle (mrad) '+ str(\"{:.2f}\".format(pty.get_angle(aperture.value))), )\n",
"aperture.observe(inte.show_probe_angle, names='value') \n",
"aperture_res2 = Label(value = f'Corrected semi angle (mrad) '+ str(\"{:.2f}\".format(pty.get_angle_corr(aperture.value))), )\n",
"beam_res = Label(value = f'λ (pm) '+ str(\"{:.1f}\".format(pty.get_wavelength(beam.value)*1e12)),layout=Layout(width='auto', grid_area='sidebar1'),)\n",
"beam.observe(inte.show_wavelength, names='value') \n",
"\n",
"aperture_res = Label(value = f'Probe semi-angle (mrad) '+ str(\"{:.1f}\".format(pty.get_angle(aperture.value))), layout=Layout(width='auto', grid_area='sidebar2'),)\n",
"aperture.observe(inte.show_probe_angle, names='value') \n",
"\n",
"aperture_res2 = Label(value = f'corr. '+ str(\"{:.2f}\".format(pty.get_angle_corr(aperture.value))),layout=Layout(width='auto', grid_area='sidebar5'),)\n",
"aperture.observe(inte.show_corrprobe_angle, names='value') \n",
"fov_res = Label(value = f'Field of view (nm) '+ str(\"{:.2f}\".format(pty.get_fov(mag.value))), )\n",
"\n",
"fov_res = Label(value = f'FoV (nm) '+ str(\"{:.1f}\".format(pty.get_fov(mag.value))),layout=Layout(width='auto', grid_area='sidebar3'),) \n",
"mag.observe(inte.show_fov, names='value') \n",
"dwell_time_res = Label(value = f'Frame rate (kHz) '+ str(\"{:.2f}\".format(pty.get_aq_frec(dwell_time.value))),)\n",
"\n",
"dwell_time_res = Label(value = f'Rate (kHz) '+ str(\"{:.1f}\".format(pty.get_aq_frec(dwell_time.value))),layout=Layout(width='auto', grid_area='sidebar4'),) \n",
"dwell_time.observe(inte.show_frame_rate, names='value') \n",
"cl_det_res = Label(value = f'Detector CL (cm) '+ str(\"{:.1f}\".format(pty.get_cl_detector(cl.value))),)\n",
"cl.observe(inte.show_cd_det, names='value') \n",
"\n",
"### Controls layout ###\n",
"col1 = VBox([Label('Beam'), beam ,beam_res, aperture, aperture_res, aperture_res2, probe, defocus], layout=box_layout_controls)\n",
"col2 = VBox([Label('Scanning'), mag, fov_res, matrix], layout=box_layout_controls)\n",
"col3 = VBox([Label('Camera length'), cl, cl_det_res, restriction ], layout=box_layout_controls)\n",
"col4 = VBox([Label('Detection'), camera, camera_res, pixel_size_res, binning, dwell_time, dwell_time_res], layout=box_layout_controls)\n",
"\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_1bf, cl_check_nbf])])\n",
"controls = HBox([VBox([Label(''), col1, col2, col3, col4]), small_control])\n",
"footer = Button(description='Footer',layout=Layout(width='auto', grid_area='footer'),style=ButtonStyle(button_color='silver'))\n",
"\n",
"\n",
"controls = GridBox(children=[header, beam_set, beam, aperture, probe, defocus, scanning_set, mag,matrix,dwell_time, cl,camera_set, camera, restriction, binning, beam_res, aperture_res,aperture_res2,fov_res, dwell_time_res,footer],\n",
" layout=Layout(\n",
" width='22%',\n",
" grid_template_rows='auto auto auto',\n",
" grid_template_columns='30% 30% 20% 20%',\n",
" grid_template_areas='''\n",
" \"header header header header\"\n",
" \"beam_set beam_set beam_set beam_set \" \n",
" \"beam_set1 beam_set1 beam_set1 beam_set1 \"\n",
" \"beam_set2 beam_set2 beam_set2 beam_set2 \"\n",
" \". sidebar2 sidebar2 sidebar5 \"\n",
" \"beam_set3 beam_set3 beam_set3 beam_set3 \"\n",
" \"beam_set4 beam_set4 beam_set4 beam_set4 \"\n",
" \"scanning_set scanning_set scanning_set scanning_set \" \n",
" \"scanning_set1 scanning_set1 scanning_set1 scanning_set1 \"\n",
" \"scanning_set2 scanning_set2 scanning_set2 scanning_set2 \"\n",
" \"scanning_set3 scanning_set3 scanning_set3 scanning_set3 \"\n",
" \"camera_set camera_set camera_set camera_set \"\n",
" \"cl_set1 cl_set1 cl_set1 cl_set1 \"\n",
" \"camera_set1 camera_set1 camera_set1 camera_set1 \"\n",
" \"camera_set3 camera_set3 camera_set3 camera_set3 \"\n",
" \"camera_set2 camera_set2 camera_set2 camera_set2 \"\n",
" ''')\n",
" )\n",
"\n",
"# SMALL CONTROLS\n",
"\n",
"\n",
"def ptycho_interact(beam, aperture, aperture_res, aperture_res2, 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_1bf, cl_check_nbf):\n",
"header = Button(description='Graph controls',layout=Layout(width='auto', grid_area='header'),style=ButtonStyle(button_color='whitesmoke'))\n",
"\n",
"method = ToggleButtons(options=[('SSB','direct'), ('Iter','iterative')], description='Method', tooltips=['SSB', 'PIE, MLc, DM'],\n",
" layout=Layout(width='auto', grid_area='methods'), style = {'description_width': descr,'button_width': butt}, button_style='',disabled=False,)\n",
"\n",
"graph_size = ToggleButtons(options=[('S', 90), ('M', 100), ('L', 120)], value=100, description='Graphs size',\n",
" layout=Layout(width='auto', grid_area='gr_size'), style = {'description_width': descr,'button_width': butt}, button_style='',disabled=False,)\n",
"\n",
"ctf_xaxis = RadioButtons(options=['α','mrad', 'A'], description='CTF x-axis:',\n",
" layout=Layout(width='auto', grid_area='ctxaxis'), style = {'description_width': descr,'button_width': butt}, disabled=False,)\n",
"\n",
"cl_check_laa = Checkbox(value=True, description='Low anlge approximation', indent=False,\n",
" layout=Layout(width='auto', grid_area='check1'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Low angle approximation check - scattering angle < 10 deg\n",
"cl_check_pix = Checkbox(value=True, description='Recon. pixel < step size',indent=False,\n",
" layout=Layout(width='auto', grid_area='check2'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Reconstructed pixel size < scanning step size \n",
"cl_check_def = Checkbox(value=True, description='Beam fits in probe window', indent=False,\n",
" layout=Layout(width='auto', grid_area='check3'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Is probe window big enough to accomodate defocused probe?\n",
"cl_check_1bf = Checkbox(value=True, description='Detector cover < 1α', indent=False,\n",
" layout=Layout(width='auto', grid_area='check4'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Detector cover is lower than 1 α\n",
"cl_check_nbf = Checkbox(value=True, description='Detector cover > 6α', indent=False,\n",
" layout=Layout(width='auto', grid_area='check5'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Detector cover is higher than 6 α\n",
"\n",
"footer = Button(description='Interactive results',layout=Layout(width='auto', grid_area='footer'),style=ButtonStyle(button_color='whitesmoke'))\n",
"\n",
"small_controls = GridBox(children=[header, method, graph_size, ctf_xaxis, cl_check_laa,cl_check_pix,cl_check_def, cl_check_1bf, cl_check_nbf, footer],\n",
" layout=Layout(\n",
" width='100%',\n",
" grid_template_rows='auto auto auto',\n",
" grid_template_columns='40% 20% 20% 20%',\n",
" grid_template_areas='''\n",
" \"header header header header \"\n",
" \"methods ctxaxis check1 check2\"\n",
" \"gr_size ctxaxis check3 check5\"\n",
" \". ctxaxis check4 . \" \n",
" \"footer footer footer footer\"\n",
" ''')\n",
" )\n",
"\n",
"\n",
"def ptycho_interact(beam, aperture, aperture_res, aperture_res2, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, cl_check_laa, cl_check_pix, cl_check_def, cl_check_1bf, cl_check_nbf, graph_size):\n",
" \n",
" ### SINGLE SETTING PARAMETERS ###\n",
" wavelength = pty.get_wavelength(beam)*1e12\n",
@ -430,12 +455,13 @@
" \n",
" \n",
" ### SAMPLE PLANE ##########################################\n",
" points = 5\n",
" yyy = np.append(np.linspace(0,overlap,100), 200)\n",
" wid = np.linspace(0,scans-1,scans) * step_size_corr\n",
" wid = np.linspace(0,points-1,points) * step_size_corr\n",
" \n",
" fig5 = make_subplots(specs=[[{\"secondary_y\": True}]])\n",
" fig5.update_xaxes(title_text=\"Sample plane (nm)\", range=[0, scans*step_size_corr], showgrid=False, zeroline=False)\n",
" fig5.update_yaxes(range=[0, scans*step_size_corr],showgrid=False, showticklabels=False)\n",
" fig5.update_xaxes(title_text=\"Sample plane (nm)\", range=[0, points*step_size_corr], showgrid=False, zeroline=False)\n",
" fig5.update_yaxes(range=[0, points*step_size_corr],showgrid=False, showticklabels=False)\n",
" for x in range(len(wid)):\n",
" fig5.add_trace(go.Scatter(showlegend=False, x=wid, y=np.ones(len(wid))*wid[x], marker_color='blue'),secondary_y=False)\n",
" for x in range(len(wid)): \n",
@ -443,16 +469,21 @@
" fig5.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.1, fillcolor=\"#FF7F7F\",name=False, x0=wid[x]-beam_diameter/2, y0=wid[y]-beam_diameter/2, x1=wid[x]+beam_diameter/2, y1=wid[y]+beam_diameter/2, line_color=\"red\",secondary_y=False)\n",
"\n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='blue', name='Step '+str(np.round(10*step_size,3))+' Å ('+str(np.round(10*step_size_corr,3))+')'))\n",
" if method == 'direct':\n",
" xx = 2*wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='green', name='Rec step '+str(np.round(xx[-1]/3,2))+' Å')) \n",
" \n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='#FF7F7F', name='Beam ⌀ '+ str(np.round(10*beam_diameter,2))+\" Å\"))\n",
" fig5.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.85,xanchor=\"right\",x=0.9))\n",
" fig5.add_trace(go.Scatter(showlegend=False, x = scans*step_size_corr*np.ones(len(yyy)), y=yyy, opacity=1,mode='markers',marker_symbol = \"triangle-down\",marker=dict(size=20, color=yyy, colorscale='rainbow_r', showscale=False)),secondary_y=True) \n",
" \n",
" \n",
" fig5.add_trace(go.Scatter(showlegend=False, x = points*step_size_corr*np.ones(len(yyy)), y=yyy, opacity=1,mode='markers',marker_symbol = \"triangle-down\",marker=dict(size=20, color=yyy, colorscale='rainbow_r', showscale=False)),secondary_y=True) \n",
" fig5.update_yaxes(title_text=\"Overlap %\", range=[0, 100],showgrid=False, showticklabels=True, tickvals = [0, 20, 40,50, 60,70, 80, 90, 100], secondary_y=True)\n",
" fig5.update_layout(title={'text': \"Sample\",'y':0.95, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig5.update_layout(width=350, height=300, margin =dict(l=30, r=30, t=10, b=0))\n",
" fig5.update_layout(title={'text': \"Sample\",'y':0.95, 'x':0.30,'xanchor': 'left','yanchor': 'top'})\n",
" fig5.update_layout(width=4.5*graph_size, height=3.0*graph_size, margin =dict(l=1.3*graph_size, r=0.3*graph_size, t=0.1*graph_size, b=0))\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" ### DETECTOR PLANE ##########################################\n",
" fig6 = go.Figure() \n",
" fig6.update_xaxes(title_text=\"Pixels\", range=[1, num_pixels], zeroline=False)\n",
@ -466,11 +497,15 @@
" fig6.add_annotation(x=num_pixels/2+beam_diameter_pix/2,y=num_pixels/2, ax=num_pixels/2-beam_diameter_pix/2, ay=num_pixels/2, xref='x',yref='y',axref='x',ayref='y', text='', showarrow=True,arrowhead=3,arrowsize=1,arrowwidth=1,arrowcolor='black')\n",
" fig6.add_annotation(x=num_pixels/2, y=num_pixels/2, text=str(np.round(beam_diameter_pix,1))+\" pix\", showarrow=False, yshift=10)\n",
" fig6.add_trace(go.Scatter(x=[1,1.5,1,1.5], y=[1,1,1.5,1.5], name='Pix ∠ ' +str(np.round(pixel_angle,2))+' mrad'))\n",
" fig6.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.85,xanchor=\"right\",x=1))\n",
" # fig6.update_layout(title={'text': \"Detector\",'y':0.925, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig6.add_trace(go.Scatter(x=[1,1.5,1,1.5], y=[1,1,1.5,1.5], name='Pixel size ' +str(np.round(size_pixel,2))+' um'))\n",
" fig6.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.80,xanchor=\"right\",x=1))\n",
" fig6.update_layout(title={'text': \"Detector\",'y':0.95, 'x':0.11,'xanchor': 'left','yanchor': 'top'})\n",
" fig6.update_layout(xaxis = dict(tickmode = 'array', tickvals = [1, num_pixels/4, num_pixels/2, 3*num_pixels/4, num_pixels])) \n",
" fig6.update_layout(width=250, height=230, margin = dict(l=20, r=20, t=0, b=0))\n",
" fig6.update_layout(width=3.5*graph_size, height=3*graph_size, margin = dict(l=0.35*graph_size, r=0.65*graph_size, t=0.3*graph_size, b=0))\n",
"\n",
" \n",
" \n",
" \n",
" focusdepth = wavelength/(semi_angle_corr/1000)**2/1000\n",
" ssb_cl, kolik = pty.cl4ssb(detector_cover_a_all)\n",
" ### MICROSCOPE SCHEME ##########################################\n",
@ -487,12 +522,17 @@
" fig8.add_trace(go.Scatter(showlegend=False, x=[-150, -2*semi_angle, None, 2*semi_angle, 150], y=[reduc*0.8*y_down,reduc*0.8*y_down,None,reduc*0.8*y_down, reduc*0.8*y_down],mode='lines', line=dict(color='black',width=7)))\n",
" fig8.add_annotation(x=-0.7*width, y=reduc*0.8*y_down, text=\"<b>Aperture </b>\", showarrow=False, yshift=2)\n",
" fig8.add_annotation(x=-0.7*width, y=reduc*0.8*y_down, text=str(aperture), showarrow=False, yshift=-15)\n",
" fig8.add_annotation(x=0.0*width, y=-y_down,text='Acquisition time (s) '+ str(np.round(matrix*matrix*dwell_time/1e6,1)), showarrow=False, yshift=-10)\n",
" fig8.add_annotation(x=0, y=reduc*0.96*y_down,text='λ (pm) '+ str(np.round((pty.get_wavelength(beam)*1e12),2)), showarrow=False, yshift=0)\n",
" \n",
" \n",
" \n",
" \n",
" if defocus > 0:\n",
" defo = np.log(defocus)/100\n",
" else:\n",
" defo = 0 \n",
"\n",
" \n",
" # Beam\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, 2*semi_angle, 0, 0], y=[defo*y_down, reduc*0.8*y_down, reduc*0.8*y_down, defo*y_down], mode='lines',fill=\"toself\", fillcolor=\"#FF7F7F\", opacity=0.7,line=dict(color='#FF7F7F',width=1)))\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, 0, -2*semi_angle, 0], y=[defo*y_down, reduc*0.8*y_down, reduc*0.8*y_down, defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"red\", opacity=0.7,line=dict(color='red',width=1)))\n",
@ -508,14 +548,14 @@
" fig8.add_annotation(x=-0.7*width, y=0,text=\"<b>Sample</b>\", showarrow=False, yshift=15)\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-np.log(fov)/20*width, np.log(fov)/20*width, np.log(fov)/20*width, -np.log(fov)/20*width, -np.log(fov)/20*width], y=[-0.01*y_down, -0.01*y_down, 0.01*y_down, 0.01*y_down, -0.01*y_down],mode='lines', fill=\"toself\", fillcolor=\"black\", line=dict(color='black',width=1), opacity=0.5))\n",
" fig8.add_annotation(x=0.4*width, y=0.05*y_down,text=\"FoV \"+str(np.round(fov,2))+\" nm\", showarrow=False, yshift=0)\n",
" fig8.add_annotation(x=0.5*width, y=0.05*y_down,text=\"Dose \"+str(np.round(dose,1))+\" e/Å2\", showarrow=False, yshift=-30)\n",
" fig8.add_annotation(x=-0.5*width, y=0.05*y_down,text=\"DoF \"+str(np.round(focusdepth,1))+\" nm\", showarrow=False, yshift=-30)\n",
" fig8.add_annotation(x=0.5*width, y=0.05*y_down,text=\"Dose \"+str(np.round(dose,1))+\" e/Å2\", showarrow=False, yshift=-40)\n",
" fig8.add_annotation(x=-0.5*width, y=0.05*y_down,text=\"DoF \"+str(np.round(focusdepth,1))+\" nm\", showarrow=False, yshift=-40)\n",
" # Detector\n",
" y = -np.log(cl)*np.ones(int(num_pixels)+1)\n",
" x = np.linspace(-det_width,det_width, int(num_pixels)+1)\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=x, y=y, mode='markers', marker_symbol=\"line-ns\",marker_line_width=0.5))\n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(cl),text=\"<b>Detector</b>\", showarrow=False,align= 'left', yshift=15)\n",
" \n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(cl),text=str(np.round(cl_det,2))+' cm', showarrow=False,align= 'left', yshift=-15) \n",
" # Scattering\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, det_width, -det_width, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"gray\", opacity=0.1,line=dict(color='black',width=1)))\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, -det_width, det_width, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"gray\", opacity=0.1,line=dict(color='black',width=1)))\n",
@ -524,7 +564,7 @@
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, -det_width/covered_alfas, det_width/covered_alfas, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"red\", opacity=0.7,line=dict(color='#FF7F7F',width=1)))\n",
" \n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-width, width], y=[-np.log(ssb_cl), -np.log(ssb_cl)], opacity=0.8, line=dict(color='green',width=3)))\n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(ssb_cl),text=\"<b>for SSB</b>\", showarrow=False,align= 'left', yshift=-15)\n",
" fig8.add_annotation(x=0*width, y=-np.log(ssb_cl),text=\"<b></b>\", showarrow=False,align= 'left', yshift=15)\n",
" \n",
" if restriction == True:\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-250, -4*semi_angle, None, 4*semi_angle, 250], y=[-reduc*0.2*y_down,-reduc*0.2*y_down,None,-reduc*0.2*y_down, -reduc*0.2*y_down],mode='lines', line=dict(color='black',width=7)))\n",
@ -540,26 +580,20 @@
" for x in opt.cameralengths():\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-width, width], y=[-np.log(x), -np.log(x)], opacity=0.3, line=dict(color='gray',width=1)))\n",
" fig8.add_annotation(x=0.9*width, y=-np.log(x),text=str(x), showarrow=False, yshift=8)\n",
"\n",
" \n",
" fig8.update_xaxes(title_text=\"\")\n",
" # fig8.update_layout(title={'text': \"Microscope\" ,'y':1, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig8.update_layout(width=250, height=570, margin = dict(l=0, r=0, t=20, b=0))\n",
" fig8.update_layout(width=3.0*graph_size, height=7.2*graph_size, margin = dict(l=0, r=0, t=0.2*graph_size, b=0))\n",
" fig8.update_layout(plot_bgcolor='white')\n",
" \n",
" \n",
" ### FINAL CHECKS ########################################## \n",
" align3 = dict(layout=Layout(width='200px') , style = {'description_width': '150px','button_width': \"100px\"}, disabled=True,) \n",
" align_check = dict(layout=Layout(width='200px') , style = {'description_width': '150px','button_width': \"50px\"}, disabled=True,) \n",
" check1 = Valid(value= bool(overlap > 60), description='Overlap > 60 %', **align_check)\n",
" check2 = Valid(value= bool(step_size_corr*10 > (wavelength * cl_det)/(num_pixels*size_pixel/1e6)/1e4), description='Ptycho pix < step size', **align_check)\n",
" check3 = Valid(value= bool(beam_diameter/2 < probe_window/2), description='Beam ⌀ < window/2', **align_check) \n",
" \n",
" check1 = Valid(value= bool(overlap > 60), description='Overlap > 60 %', **align3)\n",
" check2 = Valid(value= bool(step_size_corr*10 > (wavelength * cl_det)/(num_pixels*size_pixel/1e6)/1e4), description='Ptycho pix < step size', **align3)\n",
" check3 = Valid(value= bool(beam_diameter/2 < probe_window/2), description='Beam ⌀ < window/2', **align3) \n",
" \n",
" acquisition_time = Label(value = f'Acquisition time (s) '+ str(np.round(matrix*matrix*dwell_time/1e6,1)), **align3) \n",
"\n",
"\n",
"\n",
" \n",
" \n",
" \n",
" ### METHODS ########################################## \n",
" if method == 'direct':\n",
@ -587,21 +621,19 @@
" fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf, marker_color='gray', name='SSB-CTF',))\n",
"\n",
" fig.add_trace(go.Scatter(x=xx, y=pctf, marker_color='red', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n",
" fig.update_xaxes(title_text=\"Real space distance (Å)\", range=[-0.5, 2.5], type=\"log\", zeroline=False)\n",
" fig.update_xaxes(title_text=\"Real space distance (Å)\", range=[-0.2, 2.5], type=\"log\", zeroline=False)\n",
"\n",
" fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.75,xanchor=\"right\",x=1))\n",
" # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig.update_layout(width=600, height=225, margin = dict(l=100, r=30, t=30, b=30))\n",
" fig.update_layout(width=7.65*graph_size, height=2.25*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
" \n",
" \n",
" ssb_sampling = Label(value = f'Recommended sampling (Å) '+ str(np.round(xx[-1]/3,2)), **align3) \n",
" \n",
" ### CAMERA LENGTH GRAPH ##########################################\n",
" fig4 = make_subplots(specs=[[{\"secondary_y\": True}]])\n",
" fig4.add_trace(go.Scatter(showlegend=False, x=opt.cameralengths(), y=detector_cover_all, marker_color='gray'), secondary_y=False,)\n",
" fig4.add_trace(go.Scatter(showlegend=False, x=opt.cameralengths(), y=detector_cover_a_all,marker_color='gray'), secondary_y=True,)\n",
" fig4.add_trace(go.Scatter(x=np.array(cl), y=np.array(covered_alfas), marker_size=12, marker_color='red', name = str(np.round(detector_cover,1))+ \" mrad; \"+str(np.round(covered_alfas,2))+ \" α\"), secondary_y=True,) \n",
" fig4.add_trace(go.Scatter(x=np.array(ssb_cl), y=np.array(kolik),marker_size=12, marker_color='green', name = \"Rec SSB CL\"), secondary_y=True,) \n",
" fig4.add_trace(go.Scatter(x=np.array(ssb_cl), y=np.array(kolik),marker_size=12, marker_color='green', name = \"Recommended CL\"), secondary_y=True,) \n",
" fig4.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.65,xanchor=\"right\",x=0.9))\n",
" # fig4.update_layout(title={'text': \"CL to α\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig4.update_xaxes(title_text=\"Nominal camera length (cm)\", type=\"log\", tickvals = opt.cameralengths())\n",
@ -609,26 +641,23 @@
" fig4.update_yaxes(title_text=\" Cover angle (mrad)\", range=[0, 1.1*np.max(detector_cover_all)], secondary_y=False)\n",
" fig4.update_yaxes(title_text=\" Cover angle (α)\", range=[0, 1.1*np.max(detector_cover_a_all)], showgrid=False, secondary_y=True)\n",
" fig4.update_layout(xaxis = dict(tickmode = 'array', tickvals = opt.cameralengths()))\n",
" fig4.update_layout(width=600, height=225, margin =dict(l=110, r=30, t=30, b=30))\n",
" \n",
" \n",
" checks = VBox([Label('Final checks'), ssb_sampling, acquisition_time]) \n",
" checks.layout = Layout(border='dashed 1px gray',margin='30px 5px 5px 5px', padding='10px 10px 10px 10px')\n",
" \n",
" \n",
" fig4.update_layout(width=8.0*graph_size, height=2.25*graph_size, margin =dict(l=1.3*graph_size, r=0.25*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
"\n",
" ### SHOWING ###\n",
" right_column = VBox([go.FigureWidget(fig),HBox([go.FigureWidget(fig5),go.FigureWidget(fig6)]),go.FigureWidget(fig4)])\n",
" left_column = VBox([go.FigureWidget(fig8)])\n",
" \n",
"\n",
" \n",
" right_column = VBox([go.FigureWidget(fig),go.FigureWidget(fig5),go.FigureWidget(fig4),checks])\n",
" left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)])\n",
" \n",
"\n",
" \n",
" display(HBox([left_column, right_column]))\n",
" \n",
" \n",
" \n",
" \n",
" total = HBox([left_column, right_column])\n",
" total.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 40px', padding='10px 10px 10px 10px')\n",
" \n",
" display(total)\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" if method == 'iterative': \n",
" \n",
@ -670,14 +699,10 @@
"\n",
" fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.75,xanchor=\"right\",x=1))\n",
" # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig.update_layout(width=600, height=225, margin = dict(l=110, r=30, t=30, b=30))\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" checks = VBox([Label('Final checks'),check1, check2, check3, acquisition_time]) \n",
" checks.layout = Layout(border='dashed 1px gray',margin='30px 5px 5px 5px', padding='10px 10px 10px 10px')\n",
" fig.update_layout(width=7.65*graph_size, height=2.25*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
" \n",
" checks = VBox([Label('Final checks'),check1, check2, check3]) \n",
" checks.layout = Layout(border='dashed 1px gray', margin='30px 0px 50px 40px', padding='5px 5px 5px 5px')\n",
" \n",
" \n",
" ### PROBE WINDOW ##########################################\n",
@ -701,14 +726,14 @@
" fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n",
" fig7.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.9,xanchor=\"right\",x=1))\n",
" fig7.update_layout(title={'text': \"Probe window \",'y':0.925, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig7.update_layout(width=320, height=300, margin =dict(l=30, r=30, t=10, b=0)) \n",
" fig7.update_layout(width=3.2*graph_size, height=3.0*graph_size, margin =dict(l=0.3*graph_size, r=0.3*graph_size, t=0.1*graph_size, b=0)) \n",
" \n",
" ### CAMERA LENGTH TABLE ########################################## \n",
" dictionary = {}\n",
" tab = np.array([np.round(ptycho_pixel_size_all,2),np.round(detector_cover_all,1), np.round(detector_cover_a_all,1), np.round(max_defocus_all,1), opt.cameralengths()])\n",
"\n",
" align6 = dict(layout=Layout(width='50px') , style = {'description_width': '0px','button_width': \"33px\"}, disabled=True,)\n",
" align7 = dict(layout=Layout(width='120px') , style = {'description_width': '0px','button_width': \"105px\"}, disabled=True,)\n",
" align6 = dict(layout=Layout(width=str(int(graph_size/100*62))+'px') , style = {'description_width': '0px','button_width': str(int(graph_size/100*40))+'px'}, disabled=True,)\n",
" align7 = dict(layout=Layout(width='140px') , style = {'description_width': '0px','button_width': \"120px\"}, disabled=True,)\n",
" \n",
" for i in range(0,12):\n",
" button_style = 'success'\n",
@ -756,22 +781,26 @@
" \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",
" cltab.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 110px', padding='10px 10px 10px 10px')\n",
" \n",
" \n",
" \n",
" ### SHOWING ###\n",
" sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n",
" right_column = VBox([go.FigureWidget(fig), sample_overlap, cltab, checks ]) \n",
" left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)]) \n",
" sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7), go.FigureWidget(fig6)]) \n",
" right_column = VBox([HBox([go.FigureWidget(fig),checks]), sample_overlap, cltab]) \n",
" left_column = VBox([go.FigureWidget(fig8)]) \n",
" \n",
" display(HBox([left_column, right_column]))\n",
" \n",
" total = HBox([left_column, right_column])\n",
" total.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 40px', padding='10px 10px 10px 10px')\n",
" \n",
" display(total)\n",
" \n",
" return \n",
" \n",
"gui = interactive_output(ptycho_interact, {\"beam\": beam, \"aperture\": aperture,\"aperture_res\": aperture_res,\"aperture_res2\": aperture_res2, \"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,\n",
" \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_1bf\": cl_check_1bf, \"cl_check_nbf\": cl_check_nbf}) \n",
" \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis,\n",
" \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_1bf\": cl_check_1bf, \"cl_check_nbf\": cl_check_nbf, \"graph_size\": graph_size}) \n",
"\n"
]
},
@ -805,19 +834,19 @@
},
{
"cell_type": "code",
"execution_count": 37,
"execution_count": 759,
"id": "7937f054-fcd0-4e67-a20f-7696f5903a94",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1e35fd918b334d70b6eca967055cf6ce",
"model_id": "164f877a365543aea26b5fecf9a80a1c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HBox(children=(VBox(children=(Label(value=''), VBox(children=(Label(value='Beam'), Dropdown(des…"
"HBox(children=(GridBox(children=(Button(description='STEM control panel', layout=Layout(grid_area='header', wi…"
]
},
"metadata": {},
@ -825,35 +854,9 @@
}
],
"source": [
"\n",
"\n",
"display(HBox([controls, gui]))"
"display(HBox([controls, VBox([small_controls, gui]) ]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79e73498-4e48-4617-9085-95b6c01597c9",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "0661a5fa-f65c-45cf-a6f4-39d1f9f186cd",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ba255a1-e209-4107-8a8f-0a1cac8cce90",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
@ -874,6 +877,27 @@
"# import ipywidgets\n",
"# print(\"Ipywidgets version \", ipywidgets.__version__)"
]
},
{
"cell_type": "code",
"execution_count": 736,
"id": "df751153-70c4-47a8-801c-3a96d813399e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'55px'"
]
},
"execution_count": 752,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"str(int(graph_size.value/100*62))+'px'"
]
}
],
"metadata": {

Binary file not shown.

View File

@ -2,19 +2,10 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 462,
"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",
@ -271,31 +262,23 @@
" \n",
" \n",
" def show_wavelength(self,caller):\n",
" beam_res.value = f'Wavelength (pm) {str(\"{:.2f}\".format(pty.get_wavelength(caller.new)*1e12))}'\n",
" beam_res.value = f'λ (pm) {str(\"{:.1f}\".format(pty.get_wavelength(caller.new)*1e12))}'\n",
" return beam_res.value\n",
" \n",
" def show_detector(self,caller):\n",
" camera_res.value = f'Detector full pixel array {\"{:.0f}\".format(pty.get_det_resolution(caller.new))}'\n",
" return camera_res.value\n",
" \n",
" def show_pixel_size(self,caller):\n",
" pixel_size_res.value = f'Native pixel size (μm) {\"{:.0f}\".format(pty.get_det_orig_pixel_size(caller.new))}' \n",
" return pixel_size_res.value\n",
" \n",
" def show_probe_angle(self,caller):\n",
" aperture_res.value = f'Probe semi angle (mrad) {\"{:.2f}\".format(pty.get_angle(caller.new))}' \n",
" aperture_res.value = f'Probe semi-angle (mrad) {\"{:.1f}\".format(pty.get_angle(caller.new))}' \n",
" return aperture_res.value\n",
" \n",
" def show_corrprobe_angle(self,caller):\n",
" aperture_res2.value = f'Corrected semi angle (mrad) {\"{:.2f}\".format(pty.get_angle_corr(caller.new))}'\n",
" aperture_res2.value = f'corr. {\"{:.2f}\".format(pty.get_angle_corr(caller.new))}'\n",
" return aperture_res2.value\n",
" \n",
" def show_fov(self,caller):\n",
" fov_res.value = f'Field of view (nm) {\"{:.2f}\".format(pty.get_fov(caller.new))}'\n",
" fov_res.value = f'FoV (nm) {\"{:.1f}\".format(pty.get_fov(caller.new))}'\n",
" return fov_res.value\n",
" \n",
" def show_frame_rate(self,caller):\n",
" dwell_time_res.value = f'Frame rate (kHz) {\"{:.2f}\".format(pty.get_aq_frec(caller.new))}' \n",
" dwell_time_res.value = f'Rate (kHz) {\"{:.1f}\".format(pty.get_aq_frec(caller.new))}' \n",
" return dwell_time_res.value\n",
" \n",
" def show_cd_det(self,caller):\n",
@ -308,80 +291,122 @@
},
{
"cell_type": "code",
"execution_count": 36,
"execution_count": 758,
"id": "8055b802-cf83-4250-aea9-54e3e6b73db0",
"metadata": {},
"outputs": [],
"source": [
"### CONTROLS ##########################################\n",
"align_controls = dict(layout=Layout(width='100%'),style = {'description_width': '90px','button_width': '35px'}, button_style='primary',disabled=False,)\n",
"\n",
"# align_controls = dict(layout=Layout(button_width='10%',style = {'description_width': '5%','button_width': '10%'}, button_style='primary',disabled=False,))\n",
"ali = dict(style = {'description_width': '60px','button_width': '33px'}, button_style='',disabled=False)\n",
"ali2 = dict(style = {'description_width': '60px','button_width': '90px'}, button_style='',disabled=False)\n",
"header = Button(description='STEM control panel',layout=Layout(width='auto', grid_area='header'), style=ButtonStyle(button_color='silver'))\n",
"\n",
"# to_right = dict(layout=Layout(display=\"flex\", justify_content=\"flex-end\", width=\"95%\", ))\n",
"beam_set = Button(description='Electron beam settings',layout=Layout(width='auto', grid_area='beam_set'), style=ButtonStyle(button_color='lightsteelblue')) \n",
"beam = ToggleButtons(options=opt.energies(), value=200,description='E (keV)', layout=Layout(width='auto', grid_area='beam_set1'), **ali)\n",
"aperture = ToggleButtons(options=opt.apertures(), value='30um', description='Aperture', layout=Layout(width='auto', grid_area='beam_set2'), **ali)\n",
"probe = ToggleButtons(options=opt.probes(), value='8C', description='Probe', layout=Layout(width='auto', grid_area='beam_set3'), **ali)\n",
"defocus = IntSlider(description='Δf (nm)', value=0, min=0, max=1000, step=1, continuous_update=False, layout=Layout(width='auto', grid_area='beam_set4'), **ali)\n",
"\n",
"# align_small = dict(layout=Layout(width='100%'), style = {'description_width': '60%'}, disabled=False)\n",
"# align_small2 = dict(layout=Layout(width='95%'), disabled=False)\n",
"\n",
"box_layout_controls = Layout(width='100%', border='solid 1px gray') # display='flex'\n",
"scanning_set = Button(description='Scanning parameters',layout=Layout(width='auto', grid_area='scanning_set'),style=ButtonStyle(button_color='lightsteelblue'))\n",
"mag = ToggleButtons(options=opt.magnifications(),value=3,description='Mag. Mx', layout=Layout(width='auto', grid_area='scanning_set1'), **ali)\n",
"matrix = ToggleButtons(options=opt.mappings(), value=2048, description='Matrix', layout=Layout(width='auto', grid_area='scanning_set2'), **ali)\n",
"dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='t (μs)', layout=Layout(width='auto', grid_area='scanning_set3'), **ali)\n",
"\n",
"\n",
"### Main controls ###\n",
"beam = Dropdown(options=opt.energies(),value=200,description='Energy (keV)', **align_controls)\n",
"aperture = ToggleButtons(options=opt.apertures(), value='30um', description='Aperture', **align_controls, tooltips=['', ''])\n",
"probe = ToggleButtons(options=opt.probes(), value='8C', description='Probe', **align_controls, tooltips=['', ''])\n",
"defocus = IntSlider(description='Defocus (nm)', value=0, min=0, max=1000, step=1, continuous_update=False, **align_controls )\n",
"defocus.style.handle_color = 'blue'\n",
"mag = ToggleButtons(options=opt.magnifications(),value=3,description='Mag. (Mx)', **align_controls) \n",
"matrix = ToggleButtons(options=opt.mappings(), value=2048, description='Matrix', **align_controls, tooltips=['', ''])\n",
"cl = ToggleButtons(options=opt.cameralengths(), value=12, description='Nominal (cm)', **align_controls, tooltips=['', ''])\n",
"camera = Dropdown(options=opt.detectors(), description='Detector', **align_controls, tooltips=['', ''])\n",
"restriction = ToggleButtons(options=[('No',False), ('Yes',True)], description='Use PAAR',**align_controls, tooltips=['', ''])\n",
"binning = ToggleButtons(options=[('No',1), ('2x2',2), ('4x4',4)], value=1, description='Binning', **align_controls, tooltips=['Full detector resolution', 'Binning 2x2 - detector resolution /2, pixel size *2', 'Binning 4x4'])\n",
"dwell_time = ToggleButtons(options=opt.dwelltimes(), value=10, description='Dwell time (μs)', **align_controls, tooltips=['', ''])\n",
"\n",
"### Small controls ###\n",
"method = ToggleButtons(options=[('SSB','direct'), ('Iterative recon.','iterative')], description='', tooltips=['SSB', 'PIE, MLc, DM'])\n",
"ctf_xaxis = RadioButtons(options=['α','mrad', 'A'], description='CTF x-axis:', ) \n",
"scans = RadioButtons(options=[4,6,8,10],description='Beam positions:',continuous_update=False,)\n",
"camera_set = Button(description='Detection',layout=Layout(width='auto', grid_area='camera_set'),style=ButtonStyle(button_color='lightsteelblue'))\n",
"cl = ToggleButtons(options=opt.cameralengths(), value=12, description='CL (cm)', layout=Layout(width='auto', grid_area='cl_set1'), **ali)\n",
"camera = ToggleButtons(options=opt.detectors(), description='Detector', layout=Layout(width='auto', grid_area='camera_set1'), **ali2)\n",
"restriction = ToggleButtons(options=[('.',False), ('..',True)], value = False, description='PAAR',icons = ['times','check'], layout=Layout(width='auto', grid_area='camera_set2'), **ali)\n",
"binning = ToggleButtons(options=[('.',1), ('2×2',2), ('4×4',4), ('6×6',6), ('8×8',8)], value=1, description='Binning', icons = ['times','',''], layout=Layout(width='auto', grid_area='camera_set3'), **ali)\n",
"\n",
"cl_check_laa = Checkbox(value=True, description='Low ∠ approx.', indent=False,) # Low angle approximation check - scattering angle < 10 deg\n",
"cl_check_pix = Checkbox(value=True, description='Rec. pix. < step',indent=False,) # Reconstructed pixel size < scanning step size \n",
"cl_check_def = Checkbox(value=True, description='Beam fits in win.', indent=False,) # Is probe window big enough to accomodate defocused probe?\n",
"cl_check_1bf = Checkbox(value=True, description='Detector cover < 1α', indent=False,) # Detector cover is lower than 1 α; orange\n",
"cl_check_nbf = Checkbox(value=True, description='Detector cover > 6α', indent=False,) # Detector cover is lower than 1 α; orange\n",
" \n",
"### Live update ### \n",
"beam_res = Label(value = f'Wavelength (pm) '+ str(\"{:.2f}\".format(pty.get_wavelength(beam.value)*1e12)), )\n",
"beam.observe(inte.show_wavelength, names='value')\n",
"camera_res = Label(value = f'Full pixel array '+ str(\"{:.0f}\".format(pty.get_det_resolution(camera.value))), )\n",
"camera.observe(inte.show_detector, names='value')\n",
"pixel_size_res = Label(value = f'Native pixel size (μm) '+ str(\"{:.0f}\".format(pty.get_det_orig_pixel_size(camera.value))),)\n",
"camera.observe(inte.show_pixel_size, names='value')\n",
"aperture_res = Label(value = f'Probe semi angle (mrad) '+ str(\"{:.2f}\".format(pty.get_angle(aperture.value))), )\n",
"aperture.observe(inte.show_probe_angle, names='value') \n",
"aperture_res2 = Label(value = f'Corrected semi angle (mrad) '+ str(\"{:.2f}\".format(pty.get_angle_corr(aperture.value))), )\n",
"beam_res = Label(value = f'λ (pm) '+ str(\"{:.1f}\".format(pty.get_wavelength(beam.value)*1e12)),layout=Layout(width='auto', grid_area='sidebar1'),)\n",
"beam.observe(inte.show_wavelength, names='value') \n",
"\n",
"aperture_res = Label(value = f'Probe semi-angle (mrad) '+ str(\"{:.1f}\".format(pty.get_angle(aperture.value))), layout=Layout(width='auto', grid_area='sidebar2'),)\n",
"aperture.observe(inte.show_probe_angle, names='value') \n",
"\n",
"aperture_res2 = Label(value = f'corr. '+ str(\"{:.2f}\".format(pty.get_angle_corr(aperture.value))),layout=Layout(width='auto', grid_area='sidebar5'),)\n",
"aperture.observe(inte.show_corrprobe_angle, names='value') \n",
"fov_res = Label(value = f'Field of view (nm) '+ str(\"{:.2f}\".format(pty.get_fov(mag.value))), )\n",
"\n",
"fov_res = Label(value = f'FoV (nm) '+ str(\"{:.1f}\".format(pty.get_fov(mag.value))),layout=Layout(width='auto', grid_area='sidebar3'),) \n",
"mag.observe(inte.show_fov, names='value') \n",
"dwell_time_res = Label(value = f'Frame rate (kHz) '+ str(\"{:.2f}\".format(pty.get_aq_frec(dwell_time.value))),)\n",
"\n",
"dwell_time_res = Label(value = f'Rate (kHz) '+ str(\"{:.1f}\".format(pty.get_aq_frec(dwell_time.value))),layout=Layout(width='auto', grid_area='sidebar4'),) \n",
"dwell_time.observe(inte.show_frame_rate, names='value') \n",
"cl_det_res = Label(value = f'Detector CL (cm) '+ str(\"{:.1f}\".format(pty.get_cl_detector(cl.value))),)\n",
"cl.observe(inte.show_cd_det, names='value') \n",
"\n",
"### Controls layout ###\n",
"col1 = VBox([Label('Beam'), beam ,beam_res, aperture, aperture_res, aperture_res2, probe, defocus], layout=box_layout_controls)\n",
"col2 = VBox([Label('Scanning'), mag, fov_res, matrix], layout=box_layout_controls)\n",
"col3 = VBox([Label('Camera length'), cl, cl_det_res, restriction ], layout=box_layout_controls)\n",
"col4 = VBox([Label('Detection'), camera, camera_res, pixel_size_res, binning, dwell_time, dwell_time_res], layout=box_layout_controls)\n",
"\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_1bf, cl_check_nbf])])\n",
"controls = HBox([VBox([Label(''), col1, col2, col3, col4]), small_control])\n",
"footer = Button(description='Footer',layout=Layout(width='auto', grid_area='footer'),style=ButtonStyle(button_color='silver'))\n",
"\n",
"\n",
"controls = GridBox(children=[header, beam_set, beam, aperture, probe, defocus, scanning_set, mag,matrix,dwell_time, cl,camera_set, camera, restriction, binning, beam_res, aperture_res,aperture_res2,fov_res, dwell_time_res,footer],\n",
" layout=Layout(\n",
" width='22%',\n",
" grid_template_rows='auto auto auto',\n",
" grid_template_columns='30% 30% 20% 20%',\n",
" grid_template_areas='''\n",
" \"header header header header\"\n",
" \"beam_set beam_set beam_set beam_set \" \n",
" \"beam_set1 beam_set1 beam_set1 beam_set1 \"\n",
" \"beam_set2 beam_set2 beam_set2 beam_set2 \"\n",
" \". sidebar2 sidebar2 sidebar5 \"\n",
" \"beam_set3 beam_set3 beam_set3 beam_set3 \"\n",
" \"beam_set4 beam_set4 beam_set4 beam_set4 \"\n",
" \"scanning_set scanning_set scanning_set scanning_set \" \n",
" \"scanning_set1 scanning_set1 scanning_set1 scanning_set1 \"\n",
" \"scanning_set2 scanning_set2 scanning_set2 scanning_set2 \"\n",
" \"scanning_set3 scanning_set3 scanning_set3 scanning_set3 \"\n",
" \"camera_set camera_set camera_set camera_set \"\n",
" \"cl_set1 cl_set1 cl_set1 cl_set1 \"\n",
" \"camera_set1 camera_set1 camera_set1 camera_set1 \"\n",
" \"camera_set3 camera_set3 camera_set3 camera_set3 \"\n",
" \"camera_set2 camera_set2 camera_set2 camera_set2 \"\n",
" ''')\n",
" )\n",
"\n",
"# SMALL CONTROLS\n",
"\n",
"\n",
"def ptycho_interact(beam, aperture, aperture_res, aperture_res2, 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_1bf, cl_check_nbf):\n",
"header = Button(description='Graph controls',layout=Layout(width='auto', grid_area='header'),style=ButtonStyle(button_color='whitesmoke'))\n",
"\n",
"method = ToggleButtons(options=[('SSB','direct'), ('Iter','iterative')], description='Method', tooltips=['SSB', 'PIE, MLc, DM'],\n",
" layout=Layout(width='auto', grid_area='methods'), style = {'description_width': descr,'button_width': butt}, button_style='',disabled=False,)\n",
"\n",
"graph_size = ToggleButtons(options=[('S', 90), ('M', 100), ('L', 120)], value=100, description='Graphs size',\n",
" layout=Layout(width='auto', grid_area='gr_size'), style = {'description_width': descr,'button_width': butt}, button_style='',disabled=False,)\n",
"\n",
"ctf_xaxis = RadioButtons(options=['α','mrad', 'A'], description='CTF x-axis:',\n",
" layout=Layout(width='auto', grid_area='ctxaxis'), style = {'description_width': descr,'button_width': butt}, disabled=False,)\n",
"\n",
"cl_check_laa = Checkbox(value=True, description='Low anlge approximation', indent=False,\n",
" layout=Layout(width='auto', grid_area='check1'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Low angle approximation check - scattering angle < 10 deg\n",
"cl_check_pix = Checkbox(value=True, description='Recon. pixel < step size',indent=False,\n",
" layout=Layout(width='auto', grid_area='check2'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Reconstructed pixel size < scanning step size \n",
"cl_check_def = Checkbox(value=True, description='Beam fits in probe window', indent=False,\n",
" layout=Layout(width='auto', grid_area='check3'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Is probe window big enough to accomodate defocused probe?\n",
"cl_check_1bf = Checkbox(value=True, description='Detector cover < 1α', indent=False,\n",
" layout=Layout(width='auto', grid_area='check4'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Detector cover is lower than 1 α\n",
"cl_check_nbf = Checkbox(value=True, description='Detector cover > 6α', indent=False,\n",
" layout=Layout(width='auto', grid_area='check5'), style = {'description_width': descr,'button_width': butt}, disabled=False,) # Detector cover is higher than 6 α\n",
"\n",
"footer = Button(description='Interactive results',layout=Layout(width='auto', grid_area='footer'),style=ButtonStyle(button_color='whitesmoke'))\n",
"\n",
"small_controls = GridBox(children=[header, method, graph_size, ctf_xaxis, cl_check_laa,cl_check_pix,cl_check_def, cl_check_1bf, cl_check_nbf, footer],\n",
" layout=Layout(\n",
" width='100%',\n",
" grid_template_rows='auto auto auto',\n",
" grid_template_columns='40% 20% 20% 20%',\n",
" grid_template_areas='''\n",
" \"header header header header \"\n",
" \"methods ctxaxis check1 check2\"\n",
" \"gr_size ctxaxis check3 check5\"\n",
" \". ctxaxis check4 . \" \n",
" \"footer footer footer footer\"\n",
" ''')\n",
" )\n",
"\n",
"\n",
"def ptycho_interact(beam, aperture, aperture_res, aperture_res2, probe, cl, matrix, defocus, mag, camera, binning, dwell_time, restriction, method, ctf_xaxis, cl_check_laa, cl_check_pix, cl_check_def, cl_check_1bf, cl_check_nbf, graph_size):\n",
" \n",
" ### SINGLE SETTING PARAMETERS ###\n",
" wavelength = pty.get_wavelength(beam)*1e12\n",
@ -430,12 +455,13 @@
" \n",
" \n",
" ### SAMPLE PLANE ##########################################\n",
" points = 5\n",
" yyy = np.append(np.linspace(0,overlap,100), 200)\n",
" wid = np.linspace(0,scans-1,scans) * step_size_corr\n",
" wid = np.linspace(0,points-1,points) * step_size_corr\n",
" \n",
" fig5 = make_subplots(specs=[[{\"secondary_y\": True}]])\n",
" fig5.update_xaxes(title_text=\"Sample plane (nm)\", range=[0, scans*step_size_corr], showgrid=False, zeroline=False)\n",
" fig5.update_yaxes(range=[0, scans*step_size_corr],showgrid=False, showticklabels=False)\n",
" fig5.update_xaxes(title_text=\"Sample plane (nm)\", range=[0, points*step_size_corr], showgrid=False, zeroline=False)\n",
" fig5.update_yaxes(range=[0, points*step_size_corr],showgrid=False, showticklabels=False)\n",
" for x in range(len(wid)):\n",
" fig5.add_trace(go.Scatter(showlegend=False, x=wid, y=np.ones(len(wid))*wid[x], marker_color='blue'),secondary_y=False)\n",
" for x in range(len(wid)): \n",
@ -443,16 +469,21 @@
" fig5.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.1, fillcolor=\"#FF7F7F\",name=False, x0=wid[x]-beam_diameter/2, y0=wid[y]-beam_diameter/2, x1=wid[x]+beam_diameter/2, y1=wid[y]+beam_diameter/2, line_color=\"red\",secondary_y=False)\n",
"\n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='blue', name='Step '+str(np.round(10*step_size,3))+' Å ('+str(np.round(10*step_size_corr,3))+')'))\n",
" if method == 'direct':\n",
" xx = 2*wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='green', name='Rec step '+str(np.round(xx[-1]/3,2))+' Å')) \n",
" \n",
" fig5.add_trace(go.Scatter(showlegend=True, x=[-1], y=[-1],marker_size=12, marker_color='#FF7F7F', name='Beam ⌀ '+ str(np.round(10*beam_diameter,2))+\" Å\"))\n",
" fig5.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.85,xanchor=\"right\",x=0.9))\n",
" fig5.add_trace(go.Scatter(showlegend=False, x = scans*step_size_corr*np.ones(len(yyy)), y=yyy, opacity=1,mode='markers',marker_symbol = \"triangle-down\",marker=dict(size=20, color=yyy, colorscale='rainbow_r', showscale=False)),secondary_y=True) \n",
" \n",
" \n",
" fig5.add_trace(go.Scatter(showlegend=False, x = points*step_size_corr*np.ones(len(yyy)), y=yyy, opacity=1,mode='markers',marker_symbol = \"triangle-down\",marker=dict(size=20, color=yyy, colorscale='rainbow_r', showscale=False)),secondary_y=True) \n",
" fig5.update_yaxes(title_text=\"Overlap %\", range=[0, 100],showgrid=False, showticklabels=True, tickvals = [0, 20, 40,50, 60,70, 80, 90, 100], secondary_y=True)\n",
" fig5.update_layout(title={'text': \"Sample\",'y':0.95, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig5.update_layout(width=350, height=300, margin =dict(l=30, r=30, t=10, b=0))\n",
" fig5.update_layout(title={'text': \"Sample\",'y':0.95, 'x':0.30,'xanchor': 'left','yanchor': 'top'})\n",
" fig5.update_layout(width=4.5*graph_size, height=3.0*graph_size, margin =dict(l=1.3*graph_size, r=0.3*graph_size, t=0.1*graph_size, b=0))\n",
"\n",
" \n",
" \n",
" \n",
" \n",
" ### DETECTOR PLANE ##########################################\n",
" fig6 = go.Figure() \n",
" fig6.update_xaxes(title_text=\"Pixels\", range=[1, num_pixels], zeroline=False)\n",
@ -466,11 +497,15 @@
" fig6.add_annotation(x=num_pixels/2+beam_diameter_pix/2,y=num_pixels/2, ax=num_pixels/2-beam_diameter_pix/2, ay=num_pixels/2, xref='x',yref='y',axref='x',ayref='y', text='', showarrow=True,arrowhead=3,arrowsize=1,arrowwidth=1,arrowcolor='black')\n",
" fig6.add_annotation(x=num_pixels/2, y=num_pixels/2, text=str(np.round(beam_diameter_pix,1))+\" pix\", showarrow=False, yshift=10)\n",
" fig6.add_trace(go.Scatter(x=[1,1.5,1,1.5], y=[1,1,1.5,1.5], name='Pix ∠ ' +str(np.round(pixel_angle,2))+' mrad'))\n",
" fig6.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.85,xanchor=\"right\",x=1))\n",
" # fig6.update_layout(title={'text': \"Detector\",'y':0.925, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig6.add_trace(go.Scatter(x=[1,1.5,1,1.5], y=[1,1,1.5,1.5], name='Pixel size ' +str(np.round(size_pixel,2))+' um'))\n",
" fig6.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.80,xanchor=\"right\",x=1))\n",
" fig6.update_layout(title={'text': \"Detector\",'y':0.95, 'x':0.11,'xanchor': 'left','yanchor': 'top'})\n",
" fig6.update_layout(xaxis = dict(tickmode = 'array', tickvals = [1, num_pixels/4, num_pixels/2, 3*num_pixels/4, num_pixels])) \n",
" fig6.update_layout(width=250, height=230, margin = dict(l=20, r=20, t=0, b=0))\n",
" fig6.update_layout(width=3.5*graph_size, height=3*graph_size, margin = dict(l=0.35*graph_size, r=0.65*graph_size, t=0.3*graph_size, b=0))\n",
"\n",
" \n",
" \n",
" \n",
" focusdepth = wavelength/(semi_angle_corr/1000)**2/1000\n",
" ssb_cl, kolik = pty.cl4ssb(detector_cover_a_all)\n",
" ### MICROSCOPE SCHEME ##########################################\n",
@ -487,12 +522,17 @@
" fig8.add_trace(go.Scatter(showlegend=False, x=[-150, -2*semi_angle, None, 2*semi_angle, 150], y=[reduc*0.8*y_down,reduc*0.8*y_down,None,reduc*0.8*y_down, reduc*0.8*y_down],mode='lines', line=dict(color='black',width=7)))\n",
" fig8.add_annotation(x=-0.7*width, y=reduc*0.8*y_down, text=\"<b>Aperture </b>\", showarrow=False, yshift=2)\n",
" fig8.add_annotation(x=-0.7*width, y=reduc*0.8*y_down, text=str(aperture), showarrow=False, yshift=-15)\n",
" fig8.add_annotation(x=0.0*width, y=-y_down,text='Acquisition time (s) '+ str(np.round(matrix*matrix*dwell_time/1e6,1)), showarrow=False, yshift=-10)\n",
" fig8.add_annotation(x=0, y=reduc*0.96*y_down,text='λ (pm) '+ str(np.round((pty.get_wavelength(beam)*1e12),2)), showarrow=False, yshift=0)\n",
" \n",
" \n",
" \n",
" \n",
" if defocus > 0:\n",
" defo = np.log(defocus)/100\n",
" else:\n",
" defo = 0 \n",
"\n",
" \n",
" # Beam\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, 2*semi_angle, 0, 0], y=[defo*y_down, reduc*0.8*y_down, reduc*0.8*y_down, defo*y_down], mode='lines',fill=\"toself\", fillcolor=\"#FF7F7F\", opacity=0.7,line=dict(color='#FF7F7F',width=1)))\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, 0, -2*semi_angle, 0], y=[defo*y_down, reduc*0.8*y_down, reduc*0.8*y_down, defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"red\", opacity=0.7,line=dict(color='red',width=1)))\n",
@ -508,14 +548,14 @@
" fig8.add_annotation(x=-0.7*width, y=0,text=\"<b>Sample</b>\", showarrow=False, yshift=15)\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-np.log(fov)/20*width, np.log(fov)/20*width, np.log(fov)/20*width, -np.log(fov)/20*width, -np.log(fov)/20*width], y=[-0.01*y_down, -0.01*y_down, 0.01*y_down, 0.01*y_down, -0.01*y_down],mode='lines', fill=\"toself\", fillcolor=\"black\", line=dict(color='black',width=1), opacity=0.5))\n",
" fig8.add_annotation(x=0.4*width, y=0.05*y_down,text=\"FoV \"+str(np.round(fov,2))+\" nm\", showarrow=False, yshift=0)\n",
" fig8.add_annotation(x=0.5*width, y=0.05*y_down,text=\"Dose \"+str(np.round(dose,1))+\" e/Å2\", showarrow=False, yshift=-30)\n",
" fig8.add_annotation(x=-0.5*width, y=0.05*y_down,text=\"DoF \"+str(np.round(focusdepth,1))+\" nm\", showarrow=False, yshift=-30)\n",
" fig8.add_annotation(x=0.5*width, y=0.05*y_down,text=\"Dose \"+str(np.round(dose,1))+\" e/Å2\", showarrow=False, yshift=-40)\n",
" fig8.add_annotation(x=-0.5*width, y=0.05*y_down,text=\"DoF \"+str(np.round(focusdepth,1))+\" nm\", showarrow=False, yshift=-40)\n",
" # Detector\n",
" y = -np.log(cl)*np.ones(int(num_pixels)+1)\n",
" x = np.linspace(-det_width,det_width, int(num_pixels)+1)\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=x, y=y, mode='markers', marker_symbol=\"line-ns\",marker_line_width=0.5))\n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(cl),text=\"<b>Detector</b>\", showarrow=False,align= 'left', yshift=15)\n",
" \n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(cl),text=str(np.round(cl_det,2))+' cm', showarrow=False,align= 'left', yshift=-15) \n",
" # Scattering\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, det_width, -det_width, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"gray\", opacity=0.1,line=dict(color='black',width=1)))\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, -det_width, det_width, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"gray\", opacity=0.1,line=dict(color='black',width=1)))\n",
@ -524,7 +564,7 @@
" fig8.add_trace(go.Scatter(showlegend=False, x=[0, -det_width/covered_alfas, det_width/covered_alfas, 0], y=[defo*y_down, -np.log(cl), -np.log(cl), -np.log(cl), defo*y_down],mode='lines', fill=\"toself\", fillcolor=\"red\", opacity=0.7,line=dict(color='#FF7F7F',width=1)))\n",
" \n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-width, width], y=[-np.log(ssb_cl), -np.log(ssb_cl)], opacity=0.8, line=dict(color='green',width=3)))\n",
" fig8.add_annotation(x=-0.7*width, y=-np.log(ssb_cl),text=\"<b>for SSB</b>\", showarrow=False,align= 'left', yshift=-15)\n",
" fig8.add_annotation(x=0*width, y=-np.log(ssb_cl),text=\"<b></b>\", showarrow=False,align= 'left', yshift=15)\n",
" \n",
" if restriction == True:\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-250, -4*semi_angle, None, 4*semi_angle, 250], y=[-reduc*0.2*y_down,-reduc*0.2*y_down,None,-reduc*0.2*y_down, -reduc*0.2*y_down],mode='lines', line=dict(color='black',width=7)))\n",
@ -540,26 +580,20 @@
" for x in opt.cameralengths():\n",
" fig8.add_trace(go.Scatter(showlegend=False, x=[-width, width], y=[-np.log(x), -np.log(x)], opacity=0.3, line=dict(color='gray',width=1)))\n",
" fig8.add_annotation(x=0.9*width, y=-np.log(x),text=str(x), showarrow=False, yshift=8)\n",
"\n",
" \n",
" fig8.update_xaxes(title_text=\"\")\n",
" # fig8.update_layout(title={'text': \"Microscope\" ,'y':1, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig8.update_layout(width=250, height=570, margin = dict(l=0, r=0, t=20, b=0))\n",
" fig8.update_layout(width=3.0*graph_size, height=7.2*graph_size, margin = dict(l=0, r=0, t=0.2*graph_size, b=0))\n",
" fig8.update_layout(plot_bgcolor='white')\n",
" \n",
" \n",
" ### FINAL CHECKS ########################################## \n",
" align3 = dict(layout=Layout(width='200px') , style = {'description_width': '150px','button_width': \"100px\"}, disabled=True,) \n",
" align_check = dict(layout=Layout(width='200px') , style = {'description_width': '150px','button_width': \"50px\"}, disabled=True,) \n",
" check1 = Valid(value= bool(overlap > 60), description='Overlap > 60 %', **align_check)\n",
" check2 = Valid(value= bool(step_size_corr*10 > (wavelength * cl_det)/(num_pixels*size_pixel/1e6)/1e4), description='Ptycho pix < step size', **align_check)\n",
" check3 = Valid(value= bool(beam_diameter/2 < probe_window/2), description='Beam ⌀ < window/2', **align_check) \n",
" \n",
" check1 = Valid(value= bool(overlap > 60), description='Overlap > 60 %', **align3)\n",
" check2 = Valid(value= bool(step_size_corr*10 > (wavelength * cl_det)/(num_pixels*size_pixel/1e6)/1e4), description='Ptycho pix < step size', **align3)\n",
" check3 = Valid(value= bool(beam_diameter/2 < probe_window/2), description='Beam ⌀ < window/2', **align3) \n",
" \n",
" acquisition_time = Label(value = f'Acquisition time (s) '+ str(np.round(matrix*matrix*dwell_time/1e6,1)), **align3) \n",
"\n",
"\n",
"\n",
" \n",
" \n",
" \n",
" ### METHODS ########################################## \n",
" if method == 'direct':\n",
@ -587,21 +621,19 @@
" fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf, marker_color='gray', name='SSB-CTF',))\n",
"\n",
" fig.add_trace(go.Scatter(x=xx, y=pctf, marker_color='red', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n",
" fig.update_xaxes(title_text=\"Real space distance (Å)\", range=[-0.5, 2.5], type=\"log\", zeroline=False)\n",
" fig.update_xaxes(title_text=\"Real space distance (Å)\", range=[-0.2, 2.5], type=\"log\", zeroline=False)\n",
"\n",
" fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.75,xanchor=\"right\",x=1))\n",
" # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig.update_layout(width=600, height=225, margin = dict(l=100, r=30, t=30, b=30))\n",
" fig.update_layout(width=7.65*graph_size, height=2.25*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
" \n",
" \n",
" ssb_sampling = Label(value = f'Recommended sampling (Å) '+ str(np.round(xx[-1]/3,2)), **align3) \n",
" \n",
" ### CAMERA LENGTH GRAPH ##########################################\n",
" fig4 = make_subplots(specs=[[{\"secondary_y\": True}]])\n",
" fig4.add_trace(go.Scatter(showlegend=False, x=opt.cameralengths(), y=detector_cover_all, marker_color='gray'), secondary_y=False,)\n",
" fig4.add_trace(go.Scatter(showlegend=False, x=opt.cameralengths(), y=detector_cover_a_all,marker_color='gray'), secondary_y=True,)\n",
" fig4.add_trace(go.Scatter(x=np.array(cl), y=np.array(covered_alfas), marker_size=12, marker_color='red', name = str(np.round(detector_cover,1))+ \" mrad; \"+str(np.round(covered_alfas,2))+ \" α\"), secondary_y=True,) \n",
" fig4.add_trace(go.Scatter(x=np.array(ssb_cl), y=np.array(kolik),marker_size=12, marker_color='green', name = \"Rec SSB CL\"), secondary_y=True,) \n",
" fig4.add_trace(go.Scatter(x=np.array(ssb_cl), y=np.array(kolik),marker_size=12, marker_color='green', name = \"Recommended CL\"), secondary_y=True,) \n",
" fig4.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.65,xanchor=\"right\",x=0.9))\n",
" # fig4.update_layout(title={'text': \"CL to α\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig4.update_xaxes(title_text=\"Nominal camera length (cm)\", type=\"log\", tickvals = opt.cameralengths())\n",
@ -609,26 +641,23 @@
" fig4.update_yaxes(title_text=\" Cover angle (mrad)\", range=[0, 1.1*np.max(detector_cover_all)], secondary_y=False)\n",
" fig4.update_yaxes(title_text=\" Cover angle (α)\", range=[0, 1.1*np.max(detector_cover_a_all)], showgrid=False, secondary_y=True)\n",
" fig4.update_layout(xaxis = dict(tickmode = 'array', tickvals = opt.cameralengths()))\n",
" fig4.update_layout(width=600, height=225, margin =dict(l=110, r=30, t=30, b=30))\n",
" \n",
" \n",
" checks = VBox([Label('Final checks'), ssb_sampling, acquisition_time]) \n",
" checks.layout = Layout(border='dashed 1px gray',margin='30px 5px 5px 5px', padding='10px 10px 10px 10px')\n",
" \n",
" \n",
" fig4.update_layout(width=8.0*graph_size, height=2.25*graph_size, margin =dict(l=1.3*graph_size, r=0.25*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
"\n",
" ### SHOWING ###\n",
" right_column = VBox([go.FigureWidget(fig),HBox([go.FigureWidget(fig5),go.FigureWidget(fig6)]),go.FigureWidget(fig4)])\n",
" left_column = VBox([go.FigureWidget(fig8)])\n",
" \n",
"\n",
" \n",
" right_column = VBox([go.FigureWidget(fig),go.FigureWidget(fig5),go.FigureWidget(fig4),checks])\n",
" left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)])\n",
" \n",
"\n",
" \n",
" display(HBox([left_column, right_column]))\n",
" \n",
" \n",
" \n",
" \n",
" total = HBox([left_column, right_column])\n",
" total.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 40px', padding='10px 10px 10px 10px')\n",
" \n",
" display(total)\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" if method == 'iterative': \n",
" \n",
@ -670,14 +699,10 @@
"\n",
" fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.75,xanchor=\"right\",x=1))\n",
" # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n",
" fig.update_layout(width=600, height=225, margin = dict(l=110, r=30, t=30, b=30))\n",
" \n",
" \n",
" \n",
" \n",
" \n",
" checks = VBox([Label('Final checks'),check1, check2, check3, acquisition_time]) \n",
" checks.layout = Layout(border='dashed 1px gray',margin='30px 5px 5px 5px', padding='10px 10px 10px 10px')\n",
" fig.update_layout(width=7.65*graph_size, height=2.25*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.3*graph_size, b=0.3*graph_size))\n",
" \n",
" checks = VBox([Label('Final checks'),check1, check2, check3]) \n",
" checks.layout = Layout(border='dashed 1px gray', margin='30px 0px 50px 40px', padding='5px 5px 5px 5px')\n",
" \n",
" \n",
" ### PROBE WINDOW ##########################################\n",
@ -701,14 +726,14 @@
" fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n",
" fig7.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.9,xanchor=\"right\",x=1))\n",
" fig7.update_layout(title={'text': \"Probe window \",'y':0.925, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n",
" fig7.update_layout(width=320, height=300, margin =dict(l=30, r=30, t=10, b=0)) \n",
" fig7.update_layout(width=3.2*graph_size, height=3.0*graph_size, margin =dict(l=0.3*graph_size, r=0.3*graph_size, t=0.1*graph_size, b=0)) \n",
" \n",
" ### CAMERA LENGTH TABLE ########################################## \n",
" dictionary = {}\n",
" tab = np.array([np.round(ptycho_pixel_size_all,2),np.round(detector_cover_all,1), np.round(detector_cover_a_all,1), np.round(max_defocus_all,1), opt.cameralengths()])\n",
"\n",
" align6 = dict(layout=Layout(width='50px') , style = {'description_width': '0px','button_width': \"33px\"}, disabled=True,)\n",
" align7 = dict(layout=Layout(width='120px') , style = {'description_width': '0px','button_width': \"105px\"}, disabled=True,)\n",
" align6 = dict(layout=Layout(width=str(int(graph_size/100*62))+'px') , style = {'description_width': '0px','button_width': str(int(graph_size/100*40))+'px'}, disabled=True,)\n",
" align7 = dict(layout=Layout(width='140px') , style = {'description_width': '0px','button_width': \"120px\"}, disabled=True,)\n",
" \n",
" for i in range(0,12):\n",
" button_style = 'success'\n",
@ -756,22 +781,26 @@
" \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",
" cltab.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 110px', padding='10px 10px 10px 10px')\n",
" \n",
" \n",
" \n",
" ### SHOWING ###\n",
" sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n",
" right_column = VBox([go.FigureWidget(fig), sample_overlap, cltab, checks ]) \n",
" left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)]) \n",
" sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7), go.FigureWidget(fig6)]) \n",
" right_column = VBox([HBox([go.FigureWidget(fig),checks]), sample_overlap, cltab]) \n",
" left_column = VBox([go.FigureWidget(fig8)]) \n",
" \n",
" display(HBox([left_column, right_column]))\n",
" \n",
" total = HBox([left_column, right_column])\n",
" total.layout = Layout(border='solid 0px gray',margin='10px 10px 10px 40px', padding='10px 10px 10px 10px')\n",
" \n",
" display(total)\n",
" \n",
" return \n",
" \n",
"gui = interactive_output(ptycho_interact, {\"beam\": beam, \"aperture\": aperture,\"aperture_res\": aperture_res,\"aperture_res2\": aperture_res2, \"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,\n",
" \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_1bf\": cl_check_1bf, \"cl_check_nbf\": cl_check_nbf}) \n",
" \"binning\": binning, \"dwell_time\": dwell_time, \"restriction\": restriction, \"method\": method, \"ctf_xaxis\": ctf_xaxis,\n",
" \"cl_check_laa\":cl_check_laa, \"cl_check_pix\": cl_check_pix, \"cl_check_def\": cl_check_def, \"cl_check_1bf\": cl_check_1bf, \"cl_check_nbf\": cl_check_nbf, \"graph_size\": graph_size}) \n",
"\n"
]
},
@ -805,19 +834,19 @@
},
{
"cell_type": "code",
"execution_count": 37,
"execution_count": 759,
"id": "7937f054-fcd0-4e67-a20f-7696f5903a94",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1e35fd918b334d70b6eca967055cf6ce",
"model_id": "164f877a365543aea26b5fecf9a80a1c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(HBox(children=(VBox(children=(Label(value=''), VBox(children=(Label(value='Beam'), Dropdown(des…"
"HBox(children=(GridBox(children=(Button(description='STEM control panel', layout=Layout(grid_area='header', wi…"
]
},
"metadata": {},
@ -825,35 +854,9 @@
}
],
"source": [
"\n",
"\n",
"display(HBox([controls, gui]))"
"display(HBox([controls, VBox([small_controls, gui]) ]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79e73498-4e48-4617-9085-95b6c01597c9",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "0661a5fa-f65c-45cf-a6f4-39d1f9f186cd",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ba255a1-e209-4107-8a8f-0a1cac8cce90",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
@ -874,6 +877,27 @@
"# import ipywidgets\n",
"# print(\"Ipywidgets version \", ipywidgets.__version__)"
]
},
{
"cell_type": "code",
"execution_count": 736,
"id": "df751153-70c4-47a8-801c-3a96d813399e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'55px'"
]
},
"execution_count": 752,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"str(int(graph_size.value/100*62))+'px'"
]
}
],
"metadata": {