Update Activity 8
This commit is contained in:
		
							parent
							
								
									d00c537f30
								
							
						
					
					
						commit
						6996ac97fc
					
				|  | @ -9,12 +9,85 @@ | |||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "code", | ||||
|    "execution_count": null, | ||||
|    "id": "1df76138-c957-4da2-bcc8-ec977c209b81", | ||||
|    "cell_type": "markdown", | ||||
|    "id": "394b0c02-f28e-4074-86e5-9dfdf0447adb", | ||||
|    "metadata": {}, | ||||
|    "outputs": [], | ||||
|    "source": [] | ||||
|    "source": [ | ||||
|     "intro" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "attachments": {}, | ||||
|    "cell_type": "markdown", | ||||
|    "id": "5a4036dc-d087-419f-9a44-749a8b313d5c", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     "(aln-paper)=\n", | ||||
|     ":::{seealso}\n", | ||||
|     "based on this paper from V. Lebedev *et al.*\n", | ||||
|     "[J. Cryst. Growth. **207(4)** p266-72 (1999)](https://doi.org/10.1016/S0022-0248(99)00375-9)\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "markdown", | ||||
|    "id": "fc1cf08e-77ba-49ea-99a9-8a7bac7c98c7", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     ":::{figure-md} AlN-fig1\n", | ||||
|     "<img src=\"fig1.jpg\" alt=\"AlN growth\" width=\"600px\" align=\"center\">\n", | ||||
|     "\n", | ||||
|     "legend\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "markdown", | ||||
|    "id": "fc180c7b-eb23-47c6-8d18-e092bc777843", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     ":::{figure-md} AlN-fig2\n", | ||||
|     "<img src=\"fig2.jpg\" alt=\"AlN crystal direction\" width=\"600px\" align=\"center\">\n", | ||||
|     "\n", | ||||
|     "legend\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "markdown", | ||||
|    "id": "86c20245-abca-4587-bccf-90e0fb09f73c", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     ":::{figure-md} AlN-fig3\n", | ||||
|     "<img src=\"fig3.jpg\" alt=\"AlN XPD\" width=\"400px\" align=\"center\">\n", | ||||
|     "\n", | ||||
|     "legend\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "markdown", | ||||
|    "id": "8a3a48ef-196f-435a-b342-3a73e62160f8", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     ":::{figure-md} AlN-fig4\n", | ||||
|     "<img src=\"fig4.jpg\" alt=\"AlN number of clusters\" width=\"600px\" align=\"center\">\n", | ||||
|     "\n", | ||||
|     "legend\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   }, | ||||
|   { | ||||
|    "cell_type": "markdown", | ||||
|    "id": "abc64fdb-5895-4112-a987-66b3420d78eb", | ||||
|    "metadata": {}, | ||||
|    "source": [ | ||||
|     ":::{figure-md} AlN-fig5\n", | ||||
|     "<img src=\"fig5.jpg\" alt=\"AlN results\" width=\"600px\" align=\"center\">\n", | ||||
|     "\n", | ||||
|     "legend\n", | ||||
|     ":::" | ||||
|    ] | ||||
|   } | ||||
|  ], | ||||
|  "metadata": { | ||||
|  |  | |||
|  | @ -0,0 +1,131 @@ | |||
| #!/usr/bin/env python | ||||
| # coding: utf8 | ||||
| 
 | ||||
| 
 | ||||
| from ase.build import bulk | ||||
| import numpy as np | ||||
| from msspec.calculator import MSSPEC, XRaySource | ||||
| from msspec.utils import hemispherical_cluster, get_atom_index | ||||
| 
 | ||||
| def create_clusters(nplanes=6): | ||||
|     def get_AlN_tags_planes(side, emitter): | ||||
|         AlN = # AlN is a Wurtzite crystal with a=3.11 and c=4.975 angstroms       # <= HERE | ||||
|         [atom.set('tag', i) for i, atom in enumerate(AlN)] | ||||
|         if side == 'Al': | ||||
|             AlN.rotate([0,0,1],[0,0,-1]) | ||||
|             Al_planes = range(0, nplanes, 2) | ||||
|             N_planes  = range(1, nplanes, 2) | ||||
|         else: | ||||
|             N_planes  = range(0, nplanes, 2) | ||||
|             Al_planes = range(1, nplanes, 2) | ||||
|         if emitter == 'Al': | ||||
|             tags = [0, 2] | ||||
|             planes = Al_planes | ||||
|         else: | ||||
|            tags = [1, 3] | ||||
|            planes = N_planes | ||||
|         return AlN, tags, planes | ||||
| 
 | ||||
|     clusters = [] | ||||
|     for side in ('Al', 'N'): | ||||
|         for emitter in ('Al', 'N'): | ||||
|             AlN, tags, planes = get_AlN_tags_planes(side, emitter) | ||||
|             for emitter_tag in tags: | ||||
|                 for emitter_plane in planes: | ||||
|                     cluster = # hemis…, construct the cluster here with           # <= HERE | ||||
|                               # 2 planes below the emitter | ||||
|                     cluster.absorber = get_atom_index(cluster, 0, 0, 0) | ||||
|                     cluster.info.update({ | ||||
|                         'emitter_plane': emitter_plane, | ||||
|                         'emitter_tag'  : emitter_tag, | ||||
|                         'emitter'      : emitter, | ||||
|                         'side'         : side, | ||||
|                     }) | ||||
|                     clusters.append(cluster) | ||||
|                     print("Added cluster {}-side, emitter {}(tag {:d}) in " | ||||
|                           "plane #{:d}".format(side, emitter, emitter_tag, | ||||
|                                                emitter_plane)) | ||||
|     return clusters | ||||
| 
 | ||||
| 
 | ||||
| def compute(clusters, theta=np.arange(-20., 80., 1.), phi=0.): | ||||
|     data = None | ||||
|     for ic, cluster in enumerate(clusters): | ||||
|         # Retrieve info from cluster object | ||||
|         side    = cluster.info['side'] | ||||
|         emitter = cluster.info['emitter'] | ||||
|         plane   = cluster.info['emitter_plane'] | ||||
|         tag     = cluster.info['emitter_tag'] | ||||
| 
 | ||||
|         # Set the level and the kinetic energy | ||||
|         if emitter == 'Al': | ||||
|             level = #####                                                         # <= HERE | ||||
|             ke    = #####                                                         # <= HERE | ||||
|         elif emitter == 'N': | ||||
|             level = #####                                                         # <= HERE | ||||
|             ke    = #####                                                         # <= HERE | ||||
| 
 | ||||
|         calc = # Create a calculator using the RA series expansion algorithm      # <= HERE | ||||
| 
 | ||||
|         calc.source_parameters.energy = #####                                     # <= HERE | ||||
|         calc.source_parameters.theta  = #####                                     # <= HERE | ||||
| 
 | ||||
|         calc.detector_parameters.angular_acceptance = #####                       # <= HERE | ||||
|         calc.detector_parameters.average_sampling   = 'medium' | ||||
| 
 | ||||
|         calc.calculation_parameters.scattering_order = max(1, min(4, plane)) | ||||
|         calc.calculation_parameters.path_filtering  = 'forward_scattering' | ||||
|         calc.calculation_parameters.off_cone_events = 1 | ||||
|         [a.set('forward_angle', 30.) for a in cluster] | ||||
| 
 | ||||
|         calc.set_atoms(cluster) | ||||
| 
 | ||||
|         data = calc.get_theta_scan(level=level, theta=theta, phi=phi, | ||||
|                                    kinetic_energy=ke, data=data) | ||||
|         dset = data[-1] | ||||
|         dset.title = "\'{}\' side - {}({}) tag #{:d}, plane #{:d}".format( | ||||
|             side, emitter, level, tag, plane) | ||||
| 
 | ||||
|     return data | ||||
| 
 | ||||
| 
 | ||||
| def analysis(data): | ||||
|     tmp_data = {} | ||||
|     for dset in data: | ||||
|         info = dset.get_cluster().info | ||||
|         side = info['side'] | ||||
|         emitter = info['emitter'] | ||||
|         try: | ||||
|             key = '{}_{}'.format(side, emitter) | ||||
|             tmp_data[key] += dset.cross_section | ||||
|         except KeyError: | ||||
|             tmp_data[key] = dset.cross_section.copy() | ||||
| 
 | ||||
|     tmp_data['theta']   = dset.theta.copy() | ||||
|     tmp_data['Al_side'] = tmp_data['Al_Al'] / tmp_data['Al_N'] | ||||
|     tmp_data['N_side']  = tmp_data['N_Al']  / tmp_data['N_N'] | ||||
| 
 | ||||
|     # now add all columns | ||||
|     substrate_dset = data.add_dset('Total substrate signal') | ||||
|     substrate_dset.add_columns(**tmp_data) | ||||
| 
 | ||||
|     view = substrate_dset.add_view('Ratios', | ||||
|                                    title=r'Al(2p)/N(1s) ratios on both polar ' | ||||
|                                          r'sides of AlN in the (10$\bar{1}$0) ' | ||||
|                                          r'azimuthal plane', | ||||
|                                    xlabel=r'$\Theta (\degree$)', | ||||
|                                    ylabel='Intenisty ratio') | ||||
|     view.select('theta', 'Al_side', legend='Al side', | ||||
|                 where="theta >= 0 and theta <=70") | ||||
|     view.select('theta', 'N_side', legend='N side', | ||||
|                 where="theta >= 0 and theta <=70") | ||||
|     view.set_plot_options(autoscale=True) | ||||
| 
 | ||||
|     return data | ||||
| 
 | ||||
| 
 | ||||
| clusters = create_clusters() | ||||
| data     = compute(clusters) | ||||
| data     = analysis(data) | ||||
| data.view() | ||||
| 
 | ||||
|  | @ -0,0 +1,132 @@ | |||
| #!/usr/bin/env python | ||||
| # coding: utf8 | ||||
| 
 | ||||
| from ase.build import bulk | ||||
| import numpy as np | ||||
| from msspec.calculator import MSSPEC, XRaySource | ||||
| from msspec.utils import hemispherical_cluster, get_atom_index | ||||
| 
 | ||||
| def create_clusters(nplanes=6): | ||||
|     def get_AlN_tags_planes(side, emitter): | ||||
|         AlN = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975) | ||||
|         [atom.set('tag', i) for i, atom in enumerate(AlN)] | ||||
|         if side == 'Al': | ||||
|             AlN.rotate([0,0,1],[0,0,-1]) | ||||
|             Al_planes = range(0, nplanes, 2) | ||||
|             N_planes  = range(1, nplanes, 2) | ||||
|         else: | ||||
|             N_planes  = range(0, nplanes, 2) | ||||
|             Al_planes = range(1, nplanes, 2) | ||||
|         if emitter == 'Al': | ||||
|             tags = [0, 2] | ||||
|             planes = Al_planes | ||||
|         else: | ||||
|            tags = [1, 3] | ||||
|            planes = N_planes | ||||
|         return AlN, tags, planes | ||||
| 
 | ||||
