From b1d668c3526056a7d1694f694fb20b5e261832be Mon Sep 17 00:00:00 2001 From: rskoupy Date: Mon, 29 Apr 2024 18:00:39 +0200 Subject: [PATCH] Witches day --- .../ptychoScopy-checkpoint.ipynb | 135 ++++++--- calibrations.xlsx | Bin 33565 -> 33504 bytes ptychoScopy.ipynb | 262 ++++++++++++++---- 3 files changed, 308 insertions(+), 89 deletions(-) diff --git a/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb b/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb index feb864b..72afbc2 100644 --- a/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb +++ b/.ipynb_checkpoints/ptychoScopy-checkpoint.ipynb @@ -30,14 +30,14 @@ }, { "cell_type": "code", - "execution_count": 380, + "execution_count": 20, "id": "7937f054-fcd0-4e67-a20f-7696f5903a94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "0b1b53b08a164896893f0f563fa29206", + "model_id": "13c78bb2a5be48d79c3d210afa1c877e", "version_major": 2, "version_minor": 0 }, @@ -81,7 +81,7 @@ }, { "cell_type": "code", - "execution_count": 379, + "execution_count": 19, "id": "3ca2e3fd-4e61-4d4c-9d58-4b72f16999dc", "metadata": {}, "outputs": [], @@ -92,6 +92,7 @@ "\n", "import numpy as np\n", "import scipy.constants as cons\n", + "from scipy.stats import norm\n", "import plotly.graph_objects as go\n", "from scipy.interpolate import splrep, BSpline \n", "from copy import deepcopy\n", @@ -245,7 +246,7 @@ " excel_line = excel_data[excel_data.Probe.isin(['Def0Diameter'])]\n", " beam_0_diameter = np.array([excel_line[aperture]]).astype(float)\n", " beam_0_diameter = beam_0_diameter.item()\n", - " self.beam_diameter = defocus*2*np.tan(self.angle_corr/1000)+beam_0_diameter\n", + " self.beam_diameter = 2*defocus*np.tan(self.angle_corr/1000)+beam_0_diameter\n", " return self.beam_diameter\n", " \n", " def get_0beam_diameter(self, aperture):\n", @@ -383,7 +384,7 @@ "restriction_name = Label(value = 'PAAR',layout=Layout(width='95%', grid_area='restriction_name'),)\n", "restriction = ToggleButtons(options=[('.',False), ('..',True)], value = False, description='',icons = ['ban','check'], layout=Layout(width='95%', grid_area='camera_set2'),style = {'description_width': '80px','button_width': '48%', 'font_weight': 'bold'}, button_style='')\n", "binning_name = Label(value = 'Binning',layout=Layout(width='95%', grid_area='binning_name'),)\n", - "binning = ToggleButtons(options=[('.',1), ('2',2), ('4',4), ('8',8), ('16',16), ('24',24), ('32',32)], value=1, description='', icons = ['ban','',''], layout=Layout(width='95%', grid_area='camera_set3'), **ali3)\n", + "binning = ToggleButtons(options=[('.',1), ('2',2), ('4',4), ('8',8), ('16',16), ('24',24), ('32',32), ('48',48)], value=1, description='', icons = ['ban','',''], layout=Layout(width='95%', grid_area='camera_set3'), **ali3)\n", "\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", @@ -456,7 +457,7 @@ " \" charts charts charts charts charts\"\n", " '''))\n", "\n", - "small_controls1 = GridBox(children=[header4, ctf_xaxis], layout=Layout(width='95%', grid_template_rows='auto', grid_template_columns='67% 75px 23%', grid_template_areas='''\". header4 ctxaxis \"'''))\n", + "small_controls1 = GridBox(children=[header4, ctf_xaxis], layout=Layout(width='95%', grid_template_rows='auto', grid_template_columns='47% 75px 43%', grid_template_areas='''\". header4 ctxaxis \"'''))\n", "top_set = Button(description='',layout=Layout(width='99%', grid_area='scanning_set'), style=ButtonStyle(button_color='white', font_weight= 'bold',font_size= '16px',text_color='#0d48a1'),disabled = True)\n", "\n", "\n", @@ -482,7 +483,7 @@ " if overlap < 0:\n", " overlap = 0\n", " dose = ((matrix**2)*(dwell_time/1e6)*(current/1e12/cons.e))/((((matrix-1)*step_size_corr)**2)*100)\n", - " probe_window = (wavelength*cl_det/100)/(2*size_pixel/1e6)/1000 # now in nm\n", + " probe_window = (wavelength*cl_det/100)/(size_pixel/1e6)/1000 # now in nm\n", " \n", " ### ALL CAMERA LENGTHS PARAMETERS ###\n", " pixel_covers = pty.get_pixel_covers(camera, binning) \n", @@ -497,12 +498,13 @@ " else:\n", " ptycho_pixel_size_all = (wavelength * np.array(opt.cameralengths_eff() )) /(num_pixels/2*size_pixel/1e6)/1e4\n", " \n", - " probe_window_all = (wavelength*np.array(opt.cameralengths_eff())/100)/(2*size_pixel/1e6)/1000 # now in nm\n", + " probe_window_all = (wavelength*np.array(opt.cameralengths_eff())/100)/(size_pixel/1e6)/1000 # now in nm\n", " usable_probe_semi_window_all = probe_window_all/4\n", " detector_cover_a_all = detector_cover_all/semi_angle_corr\n", - " max_defocus_all = (usable_probe_semi_window_all - pty.get_0beam_diameter(aperture)/2)/np.tan(semi_angle_corr/1000)\n", + " max_defocus_all = (usable_probe_semi_window_all)/np.tan(semi_angle_corr/1000)\n", + " # max_defocus_all = (usable_probe_semi_window_all - pty.get_0beam_diameter(aperture)/2)/np.tan(semi_angle_corr/1000) # with r0\n", " max_defocus_all[max_defocus_all < 0] = 'nan'\n", - " \n", + " #\n", " omega = np.linspace(1e-6,2,100) \n", " pctf = pty.get_ssb_ctf()\n", " apertury = opt.apertures()\n", @@ -530,7 +532,7 @@ " fig5.add_annotation(x=2.25*step_size_corr, y=-2*step_size_corr, text=str(np.round(10*beam_diameter,2))+' Å', showarrow=False, yshift=-15)\n", " \n", " if method == 'direct':\n", - " xx = 2*wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n", + " xx = 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", " if method == 'iterative':\n", @@ -548,20 +550,15 @@ " fig6 = make_subplots(specs=[[{\"secondary_y\": True}]])\n", " fig6.update_xaxes(title_text=\"\", range=[0.5, num_pixels+0.5], tickvals = [1, num_pixels/2+0.5, num_pixels], ticktext = [1, \"Detector pixel array\", num_pixels], showticklabels=True,showgrid=True) \n", " fig6.update_yaxes(range=[0.5, num_pixels+0.5], showticklabels=False, showgrid=False, secondary_y=False)\n", - " \n", " fig6.add_shape(type=\"circle\",xref=\"x\", yref=\"y\",opacity=0.5, fillcolor=\"#FF7F7F\", x0=(num_pixels+1)/2-beam_diameter_pix/2, y0=(num_pixels+1)/2-beam_diameter_pix/2, x1=(num_pixels+1)/2+beam_diameter_pix/2, y1=(num_pixels+1)/2+beam_diameter_pix/2,line_color=\"red\",secondary_y=False)\n", " fig6.add_shape(type=\"rect\",xref=\"x\", yref=\"y\",opacity=0.5, fillcolor=\"#f0f921\", x0=0.5, y0=0.5, x1=1.5, y1=1.5,line_color=\"#000004\",secondary_y=False)\n", - " \n", " fig6.add_annotation(x=(num_pixels+1)/2-beam_diameter_pix/2, y=(num_pixels+1)/2, ax=(num_pixels+1)/2+beam_diameter_pix/2, ay=(num_pixels+1)/2, xref='x',yref='y',axref='x',ayref='y',text='', showarrow=True,arrowhead=2,arrowsize=2,arrowwidth=1,arrowcolor='black')\n", " fig6.add_annotation(x=(num_pixels+1)/2+beam_diameter_pix/2,y=(num_pixels+1)/2, ax=(num_pixels+1)/2-beam_diameter_pix/2, ay=(num_pixels+1)/2, xref='x',yref='y',axref='x',ayref='y', text='', showarrow=True,arrowhead=2,arrowsize=2,arrowwidth=1,arrowcolor='black')\n", " fig6.add_annotation(x=(num_pixels+1)/2, y=(num_pixels+1)/2, text=str(np.round(beam_diameter_pix,1))+\" pix\", showarrow=False, yshift=10)\n", " fig6.add_annotation(x=1, y=1, text=str(np.round(size_pixel,2))+\" μm ≈ \" +str(np.round(pixel_angle,4))+\" mrad\", showarrow=False, xshift=70+(50/np.sqrt(num_pixels)), yshift=10+(50/np.sqrt(num_pixels)))\n", - "\n", " fig6.add_trace(go.Scatter(showlegend=False,x=[-1], y=[-1]),secondary_y=True)\n", " fig6.update_yaxes(title_text=\"\", range=[-1, 1], showticklabels=True, showgrid=False, tickvals = [-1, 0, 0.85], ticktext = [\"\", \"Max cover angle (mrad)\", str(np.round(detector_cover,1))], secondary_y=True) \n", " fig6.update_yaxes(tickangle=-90)\n", - "\n", - " \n", " fig6.update_layout(width=3.8*graph_size, height=3.1*graph_size, margin = dict(l=0.6*graph_size, r=0.48*graph_size, t=0.1*graph_size, b=0.1*graph_size))\n", "\n", " \n", @@ -577,10 +574,7 @@ " fig8 = go.Figure() \n", " fig8.update_xaxes(range=[-width, width], showticklabels=False,zeroline=False)\n", " fig8.update_yaxes(range=[-y_down, reduc*y_down], showticklabels=False,)\n", - "\n", - "\n", " fig8.add_shape(type=\"rect\",xref=\"x\", yref=\"y\",opacity=0.05, fillcolor=\"gray\", x0=-width, y0=-y_down, x1=width, y1=reduc*y_down,line_color=\"gray\")\n", - " \n", " fig8.add_shape(type=\"rect\",xref=\"x\", yref=\"y\",opacity=0.7, fillcolor=\"red\", x0=-100, y0=reduc*0.8*y_down, x1=100, y1=reduc*0.9*y_down,line_color=\"red\")\n", " 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=\"Aperture \", showarrow=False, yshift=2)\n", @@ -593,7 +587,6 @@ " 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", @@ -670,8 +663,8 @@ " ### PROBE ##########################################\n", " fig = go.Figure() \n", " fig.update_yaxes(title_text=\"Contrast transfer func.\")\n", - " xx = wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n", - " # xx = 2*wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n", + "\n", + " xx = wavelength/(np.sin(semi_angle_corr*omega/1000))/100 # Full pitch size\n", " \n", " if ctf_xaxis == 'α': \n", " fig.add_trace(go.Scatter(x=omega, y=pctf, marker_color='red', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n", @@ -686,25 +679,30 @@ "\n", " elif ctf_xaxis == 'A':\n", " for x in apertury:\n", - " d = wavelength/(np.sin(pty.get_angle_corr(x)*omega/1000))/100\n", + " d = wavelength/(np.sin(pty.get_angle_corr(x)*omega/1000))/100 # Full pitch size\n", " 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", "\n", " # SmB6\n", - " fig.add_trace(go.Scatter(x=[4.13, 4.13], y=[0, 0.41], marker_color='green', ))\n", - " fig.add_trace(go.Scatter(x=[2.92, 2.92], y=[0, 0.41], marker_color='green', ))\n", + " fig.add_trace(go.Scatter(showlegend=False,x=[4.13, 4.13], y=[0, 0.41], marker_color='green', ))\n", + " fig.add_trace(go.Scatter(showlegend=False,x=[2.92, 2.92], y=[0, 0.41], marker_color='green', ))\n", "\n", - " fig.add_trace(go.Scatter(x=[1.71, 1.71], y=[0, 0.41], marker_color='blue', ))\n", - " fig.add_trace(go.Scatter(x=[1.21, 1.21], y=[0, 0.41], marker_color='blue', ))\n", + " fig.add_trace(go.Scatter(showlegend=False,x=[1.71, 1.71], y=[0, 0.41], marker_color='blue', ))\n", + " fig.add_trace(go.Scatter(showlegend=False,x=[1.21, 1.21], y=[0, 0.41], marker_color='blue', ))\n", "\n", " \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 periode (Å)\", range=[-0.25, 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=6*graph_size, height=2.5*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.3*graph_size))\n", - " \n", + " \n", + " fig.update_layout(width=5*graph_size, height=2.5*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.3*graph_size))\n", + " fig.update_layout(width=5*graph_size, height=2.5*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.3*graph_size))\n", + "\n", + "\n", + "\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", @@ -772,20 +770,64 @@ "\n", " case 'A':\n", " for x in apertury:\n", - " d = 2*wavelength/(np.sin(pty.get_angle_corr(x)*xnew/1000))/100\n", + " d = wavelength/(np.sin(pty.get_angle_corr(x)*xnew/1000))/100\n", " fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf_new, marker_color='gray', name='CTF',))\n", " \n", - " xx = 2*wavelength/(np.sin(semi_angle_corr*xnew/1000))/100\n", + " xx = wavelength/(np.sin(semi_angle_corr*xnew/1000))/100\n", " fig.add_trace(go.Scatter(x=xx, y=pctf_new, 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], type=\"log\", zeroline=False) # \n", "\n", " fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.8,xanchor=\"right\",x=0.95))\n", " # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n", - " fig.update_layout(width=9.25*graph_size, height=2.2*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.6*graph_size))\n", + " fig.update_layout(width=5*graph_size, height=2.2*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.45*graph_size))\n", " \n", " checks = VBox([Label('Final checks'),check1, check2, check3]) \n", " checks.layout = Layout(border='dashed 1px gray', margin='0px 30px 20px 120px', padding='5px 5px 5px 5px')\n", " \n", + " ### INTENSIY DISTRIBUTION ##################################\n", + " fig9 = go.Figure() \n", + " fig9.update_yaxes(title_text=\"Probe intensity [-]\")\n", + " fig9.update_xaxes(title_text=\"Sample plane (nm)\", range=[-4*step_size_corr, 4*step_size_corr], zeroline=False)\n", + "\n", + " # define constants\n", + " mu = 0\n", + " # sigma = beam_diameter/(2*np.sqrt(8*np.log(2))) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " sigma = beam_diameter/4 # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " # sigma = beam_diameter/np.sqrt(8*np.log(2)) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " # sigma = beam_diameter/np.sqrt(8*np.log(2)) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " x = np.linspace(-4*step_size_corr, 4*step_size_corr, 300)\n", + "\n", + " possitions = 10\n", + " yy = np.zeros(len(x))\n", + " for i in np.linspace(-possitions,possitions,2*possitions+1).astype(int):\n", + " \n", + " y = norm.pdf(x,mu-i*step_size_corr,sigma)\n", + " yy = yy+y\n", + " if i == 0:\n", + " fig9.add_trace(go.Scatter(x=x, y=y, marker_color='gray',name='Individual probes')) \n", + " fig9.add_trace(go.Scatter(showlegend=False,x=x, y=y, marker_color='gray')) \n", + " \n", + " fig9.add_trace(go.Scatter(x=x, y=yy, marker_color='red', name='Sumed probes'))\n", + " fig9.add_annotation(x=0, y=np.max(yy),text=\"Hilliness \"+str(np.round( ((np.max(yy[100:200])-np.min(yy[100:200]))/np.max(yy[100:200])*100),1))+\" %\", showarrow=False,align= 'left', yshift=15)\n", + " fig9.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.1,xanchor=\"right\",x=0.95))\n", + " fig9.update_layout(width=5*graph_size, height=2.2*graph_size, margin = dict(l=0.5*graph_size, r=1*graph_size, t=0.0*graph_size, b=0.0*graph_size))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", " \n", " ### PROBE WINDOW ##########################################\n", " if beam_diameter < probe_window/2:\n", @@ -814,7 +856,7 @@ " fig7.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.4, fillcolor=color, x0=probe_window/2-beam_diameter/2, y0=probe_window/2-beam_diameter/2, x1=probe_window/2+beam_diameter/2, y1=probe_window/2+beam_diameter/2, line_color=color,)\n", "\n", " \n", - " fig7.update_xaxes(title_text=\"Probe window (nm)\", range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], ticktext = [0, np.round(probe_window/4,2),np.round(probe_window/4,2),np.round(probe_window/2,2),np.round(3*probe_window/4,2),np.round(probe_window,2)])\n", + " fig7.update_xaxes(title_text=\"Probe window (nm)\", range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], ticktext = [0, np.round(probe_window/4,2),np.round(probe_window/2,2),np.round(3*probe_window/4,2),np.round(probe_window,2)])\n", " fig7.update_yaxes(range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], showticklabels=False,)\n", " fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n", " fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n", @@ -884,10 +926,10 @@ " total = VBox([go.FigureWidget(fig8),go.FigureWidget(fig6)])\n", " case 'dedic':\n", " sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n", - " total = VBox([HBox([go.FigureWidget(fig)]), sample_overlap, cltab,checks]) \n", + " total = VBox([HBox([go.FigureWidget(fig),go.FigureWidget(fig9)]), sample_overlap, cltab,checks]) \n", " case _:\n", " sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n", - " right_column = VBox([HBox([go.FigureWidget(fig)]), sample_overlap, cltab,checks]) \n", + " right_column = VBox([HBox([go.FigureWidget(fig),go.FigureWidget(fig9)]), sample_overlap, cltab,checks]) \n", " left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)]) \n", " total = HBox([left_column, right_column]) \n", " \n", @@ -900,6 +942,27 @@ "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, \"graph_size\": graph_size,\"chart\": chart,\"cl_checks\": cl_checks}) \n" ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "5a35407f-11fd-4214-940e-ecdf089cf2c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.3548200450309493" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sqrt(8*np.log(2)) " + ] } ], "metadata": { diff --git a/calibrations.xlsx b/calibrations.xlsx index 916921e1f4c5b5d4db716dcafdcd380f99cb0dae..9893bc3f5e2f99137b621345d35649fbdaa9dc10 100644 GIT binary patch delta 15146 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 zAperture \", showarrow=False, yshift=2)\n", @@ -593,7 +666,6 @@ " 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", @@ -669,9 +741,9 @@ " \n", " ### PROBE ##########################################\n", " fig = go.Figure() \n", - " fig.update_yaxes(title_text=\"Contrast transfer func.\")\n", - " xx = wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n", - " # xx = 2*wavelength/(np.sin(semi_angle_corr*omega/1000))/100\n", + " fig.update_yaxes(title_text=\"Contrast transfer [-]\")\n", + "\n", + " xx = wavelength/(np.sin(semi_angle_corr*omega/1000))/100 # Full pitch size\n", " \n", " if ctf_xaxis == 'α': \n", " fig.add_trace(go.Scatter(x=omega, y=pctf, marker_color='red', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n", @@ -679,32 +751,54 @@ " \n", " if ctf_xaxis == 'mrad': \n", " for x in apertury:\n", - " fig.add_trace(go.Scatter(showlegend=False, x=pty.get_angle_corr(x) *omega, y=pctf, marker_color='gray', name='SSB-CTF',))\n", + " fig.add_trace(go.Scatter(showlegend=False, x=pty.get_angle_corr(x) *omega, y=pctf, marker_color='black', name='SSB-CTF',))\n", "\n", - " fig.add_trace(go.Scatter(x=semi_angle_corr*omega, y=pctf, marker_color='red', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n", + " # fig.add_trace(go.Scatter(x=semi_angle_corr*omega, y=pctf, marker_color='black', name=str(np.round(semi_angle_corr,2))+ ' mrad',))\n", + " fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.85,xanchor=\"right\",x=1))\n", " fig.update_xaxes(title_text=\"Spacial frequency (mrad)\", range=[0, 60], zeroline=False)\n", "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", " elif ctf_xaxis == 'A':\n", " for x in apertury:\n", - " d = wavelength/(np.sin(pty.get_angle_corr(x)*omega/1000))/100\n", - " fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf, marker_color='gray', name='SSB-CTF',))\n", + " d = wavelength/(np.sin(pty.get_angle_corr(x)*omega/1000))/100 # Full pitch size\n", + " fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf, marker_color='black', 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", "\n", " # SmB6\n", - " fig.add_trace(go.Scatter(x=[4.13, 4.13], y=[0, 0.41], marker_color='green', ))\n", - " fig.add_trace(go.Scatter(x=[2.92, 2.92], y=[0, 0.41], marker_color='green', ))\n", + " # fig.add_trace(go.Scatter(showlegend=False,x=[4.13, 4.13], y=[0, 0.41], marker_color='green', ))\n", + " # fig.add_trace(go.Scatter(showlegend=False,x=[2.92, 2.92], y=[0, 0.41], marker_color='green', ))\n", "\n", - " fig.add_trace(go.Scatter(x=[1.71, 1.71], y=[0, 0.41], marker_color='blue', ))\n", - " fig.add_trace(go.Scatter(x=[1.21, 1.21], y=[0, 0.41], marker_color='blue', ))\n", + " # fig.add_trace(go.Scatter(showlegend=False,x=[1.71, 1.71], y=[0, 0.41], marker_color='blue', ))\n", + " # fig.add_trace(go.Scatter(showlegend=False,x=[1.21, 1.21], y=[0, 0.41], marker_color='blue', ))\n", "\n", " \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.5, 2], 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=6*graph_size, height=2.5*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.3*graph_size))\n", - " \n", + "\n", + "\n", + " fig.update_layout(plot_bgcolor='white')\n", + " fig.update_xaxes(mirror=True,ticks='outside',showline=True,linecolor='black',gridcolor='lightgrey')\n", + " fig.update_yaxes(mirror=True,ticks='outside',showline=True,linecolor='black',gridcolor='lightgrey')\n", + " fig.update_yaxes(title_font_color=\"#000000\")\n", + " fig.update_xaxes(title_font_color=\"#000000\")\n", + "\n", + " \n", + " fig.update_layout(width=5*graph_size, height=2.5*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.3*graph_size))\n", + " \n", + "\n", + "\n", + "\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", @@ -772,20 +866,69 @@ "\n", " case 'A':\n", " for x in apertury:\n", - " d = 2*wavelength/(np.sin(pty.get_angle_corr(x)*xnew/1000))/100\n", + " d = wavelength/(np.sin(pty.get_angle_corr(x)*xnew/1000))/100\n", " fig.add_trace(go.Scatter(showlegend=False, x=d, y=pctf_new, marker_color='gray', name='CTF',))\n", " \n", - " xx = 2*wavelength/(np.sin(semi_angle_corr*xnew/1000))/100\n", + " xx = wavelength/(np.sin(semi_angle_corr*xnew/1000))/100\n", " fig.add_trace(go.Scatter(x=xx, y=pctf_new, 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], type=\"log\", zeroline=False) # \n", "\n", " fig.update_layout(legend=dict(orientation=\"h\",yanchor=\"bottom\",y=0.8,xanchor=\"right\",x=0.95))\n", " # fig3.update_layout(title={'text': \"CTF\",'y':0.93, 'x':0.12,'xanchor': 'left','yanchor': 'top'})\n", - " fig.update_layout(width=9.25*graph_size, height=2.2*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.6*graph_size))\n", + " fig.update_layout(width=5*graph_size, height=2.2*graph_size, margin = dict(l=1.3*graph_size, r=0.3*graph_size, t=0.0*graph_size, b=0.45*graph_size))\n", " \n", " checks = VBox([Label('Final checks'),check1, check2, check3]) \n", " checks.layout = Layout(border='dashed 1px gray', margin='0px 30px 20px 120px', padding='5px 5px 5px 5px')\n", " \n", + " ### INTENSIY DISTRIBUTION ##################################\n", + " fig9 = go.Figure() \n", + " fig9.update_yaxes(title_text=\"Probe intensity [-]\")\n", + " fig9.update_xaxes(title_text=\"Sample plane (nm)\", range=[-4*step_size_corr, 4*step_size_corr], zeroline=False)\n", + "\n", + " # define constants\n", + " mu = 0\n", + " # sigma = beam_diameter/(2*np.sqrt(8*np.log(2))) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " \n", + " \n", + " # sigma = beam_diameter/4 # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " sigma = beam_diameter/1.66 # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + "\n", + " \n", + " # sigma = beam_diameter/np.sqrt(8*np.log(2)) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " # sigma = beam_diameter/np.sqrt(8*np.log(2)) # WHAT ABOUT THE FORMULA?????? SHOULD BE beam_diameter/np.sqrt(8*np.log(2)) IS BEAM DEFINED BY DIAMETER +-2 SIGMA?\n", + " x = np.linspace(-4*step_size_corr, 4*step_size_corr, 300)\n", + "\n", + " possitions = 10\n", + " yy = np.zeros(len(x))\n", + " for i in np.linspace(-possitions,possitions,2*possitions+1).astype(int):\n", + " \n", + " y = norm.pdf(x,mu-i*step_size_corr,sigma)\n", + " yy = yy+y\n", + " if i == 0:\n", + " fig9.add_trace(go.Scatter(x=x, y=y, marker_color='gray',name='Individual probes')) \n", + " fig9.add_trace(go.Scatter(showlegend=False,x=x, y=y, marker_color='gray')) \n", + " \n", + " fig9.add_trace(go.Scatter(x=x, y=yy, marker_color='red', name='Sumed probes'))\n", + " fig9.add_annotation(x=0, y=np.max(yy),text=\"Hilliness \"+str(np.round( ((np.max(yy[100:200])-np.min(yy[100:200]))/np.max(yy[100:200])*100),1))+\" %\", showarrow=False,align= 'left', yshift=15)\n", + " fig9.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=0.1,xanchor=\"right\",x=0.95))\n", + " fig9.update_layout(width=5*graph_size, height=2.2*graph_size, margin = dict(l=0.5*graph_size, r=1*graph_size, t=0.0*graph_size, b=0.0*graph_size))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", " \n", " ### PROBE WINDOW ##########################################\n", " if beam_diameter < probe_window/2:\n", @@ -799,10 +942,10 @@ " name = 'Beam ⌀ is too big'\n", "\n", " fig7 = go.Figure() \n", - " fig7.add_shape(type=\"rect\",xref=\"x\", yref=\"y\",opacity=0.3, fillcolor=\"LightSkyBlue\", x0=probe_window/4, y0=probe_window/4, x1=3*probe_window/4, y1=3*probe_window/4,line_color=\"LightSkyBlue\")\n", + " fig7.add_shape(type=\"rect\",xref=\"x\", yref=\"y\",opacity=0.3, fillcolor=\"#6F6F6F\", x0=probe_window/4, y0=probe_window/4, x1=3*probe_window/4, y1=3*probe_window/4,line_color=\"#6F6F6F\")\n", " # fig7.add_trace(go.Scatter(x=np.array(probe_window/2), y=np.array(probe_window/2), showlegend=False, marker_color=\"LightSkyBlue\"))\n", " fig7.add_trace(go.Scatter(x=np.array(probe_window/2), y=np.array(probe_window/2), name=name, showlegend=True, marker_color=color, opacity = 0))\n", - " fig7.add_annotation(x=probe_window/2, y=3*probe_window/4, text=\"Usable area \", showarrow=False, yshift=-15)\n", + " # fig7.add_annotation(x=probe_window/2, y=3*probe_window/4, text=\"Usable area \", font_color=\"#FFFFFF\", showarrow=False, yshift=-15)\n", "\n", " fig7.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.2, fillcolor=color, x0=probe_window/2-beam_diameter/8, y0=probe_window/2-beam_diameter/8, x1=probe_window/2+beam_diameter/8, y1=probe_window/2+beam_diameter/8, line_color=color,)\n", " fig7.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.2, fillcolor=color, x0=probe_window/2-beam_diameter/6, y0=probe_window/2-beam_diameter/6, x1=probe_window/2+beam_diameter/6, y1=probe_window/2+beam_diameter/6, line_color=color,)\n", @@ -814,13 +957,26 @@ " fig7.add_shape(type=\"circle\",xref=\"x\", yref=\"y\", opacity=0.4, fillcolor=color, x0=probe_window/2-beam_diameter/2, y0=probe_window/2-beam_diameter/2, x1=probe_window/2+beam_diameter/2, y1=probe_window/2+beam_diameter/2, line_color=color,)\n", "\n", " \n", - " fig7.update_xaxes(title_text=\"Probe window (nm)\", range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], ticktext = [0, np.round(probe_window/4,2),np.round(probe_window/4,2),np.round(probe_window/2,2),np.round(3*probe_window/4,2),np.round(probe_window,2)])\n", + " fig7.update_xaxes(title_text=\"Probe window (nm)\", range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], ticktext = [0, np.round(probe_window/4,2),np.round(probe_window/2,2),np.round(3*probe_window/4,2),np.round(probe_window,2)])\n", " fig7.update_yaxes(range=[0, probe_window], tickvals = [0, probe_window/4, probe_window/2, 3*probe_window/4, probe_window], showticklabels=False,)\n", " fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n", " fig7.update_yaxes(range=[0, probe_window], showticklabels=False,)\n", - " fig7.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=1.0,xanchor=\"right\",x=1))\n", + " fig7.update_layout(legend=dict(orientation=\"v\",yanchor=\"bottom\",y=1.01,xanchor=\"right\",x=1))\n", " fig7.update_layout(title={'text': \"Probe\",'y':0.975, 'x':0.10,'xanchor': 'left','yanchor': 'top'})\n", " fig7.update_layout(width=4*graph_size, height=4*graph_size, margin =dict(l=0.3*graph_size, r=0.3*graph_size, t=0.1*graph_size, b=0)) \n", + "\n", + "\n", + "\n", + "\n", + " fig7.update_layout(plot_bgcolor='white')\n", + " fig7.update_xaxes(mirror=True,ticks='outside',showline=True,linecolor='black',gridcolor='lightgrey')\n", + " fig7.update_yaxes(mirror=True,ticks='inside',showline=True,linecolor='black',gridcolor='lightgrey')\n", + " fig7.update_yaxes(title_font_color=\"#000000\")\n", + " fig7.update_xaxes(title_font_color=\"#000000\")\n", + "\n", + "\n", + "\n", + "\n", " \n", " ### CAMERA LENGTH TABLE ########################################## \n", " dictionary = {}\n", @@ -884,10 +1040,10 @@ " total = VBox([go.FigureWidget(fig8),go.FigureWidget(fig6)])\n", " case 'dedic':\n", " sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n", - " total = VBox([HBox([go.FigureWidget(fig)]), sample_overlap, cltab,checks]) \n", + " total = VBox([HBox([go.FigureWidget(fig),go.FigureWidget(fig9)]), sample_overlap, cltab,checks]) \n", " case _:\n", " sample_overlap = HBox([go.FigureWidget(fig5), go.FigureWidget(fig7)]) \n", - " right_column = VBox([HBox([go.FigureWidget(fig)]), sample_overlap, cltab,checks]) \n", + " right_column = VBox([HBox([go.FigureWidget(fig),go.FigureWidget(fig9)]), sample_overlap, cltab,checks]) \n", " left_column = VBox([go.FigureWidget(fig8), go.FigureWidget(fig6)]) \n", " total = HBox([left_column, right_column]) \n", " \n",