3.3. Example of potential slice generation

3.3.1. Prerequisites for running this example

Prior to running any scripts or Jupyter notebooks in the directory <root>/examples, where <root> is the root of the prismatique repository, a set of Python libraries need to be installed in the Python environment within which any such scripts or Jupyter notebooks are to be executed. See this page for instructions on how to do so.

3.3.2. Example description

In this example, we generate the potential slices for the bilayer \(\text{MoS}_2\) sample that we defined in the Example of atomic coordinate generation page. See the documentation for the class prismatique.discretization.Params for a discussion on potential slices.

3.3.3. Code

Below is the code that generates the aforementioned potential slices. You can also find the same code in the file <root>/examples/potential_slice_generator/generate.py of the repository, where <root> is the root of the prismatique repository. To run the script from the terminal, change into the directory containing said script, and then issue the following command:

python generate.py

The output files generated by this script are saved in the directory <root>/examples/data/potential_slice_generator_output, where <root> is the root of the prismatique repository. To analyze the output, use the Jupyter notebook <root>/examples/output_data_analysis_notebooks/analyzing_potential_slice_generator_output.ipynb.

If you would like to modify this script for your own work, it is recommended that you copy the original script and save it elsewhere outside of the git repository so that the changes made are not tracked by git.

# -*- coding: utf-8 -*-
# Copyright 2024 Matthew Fitzpatrick.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
"""An example of potential slice generation.

See the link
https://mrfitzpa.github.io/prismatique/examples/potential-slice-generator/generate.html
for a description of the example.

A NOTE BEFORE STARTING
----------------------

To run this script from the terminal as is, i.e. without modifications, change
into the directory containing said script, and then issue the following
command::

  python generate.py

The output files generated by this script are saved in the directory
``<root>/examples/data/potential-slice-generator-output``, where ``<root>`` is
the root of the ``prismatique`` repository. To analyze the output, use the
Jupyter notebook
``<root>/examples/output-data-analysis-notebooks/analyzing-potential-slices.ipynb``.

If you would like to modify this script for your own work, it is recommended
that you copy the original script and save it elsewhere outside of the git
repository so that the changes made are not tracked by git.

"""



#####################################
## Load libraries/packages/modules ##
#####################################

# For making directories and creating path objects.
import pathlib

# For spawning shell processes and getting the path to current script.
import os



# For generating the potential slices.
import prismatique



###############################################
## Define classes, functions, and contstants ##
###############################################



###########################
## Define error messages ##
###########################



#########################
## Main body of script ##
#########################

msg = "Generating the potential slices for the MoS2 sample..."
print(msg)
print()



# In another example script, we generate all the simulation parameters required
# to generate the potential slices, the S-matrices, and for simulating STEM and
# HRTEM experiments involving the MoS2 sample. Rather than set explicitly again
# all the simulation parameters required for potential slice generation, we can
# run the other script to generate the parameters if they do not already exist,
# then load a subset of these parameters in this current script, and use said
# parameters to generate the potential slices.
path_to_current_script = pathlib.Path(os.path.realpath(__file__))
path_to_examples_dir = str(path_to_current_script.parent.parent)
path_to_data_dir = path_to_examples_dir + "/data"
path_to_serialized_params = (path_to_data_dir
                             + "/sim_param_generator_output"
                             + "/prism_stem_sim_params.json")
for try_count in range(2):
    try:
        prism_stem_sim_params = \
            prismatique.stem.sim.Params.load(path_to_serialized_params)
        stem_system_model_params = \
            prism_stem_sim_params.core_attrs["stem_system_model_params"]
        sample_specification = \
            stem_system_model_params.core_attrs["sample_specification"]
        atomic_coords_filename = \
            sample_specification.core_attrs["atomic_coords_filename"]

        module_alias = prismatique.sample
        module_alias.check_atomic_coords_file_format(atomic_coords_filename)



        # Lastly, we use a subset of the parameters loaded above to generate the
        # potential slices. See the documentation for the function
        # :func:`prismatique.sample.generate_potential_slices` for a discussion
        # on the input parameters of said function, and the organization of the
        # output files.
        output_dirname = path_to_data_dir + "/potential_slice_generator_output"
        worker_params = prism_stem_sim_params.core_attrs["worker_params"]
        kwargs = {"sample_model_params": sample_specification,
                  "output_dirname": output_dirname,
                  "max_data_size": 2*10**9,  # In bytes.
                  "worker_params": worker_params}
        prismatique.sample.generate_potential_slices(**kwargs)



        break  # No exceptions raised, hence we can exit the for-loop early.

    except:
        msg = ("Need to generate the simulation parameter sets for the various "
               "simulated experiments involving the MoS2 sample...")
        print(msg)
        print()
        script_to_execute = (path_to_examples_dir
                             + "/sim_param_generator/generate.py")
        os.system("python " + script_to_execute)
        msg = ("Resuming the generation of the potential slices for the MoS2 "
               "sample...")
        print(msg)
        print()



msg = ("Finished generating all the potential slices for the MoS2 sample: "
       "all output files were saved in the directory {}"
       ".".format(output_dirname))
print(msg)
print()