|     clusters = [] | ||||
|     for side in ('Al', 'N'): | ||||
|         for emitter in ('Al', 'N'): | ||||
|             AlN, tags, planes = get_AlN_tags_planes(side, emitter) | ||||
|             for emitter_tag in tags: | ||||
|                 for emitter_plane in planes: | ||||
|                     cluster = hemispherical_cluster(AlN, | ||||
|                                                     emitter_tag=emitter_tag, | ||||
|                                                     emitter_plane=emitter_plane, | ||||
|                                                     planes=emitter_plane+2) | ||||
|                     cluster.absorber = get_atom_index(cluster, 0, 0, 0) | ||||
|                     cluster.info.update({ | ||||
|                         'emitter_plane': emitter_plane, | ||||
|                         'emitter_tag'  : emitter_tag, | ||||
|                         'emitter'      : emitter, | ||||
|                         'side'         : side, | ||||
|                     }) | ||||
|                     clusters.append(cluster) | ||||
|                     print("Added cluster {}-side, emitter {}(tag {:d}) in " | ||||
|                           "plane #{:d}".format(side, emitter, emitter_tag, | ||||
|                                                emitter_plane)) | ||||
|     return clusters | ||||
| 
 | ||||
| 
 | ||||
| def compute(clusters, theta=np.arange(-20., 80., 1.), phi=0.): | ||||
|     data = None | ||||
|     for ic, cluster in enumerate(clusters): | ||||
|         # Retrieve info from cluster object | ||||
|         side    = cluster.info['side'] | ||||
|         emitter = cluster.info['emitter'] | ||||
|         plane   = cluster.info['emitter_plane'] | ||||
|         tag     = cluster.info['emitter_tag'] | ||||
| 
 | ||||
