{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0cbf2f32",
   "metadata": {
    "id": "m5yYPGDk-NIu"
   },
   "source": [
    "# Hello SAFIRE\n",
    "\n",
    "<b>Goal:</b>\n",
    "At the end of this tutorial, you will know how to run an AFQMC calculation using SAFIRE and extract the AFQMC energy from the output\n",
    "given all necessary inputs.\n",
    "\n",
    "## What you will learn\n",
    "\n",
    "1. what are the inputs and outputs of SAFIRE.\n",
    "2. how to invoke the SAFIRE executable from the command line in serial, using MPI, and using GPU(s)\n",
    "3. how to extract the AFQMC energy from the outputs of SAFIRE using afqmctools\n",
    "4. how to use the tutorial helper functions to perform 2 and 3 from within an interactive Python notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0669e14",
   "metadata": {
    "id": "7FBZ0COY-NIw"
   },
   "source": [
    "<b>\n",
    "Inputs and outputs of SAFIRE.\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "The purpose of this tutorial is to run a first AFQMC calculation without going into low-level details.\n",
    "\n",
    "<!--\n",
    "AFQMC is formulated in terms of a generic second quantized Hamiltonian and trial wavefunction.\n",
    "In order to take advantage of this flexibility, SAFIRE accepts a generic\n",
    "second quantized Hamiltonian and wavefunction, saved in HDF5 files, as input along with\n",
    "AFQMC algorithmic parameters in a json-based input file.\n",
    "-->\n",
    "\n",
    "Below is a schematic of the inputs and outputs of SAFIRE.\n",
    "\n",
    "<!---\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_all.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_all.png)\n",
    "\n",
    "We will learn more about the details of all of these files in future tutorials. For this tutorial, pregenerated input files are provided in the \"files\" directory relative to the directory of this tutorial."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff3f56fb",
   "metadata": {
    "id": "tMJ2Y4re-NIw"
   },
   "source": [
    "<b>The Inputs\n",
    "</b>\n",
    "\n",
    "---\n",
    "To perform a calculation, SAFIRE requires a Hamiltonian and a trial wave function. Both are provided as inputs using the files \"hamil.h5\" and \"wfn.h5\", respectively. The file \"input.json\" references these two files and provides further information about how the simulation should be run.\n",
    "\n",
    "<b> Hamiltonian file : \"hamil.h5\"\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_hamil.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_hamil.png)\n",
    "\n",
    "This HDF5 file contains the second-quantized Hamiltonian $\\hat{H}$.\n",
    "\n",
    "For this tutorial, we have supplied an HDF5 file containing the Born-Oppenheimer\n",
    "Hamiltonian for Si in its primitive cell at equilibrium\n",
    "in \"hamil.h5\".\n",
    "\n",
    "![](files/Si_primitive.png)\n",
    "\n",
    "For technical details on the Hamiltonian HDF5 format, see [the User Guide](https://users.flatironinstitute.org/~beskridge/auxiliary_fields/afqmc.html#dense-cholesky).\n",
    "\n",
    "<b> Wavefunction file : \"wfn.h5\"\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_wfn.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_wfn.png)\n",
    "\n",
    "This HDF5 file contains the trial wavefunction, $| \\Psi_\\mathrm{T} \\rangle$.\n",
    "\n",
    "For this tutorial, we have supplied an HDF5 file containing the RHF\n",
    "ground state as the trial wavefunction.\n",
    "\n",
    "$$\n",
    "| \\Psi_\\mathrm{T} \\rangle = | \\Phi_\\mathrm{RHF} \\rangle\n",
    "$$\n",
    "\n",
    "For technical details on the wavefunction HDF5 format, see [the User Guide](https://users.flatironinstitute.org/~beskridge/auxiliary_fields/afqmc.html#wavefunction-file-formats).\n",
    "\n",
    "<b> Input file (json format) : \"input.json\"\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_json.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_json.png)\n",
    "\n",
    "The JSON input file sets AFQMC run parameters and references the locations of the Hamiltonian and trial wavefunction files. It is organized into a hierarchy of input blocks which each control specific\n",
    "details of the calculation. Understanding the details of the input file is the goal of the next tutorial, [Understanding the input file](https://safire.flatironinstitute.org/docs/dev/tutorials/solids/02_understanding_the_input_file/02_understanding_the_input_file.html).\n",
    "\n",
    "**For now, we focus on the `wavefunction` and `hamiltonian` blocks.**\n",
    "\n",
    "The `wavefunction` input block is used to tell SAFIRE where to find the HDF5 file containing the trial wavefunction.\n",
    "Similarly, the `hamiltonian` input block is used to tell SAFIRE where to find the HDF5 file containing the Hamiltonian.  \n",
    "\n",
    "The sample json file that we have provided is reproduced here.\n",
    "\n",
    "```json\n",
    "{\n",
    "\"afqmc\": {\n",
    "  \"project\": {\n",
    "    \"id\": \"qmc\",\n",
    "    \"series\": 0\n",
    "  },\n",
    "  \"execute\": {\n",
    "    \"walker_set\": {\n",
    "      \"walker_type\": \"CLOSED\"\n",
    "    },\n",
    "    \"wavefunction\": {\n",
    "      \"filename\": \"files/wfn.h5\"\n",
    "    },\n",
    "    \"hamiltonian\": {\n",
    "      \"filename\": \"files/hamil.h5\"\n",
    "    },\n",
    "    \"timestep\": 0.01,\n",
    "    \"steps\": 10000,\n",
    "    \"n_walkers_per_mpi_task\": 200,\n",
    "    \"seed\": 42\n",
    "  }\n",
    "}\n",
    "}\n",
    "```\n",
    "  \n",
    "Notice that the `wavefunction` and `hamiltonian` input blocks point to the HDF5 file where we have saved the RHF ground\n",
    "state and second-quantized Hamiltonian, respectively."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "849c1c89",
   "metadata": {
    "id": "dWRr3WmB-NIw"
   },
   "source": [
    "<b>The Outputs\n",
    "</b>\n",
    "\n",
    "---\n",
    "Now that we have seen the inputs of SAFIRE, we will move on to the outputs.\n",
    "\n",
    "<b> stdout\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "SAFIRE prints information about the setup of the AFQMC calculation to stdout along with timing information at the end.\n",
    "\n",
    "We will see the output from SAFIRE throughout the tutorials. Here is a sample header which is printed at the beginning of\n",
    "the output.\n",
    "\n",
    "```\n",
    "\n",
    "███████╗ █████╗ ███████╗██╗██████╗ ███████╗\n",
    "██╔════╝██╔══██╗██╔════╝██║██╔══██╗██╔════╝\n",
    "███████╗███████║█████╗  ██║██████╔╝█████╗  \n",
    "╚════██║██╔══██║██╔══╝  ██║██╔══██╗██╔══╝  \n",
    "███████║██║  ██║██║     ██║██║  ██║███████╗\n",
    "╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝╚══════╝\n",
    "\n",
    "\n",
    "AF App version: 1.0.0\n",
    "app git branch: fix_compiler_warnings\n",
    "app git commit: 83a5e18c30fe824a77185cdb5df6e4dba2918f5c\n",
    " AFQMCFactory Project settings:\n",
    "    -- ncores (local) : 1\n",
    "    -- n_groups       : 1\n",
    "    -- id             : qmc\n",
    "    -- series         : 0\n",
    "    -- MPI tasks/node : 1\n",
    "    -- MPI nodes      : 1\n",
    "    -- MPI tasks      : 1\n",
    "\n",
    "\n",
    "```\n",
    "\n",
    "You can see git information from when SAFIRE was compiled.\n",
    "You can also see MPI / parallelization information.\n",
    "We will explore the output further in later tutorials.\n",
    "\n",
    "<b> scalar data file : [id].s[series].scalar.dat\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_scalar.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_scalar.png)\n",
    "\n",
    "A text-based file containing stochastic samples of scalar data, such as the energy.\n",
    "\n",
    "This file is not meant to be read directly by the user.\n",
    "Instead, afqmctools provides tools to extract information from this file.\n",
    "**We will learn how to extract the AFQMC energy from this file later in this tutorial.**\n",
    "\n",
    "The name of this file is derived from the `id` (string) and `series` (integer) parameters set in the json input file. Setting these parameters allows running multiple AFQMC calculations in a single directory without output file collisions.\n",
    "\n",
    "<b> observables output HDF5 file : [id].s[series].stat.h5\n",
    "</b>\n",
    "\n",
    "---\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/inputs_and_outputs_hdf5.png\" width=\"800\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/inputs_and_outputs_hdf5.png)\n",
    "\n",
    "An HDF5 file where stochastic samples of non-scalar data, such as the one-body reduced density matrix, are printed by SAFIRE\n",
    "when requested.\n",
    "\n",
    "Similar to the `[id].s[series].scalar.dat` file, this file is not meant to be read directly by a user.\n",
    "Instead, afqmctools provides tools to extract data from this file for you.\n",
    "You will learn more about this in [Computing general observables](https://safire.flatironinstitute.org/docs/dev/tutorials/solids/04_computing_observables/04_computing_observables.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "afcab98a",
   "metadata": {
    "id": "Yhdjs78S-NIx"
   },
   "source": [
    "## Running SAFIRE\n",
    "\n",
    "Now that we have learned what the inputs and outputs of SAFIRE are,\n",
    "we are ready to learn how to run the SAFIRE executable given the inputs.\n",
    "\n",
    "### Running SAFIRE in serial\n",
    "\n",
    "SAFIRE can be invoked from the command line as\n",
    "\n",
    "```bash\n",
    "    $ /path/to/SAFIRE/build/bin/safire input.json\n",
    "```\n",
    "\n",
    "where `input.json` is the json input file.\n",
    "The input file can have an arbitrary name, but must end with `.json`.\n",
    "When you run the above, an AFQMC calculation will be performed based on the contents of input.json,\n",
    "using the Hamiltonian and trial wavefunction specified there.\n",
    "\n",
    "**For brevity, we will abbreviate `/path/to/SAFIRE/build/bin/safire` as `safire` in this tutorial**.\n",
    "There are many standard ways to make `safire` accessible from the command line in this way.\n",
    "\n",
    "You can see the possible command line options for SAFIRE by using the `-h`/`--help` switch.\n",
    "\n",
    "```bash\n",
    "    $ safire --help\n",
    "\n",
    "SAFIRE\n",
    "Usage:\n",
    "  /path/to/SAFIRE/build/bin/safire [OPTION...] [optional args]\n",
    "\n",
    "  -h, --help           print help message\n",
    "  -v, --version        print version message\n",
    "      --verbosity arg  0, 1, 2, ...: higher means more (default: 2)\n",
    "      --debug arg      0, 1, 2, ...: higher means more (default: 0)\n",
    "      --filenames arg  input filenames\n",
    "```\n",
    "\n",
    "### Exercise: Try Running SAFIRE.\n",
    "\n",
    "Run SAFIRE with the provided input files.\n",
    "You may use either the code block below, or run SAFIRE in a terminal\n",
    "as described previously.\n",
    "In either case, you can find the json input file here\n",
    "\n",
    "```bash\n",
    "    /path/to/SAFIRE/tutorials/molecules/files/input.json\n",
    "```\n",
    "\n",
    "where `/path/to/SAFIRE` should be replaced with the path where\n",
    "you have installed SAFIRE.\n",
    "\n",
    "**The provided json input file assumes that you are running SAFIRE from\n",
    "`/path/to/SAFIRE/tutorials/01_hello_auxiliary_fields/`**\n",
    "\n",
    "After running with the default parameters, try changing the verbosity level to\n",
    "see what changes.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Note:</b>\n",
    "    in a jupyter notebook, the `!` symbol will run commands in\n",
    "    a shell instead of in Python.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c7823df",
   "metadata": {},
   "outputs": [],
   "source": [
    "!$AFQMC_EXEC files/input.json"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbe41ce2",
   "metadata": {
    "id": "eShMF9Ab-NIy"
   },
   "source": [
    "### Post-exercise\n",
    "\n",
    "You should see the following a the top of the\n",
    "output after running SAFIRE.\n",
    "\n",
    "```\n",
    "███████╗ █████╗ ███████╗██╗██████╗ ███████╗\n",
    "██╔════╝██╔══██╗██╔════╝██║██╔══██╗██╔════╝\n",
    "███████╗███████║█████╗  ██║██████╔╝█████╗  \n",
    "╚════██║██╔══██║██╔══╝  ██║██╔══██╗██╔══╝  \n",
    "███████║██║  ██║██║     ██║██║  ██║███████╗\n",
    "╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝╚══════╝\n",
    "\n",
    "\n",
    "AF App version: 1.0.0\n",
    "This build has the following enabled:\n",
    " - MKL:  1\n",
    " - CUDA: 0\n",
    " - HIP:  0\n",
    "app git branch: develop\n",
    "app git commit: ee49a5e69208e2afc03aab970572b9e79759e543\n",
    "app git commit date: Fri Nov 7 13:27:02 2025 -0500\n",
    " AFQMCFactory Project settings:\n",
    "    -- ncores (local) : 1\n",
    "    -- n_groups       : 1\n",
    "    -- id             : qmc\n",
    "    -- series         : 0\n",
    "    -- MPI tasks/node : 1\n",
    "    -- MPI nodes      : 1\n",
    "    -- MPI tasks      : 1\n",
    "\n",
    "```\n",
    "\n",
    "Congratulations, you have now run an AFQMC calculation using SAFIRE!\n",
    "In the directory that you ran this notebook from, you should see a file called\n",
    "`qmc.s000.scalar.dat`.\n",
    "We will return to how to use the tools in `afqmctools` to extract the AFQMC energy later in this tutorial."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6098bd45",
   "metadata": {
    "id": "L0YADhMN-NIy"
   },
   "source": [
    "## Running SAFIRE in parallel\n",
    "\n",
    "### Using MPI\n",
    "\n",
    "SAFIRE can be run with MPI in the usual ways.\n",
    "For example, using mpirun, we could run SAFIRE with 64 MPI tasks as\n",
    "\n",
    "```bash\n",
    "    $ mpirun -np 64 safire --filenames input.json\n",
    "```\n",
    "\n",
    "It is important to note that the number of walkers is specified in the input file\n",
    "as `n_walkers_per_mpi_task`.\n",
    "So, the total number of walkers using the sample input file above and 64 MPI tasks\n",
    "would be\n",
    "\n",
    "$$\n",
    "N_\\mathrm{walkers} = n_\\mathrm{walkers\\_per\\_mpi} \\times n_\\mathrm{mpi\\_task} = 200 \\times 64 = 12800.\n",
    "$$\n",
    "\n",
    "For the sample inputs, this is significantly more walkers than necessary,\n",
    "and for calculations that run on a CPU only build of SAFIRE,\n",
    "`n_walkers_per_mpi_task` will typically be on the order of 10-50.\n",
    "\n",
    "### GPU Builds\n",
    "\n",
    "To run on GPUs, you must compile SAFIRE for the GPU.\n",
    "See the [documentation](https://users.flatironinstitute.org/~beskridge/auxiliary_fields/getting_started.html#gpu-accelerated-build-at-ccq) for instructions on compiling for GPU.\n",
    "\n",
    "On GPU builds of SAFIRE, the calculation is more efficient when\n",
    "the GPU is saturated.\n",
    "The specific number of walkers needed to achieve this depends on how large the system is and how much memory is available on the GPUs.\n",
    "For small systems, this could mean using on the order of 1000 walkers or more per task.\n",
    "For very large systems, this may mean on the order of 10 walkers per MPI task."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7298be70",
   "metadata": {
    "id": "ifrwtXzA-NIy"
   },
   "source": [
    "## Basic post-processing\n",
    "\n",
    "Now that we've learned how to invoke the SAFIRE executable from the command line in serial, using MPI, and using GPU(s),\n",
    "we are ready to learn how to extract the AFQMC energy from the outputs using afqmctools.\n",
    "\n",
    "We previously ran SAFIRE on the Hamiltonian of the STO-3G basis hydrogen dimer\n",
    "with bondlength $\\delta_{H-H} = 1.4 a_0$.\n",
    "This generated a scalar data file, `qmc.s000.scalar.dat`, which contains\n",
    "the scalar data that was accumulated during the AFQMC calculation, including the AFQMC energy.\n",
    "\n",
    "afqmctools provides the `scalar_stats` CLI tool to extract data from the scalar data file.\n",
    "If you followed the official installation instructions for `afqmctools`, you\n",
    "should be able to run `$ scalar_stats` from within whichever Python environment you\n",
    "installed afqmctools in.\n",
    "\n",
    "By default, `scalar_stats` will compute the average AFQMC energy and the stochastic uncertainty of the\n",
    "energy based on the samples in the `*.scalar.dat` file.\n",
    "Below is an example of using `scalar_stats` where we have set the \"x axis\" to (AFQMC projection) time,\n",
    "and the equilibration time to 2.0 inverse energy units.\n",
    "\n",
    "```bash\n",
    "$ scalar_stats qmc.s000.scalar.dat -s time -e 2.0\n",
    "\n",
    "====== [analyze_scalar_data Settings] ======\n",
    "\n",
    "[+] fname            = qmc.s000.scalar.dat\n",
    "[+] mark_header      = #               \n",
    "[+] series_column    = time           \n",
    "[+] nequil           = 2.0             \n",
    "[+] estimate_equil   = False           \n",
    "[+] column           = LocalEnergy     \n",
    "[+] reblock          = 1               \n",
    "[+] ndiscard         = None            \n",
    "[+] list             = False           \n",
    "[+] trace            = False           \n",
    "[+] append           = None            \n",
    "[+] dump             = False           \n",
    "[+] dump_fname       = trace.dat       \n",
    "[+] verbose          = True            \n",
    "[+] autocorr         = None            \n",
    "[+] savefig          = None            \n",
    "[+] dump_avail_columns = False           \n",
    "\n",
    "AFQMC Energy    -1.135742 +/-   0.000286 7.87  2.0/100.0\n",
    "```\n",
    "\n",
    "You can also view the AFQMC energy as a function of the projection time (sometimes referred to as the \"equilibration curve\") by\n",
    "adding the `-t` option to plot the data trace.\n",
    "\n",
    "Running\n",
    "\n",
    "```bash\n",
    "$ scalar_stats qmc.s000.scalar.dat -s time -e 2.0 -t\n",
    "```\n",
    "\n",
    "will generate the plot,\n",
    "\n",
    "<!--\n",
    "<div>\n",
    "<img src=\"./figs/HelloAuxyFields_equil.png\" width=\"600\"/>\n",
    "</div>\n",
    "-->\n",
    "\n",
    "![](files/Equil_Si_prim_01_hello_safire.png)\n",
    "\n",
    "One should check the equilibration curve to ensure that the equilibration\n",
    "time, `-s time -e 2.0`, is large enough to discard the samples where AFQMC is not sampling from the target many-body wavefunction yet.\n",
    "On the other hand, the equilibration length should not be so large that it discards equilibrated samples.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Note:</b>\n",
    "    Using the `-t` option to plot the trace will only work when running locally;\n",
    "    you can use the `--savefig [SAVEFIG]` option to save the figure as an image\n",
    "    in the file \"SAVEFIG\". The file type is detected from the file extension in\n",
    "    the name. *.png is generally recommended.\n",
    "</div>\n",
    "\n",
    "### Exercise: Try Running scalar_stats\n",
    "\n",
    "Use the code block below to run scalar_stats on the data that we generated\n",
    "in the last exercise.\n",
    "You should get an AFQMC energy of `-1.135742 +/-   0.000286`\n",
    "if you did not change any settings.\n",
    "\n",
    "Now, try to changing the equilibration length such that only un-equilibrated samples\n",
    "are discarded."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc90698b",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "-Ej94zXY-NIz",
    "outputId": "74fb0dab-3f45-4fac-ea34-2931de197dcb"
   },
   "outputs": [],
   "source": [
    "!scalar_stats qmc.s000.scalar.dat -s time -e 2.0 -t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d019ab62",
   "metadata": {
    "id": "Q7NGQf5v-NIz"
   },
   "source": [
    "## Post Exercise\n",
    "\n",
    "If you play around with the equilibration length, you will see that, for very small equilibration length,\n",
    "the predicted energy will be incorrect.\n",
    "This is due to the inclusion of un-equilibrated samples in the average.\n",
    "On the other hand, the average energy should be stable if you use too large of a value for the equilibration length."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e605abc5",
   "metadata": {
    "id": "HxaTJ4Rd-NIz"
   },
   "source": [
    "## Some Tutorial Helper Python Functions\n",
    "\n",
    "Now that we have learned how to extract the AFQMC energy from the outputs of SAFIRE using afqmctools,\n",
    "we are ready to how to use the tutorial helper functions to invoke SAFIRE and extract the AFQMC energy\n",
    "from within an interactive Python notebook.\n",
    "\n",
    "For convenience, we provide the `run_afqmc()` helper function in the `tutorial_utils` Python package.\n",
    "\n",
    "`run_afqmc(input_file=input_file, np=np)` runs the SAFIRE executable as\n",
    "\n",
    "```bash\n",
    "    $ mpirun -np [np] safire --filenames [input_file]\n",
    "```\n",
    "\n",
    "<div class=\"alert alert-block alert-warning\">\n",
    "<b>CAUTION:</b>\n",
    "    The AFQMC_EXEC environment variable must be set to the path to the SAFIRE executable\n",
    "    in order to use `run_afqmc()`.\n",
    "</div>\n",
    "\n",
    "Here is a typical example of using `run_afqmc()`.\n",
    "\n",
    "```python\n",
    "    from tutorial_utils import run_afqmc\n",
    "\n",
    "    scratch_dir = Path(\"data\")\n",
    "    \n",
    "    run_afqmc(\n",
    "        run_dir=scratch_dir,                # directory to run SAFIRE in - output files will be there\n",
    "        input_file=\"/path/to/inputfile/input.json\",\n",
    "        np=12,                              # number of MPI tasks\n",
    "        output_file=None                    # optionally direct output to file; if None,\n",
    "    )                                       # then output will be captured in the jupyter notebook.\n",
    "```\n",
    "\n",
    "Where the `np` parameter is forwarded directly to `-np [np]` and\n",
    "`input_file` is passed to `safire --filenames [input_file]`.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Note:</b>\n",
    "    There is no difference between running SAFIRE via `run_afqmc()` or\n",
    "    directly in the command line other than convenience.\n",
    "</div>\n",
    "\n",
    "### Exercise: Run the full sample calculation using the convenience wrappers.\n",
    "\n",
    "Use the code block below to run the entire calculation again.\n",
    "\n",
    "Just as before, at the end, you should get an AFQMC energy of `-1.135742 +/-   0.000286`\n",
    "if you did not change any settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8451bbd7",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "lFXM3f_c-NIz",
    "outputId": "23c92fb6-6385-46fa-a007-1b019b3bffa5"
   },
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import shutil\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "from afqmctools.hamiltonian.mol import write_hamiltonian_generic\n",
    "from afqmctools.wavefunction.mol import write_wfn\n",
    "from afqmctools.inputs.from_hdf import write_json\n",
    "from tutorial_utils import run_afqmc\n",
    "from stats.scalar_dat import analyze_scalar_data\n",
    "\n",
    "scratch_dir = Path(\"data\")\n",
    "scratch_dir.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# copy the provided files\n",
    "files_dir = scratch_dir / \"files\"\n",
    "files_dir.mkdir(exist_ok=True)\n",
    "shutil.copy(\"files/input.json\", files_dir)\n",
    "shutil.copy(\"files/wfn.h5\", files_dir)\n",
    "shutil.copy(\"files/hamil.h5\", files_dir)\n",
    "\n",
    "run_afqmc(\n",
    "    run_dir=scratch_dir,\n",
    "    input_file=\"files/input.json\",   # the location of the sample input file.\n",
    "    np=16,                                         # to run in serial just as before!\n",
    "    output_file=None\n",
    ")\n",
    "\n",
    "# post process!\n",
    "_ = analyze_scalar_data(dict(\n",
    "    fname = scratch_dir/\"qmc.s000.scalar.dat\",\n",
    "    series_column = \"time\",\n",
    "    nequil = 10,\n",
    "    trace = True\n",
    "))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9200068d",
   "metadata": {
    "id": "gGT0fdst-NIz"
   },
   "source": [
    "## Summary\n",
    "\n",
    "In this tutorial we have learned,\n",
    "\n",
    "1. what are the inputs and outputs of SAFIRE.\n",
    "2. how to invoke the SAFIRE executable from the command line in serial, using MPI, and using GPU(s)\n",
    "3. how to extract the AFQMC energy from the outputs of SAFIRE using afqmctools\n",
    "4. how to use the tutorial helper functions to perform 2 and 3 from within an interactive Python notebook\n",
    "\n",
    "---\n",
    "\n",
    "Next, we will take a more detailed look at the input file in [Understanding the input file](https://safire.flatironinstitute.org/docs/dev/tutorials/solids/02_understanding_the_input_file/02_understanding_the_input_file.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f10db84a",
   "metadata": {
    "id": "hOyKTzP5tm1N"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "default_lexer": "ipython3",
   "text_representation": {
    "extension": ".md",
    "format_name": "myst",
    "format_version": 0.13,
    "jupytext_version": "1.19.1"
   }
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "ipython3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}