|         # Set the level and the kinetic energy | ||||
|         if emitter == 'Al': | ||||
|             level = '2p' | ||||
|             ke    = 1407. | ||||
|         elif emitter == 'N': | ||||
|             level = '1s' | ||||
|             ke    = 1083. | ||||
| 
 | ||||
|         calc = MSSPEC(spectroscopy='PED', algorithm='expansion') | ||||
| 
 | ||||
|         calc.source_parameters.energy = XRaySource.AL_KALPHA | ||||
|         calc.source_parameters.theta  = -35 | ||||
| 
 | ||||
|         calc.detector_parameters.angular_acceptance = 4. | ||||
|         calc.detector_parameters.average_sampling   = 'medium' | ||||
| 
 | ||||
|         calc.calculation_parameters.scattering_order = max(1, min(4, plane)) | ||||
|         calc.calculation_parameters.path_filtering  = 'forward_scattering' | ||||
|         calc.calculation_parameters.off_cone_events = 1 | ||||
|         [a.set('forward_angle', 30.) for a in cluster] | ||||
| 
 | ||||
|         calc.set_atoms(cluster) | ||||
| 
 | ||||
|         data = calc.get_theta_scan(level=level, theta=theta, phi=phi, | ||||
|                                    kinetic_energy=ke, data=data) | ||||
|         dset = data[-1] | ||||
|         dset.title = "\'{}\' side - {}({}) tag #{:d}, plane #{:d}".format( | ||||
|             side, emitter, level, tag, plane) | ||||
| 
 | ||||
|     return data | ||||
| 
 | ||||
| 
 | ||||
| def analysis(data): | ||||
|     tmp_data = {} | ||||
|     for dset in data: | ||||
|         info = dset.get_cluster().info | ||||
|         side = info['side'] | ||||
|         emitter = info['emitter'] | ||||
|         try: | ||||
|             key = '{}_{}'.format(side, emitter) | ||||
|             tmp_data[key] += dset.cross_section | ||||
|         except KeyError: | ||||
|             tmp_data[key] = dset.cross_section.copy() | ||||
| 
 | ||||
|     tmp_data['theta']   = dset.theta.copy() | ||||
|     tmp_data['Al_side'] = tmp_data['Al_Al'] / tmp_data['Al_N'] | ||||
|     tmp_data['N_side']  = tmp_data['N_Al']  / tmp_data['N_N'] | ||||
| 
 | ||||
|     # now add all columns | ||||
|     substrate_dset = data.add_dset('Total substrate signal') | ||||
|     substrate_dset.add_columns(**tmp_data) | ||||
| 
 | ||||
|     view = substrate_dset.add_view('Ratios', | ||||
|                                    title=r'Al(2p)/N(1s) ratios on both polar ' | ||||
|                                          r'sides of AlN in the (10$\bar{1}$0) ' | ||||
|                                          r'azimuthal plane', | ||||
|                                    xlabel=r'$\Theta (\degree$)', | ||||
|                                    ylabel='Intenisty ratio') | ||||
|     view.select('theta', 'Al_side', legend='Al side', | ||||
|                 where="theta >= 0 and theta <=70") | ||||
|     view.select('theta', 'N_side', legend='N side', | ||||
|                 where="theta >= 0 and theta <=70") | ||||
|     view.set_plot_options(autoscale=True) | ||||
| 
 | ||||
|     return data | ||||
| 
 | ||||
| 
 | ||||
| clusters = create_clusters() | ||||
| data     = compute(clusters) | ||||
| data     = analysis(data) | ||||
| data.view() | ||||
| 
 | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 438 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 304 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 39 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 513 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 296 KiB | 
		Loading…
	
		Reference in New Issue