{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1><center>The FUDGE translation of the TENDL-2021 library from ENDF-6 to GNDS</center></h1>\n",
    "<h3><center>Godfree Gert</center></h3>\n",
    "<h5><center>May 24, 2023</center></h5>\n",
    "<br>\n",
    "\n",
    "**LLNL-PRES-849740**\n",
    "\n",
    "*This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under contract DE- AC52-07NA27344. Lawrence Livermore National Security, LLC*"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "title": "The FUDGE translation of the TENDL-2021 library from ENDF-6 to GNDS\n"
   },
   "source": [
    "# Overview\n",
    "\n",
    "- Demonstrate FUDGE installation from GitHub\n",
    "\n",
    "- Demonstrate translation of TENDL-2021 library from ENDF6 to GNDS\n",
    "\n",
    "- Summary of TENDL-2021 library translation from ENDF6 to GNDS"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Downloading TENDL-2021 Library"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "for projectile in a d g h n p t; do\n",
    "  tarFile=TENDL-${projectile}.tgz\n",
    "  if [[ ! -f $tarFile ]]; then\n",
    "    echo https://tendl.web.psi.ch/tendl_2021/tar_files/TENDL-${projectile}.tgz\n",
    "    wget https://tendl.web.psi.ch/tendl_2021/tar_files/TENDL-${projectile}.tgz\n",
    "  fi\n",
    "done"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# FUDGE installation from GitHub"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following code demonstrates the installation of FUDGE to a Python virtual environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "python3 -m pip install git+https://github.com/LLNL/fudge.git@6.2.0"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Translating TENDL-2021 Library from ENDF6 to GNDS"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Function to run shell commands from within python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pathlib\n",
    "import subprocess\n",
    "\n",
    "def runShellCommand(commandList, cwd=pathlib.Path()):\n",
    "  process = subprocess.Popen(commandList, universal_newlines=True, cwd=cwd)\n",
    "  process.communicate()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Path to FUDGE translation script"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import brownies\n",
    "\n",
    "translationScript = pathlib.Path(brownies.__path__._path[0]) / 'bin' / 'endf2gnds.py'"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Arguments available in processing script"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "usage: endf2gnds.py [-h] [-v] [--skipBadData] [--skipCovariances]\n",
      "                    [--verboseWarnings] [--printBadNK14]\n",
      "                    [--continuumSpectraFix] [--ignoreBadDate]\n",
      "                    [--acceptBadMF10FissionZAP] [--traceback]\n",
      "                    [--formatVersion {1.10,2.0}] [--energyUnit ENERGYUNIT]\n",
      "                    [--JENDL_stylePrimarygammas]\n",
      "                    [--IDs {familiar,nucleus,nuclide}]\n",
      "                    inFile [outputFile]\n",
      "\n",
      "Translates an ENDF file to the GNDS format.\n",
      "\n",
      "positional arguments:\n",
      "  inFile                input file\n",
      "  outputFile            output file\n",
      "\n",
      "options:\n",
      "  -h, --help            show this help message and exit\n",
      "  -v, --verbose         enable verbose output. The more the gabbier.\n",
      "  --skipBadData         skip bad data, rather than throw an exception, when\n",
      "                        reading an ENDF file\n",
      "  --skipCovariances     skip the covariance, if present\n",
      "  --verboseWarnings     print verbose warnings\n",
      "  --printBadNK14        print bad NK's if found\n",
      "  --continuumSpectraFix\n",
      "                        fix continuous spectra on read, if foobar\n",
      "  --ignoreBadDate       ignore malformed ENDF dates\n",
      "  --acceptBadMF10FissionZAP\n",
      "                        allow MF=10 MT=18 IZAP=0\n",
      "  --traceback           print traceback on exception\n",
      "  --formatVersion {1.10,2.0}\n",
      "                        Specifies the format for the outputted GNDS file.\n",
      "  --energyUnit ENERGYUNIT\n",
      "                        Convert all energies in the gnds file to this unit.\n",
      "  --JENDL_stylePrimarygammas\n",
      "                        If prsent, treat MF=6 primary gamma energies as\n",
      "                        binding energy, otherwise as gamma energy.\n",
      "  --IDs {familiar,nucleus,nuclide}\n",
      "                        Choose between light charged particle naming\n",
      "                        conversion: \"nuclide\" (i.e., H1, H2, H3, He3 and He4),\n",
      "                        \"nucleus\" (i.e., h1, h2, h3, he3 and he4), or\n",
      "                        \"familiar\" (i.e., p, d, t, h and a).\n"
     ]
    }
   ],
   "source": [
    "runShellCommand(['python3', translationScript, '-h'])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Shell script to run FUDGE translation script"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "import stat\n",
    "\n",
    "translateSingleProtare = [\n",
    "    '#!/usr/env/sh bash',\n",
    "    '',\n",
    "    'if [[ \"$1\" == \"\" ]]; then',\n",
    "    '  echo \"USAGE ERROR: $0 endf_file\"',\n",
    "    '  exit 1',\n",
    "    'fi',\n",
    "    '',\n",
    "    'endf6File=$1',\n",
    "    'gndsFile=$(basename ${endf6File}).gnds.xml',\n",
    "    'logFile=${gndsFile%gnds.xml}log',\n",
    "    'outputFile=${gndsFile%gnds.xml}out',\n",
    "    f'python3 {translationScript} $endf6File $gndsFile --verbose 2>$logFile 1>$outputFile',\n",
    "    ''\n",
    "]\n",
    "\n",
    "endf2gndsScript = pathlib.Path('endf2gnds.sh')\n",
    "endf2gndsScript.write_text('\\n'.join(translateSingleProtare))\n",
    "endf2gndsScript.chmod(endf2gndsScript.stat().st_mode | stat.S_IEXEC)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Translate files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tarfile as tarfileModule\n",
    "\n",
    "projectileKeyMap = {\"a\": \"alpha\", \"d\": \"deuteron\", \"g\": \"gamma\", \"h\": \"helion\", \"n\": \"neutron\", \"p\": \"proton\", \"t\": \"triton\"}\n",
    "\n",
    "for tarFile in pathlib.Path().glob('*.tgz'):\n",
    "  projectileDir = tarFile.parent / projectileKeyMap[tarFile.name[-5]]\n",
    "  if not projectileDir.is_dir():\n",
    "    projectileDir.mkdir()\n",
    "    tarfileModule.open(tarFile).extractall(path=projectileDir)\n",
    "\n",
    "  gndsDir = projectileDir / 'gnds'\n",
    "  if not gndsDir.is_dir():\n",
    "    gndsDir.mkdir()\n",
    "\n",
    "    fileList = [file.resolve() for file in projectileDir.glob('*.tendl')]\n",
    "    numberFiles = len(fileList)\n",
    "    for i, endf6File in enumerate(fileList):\n",
    "      shellCommand = ['bash', endf2gndsScript.resolve(), endf6File]\n",
    "      runShellCommand(shellCommand, gndsDir)\n",
    "  \n",
    "      if i % 10 == 0:\n",
    "        print(f'{i}/{numberFiles} for {projectileKeyMap[tarFile.name[-5]]}s')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TENDL-2021 library translation at LLNL "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Summary of translation failures\n",
    "\n",
    "The table below gives an overview of the number of translation failures for different versions of the FUDGE brownies module and command line arguments. The first column shows the version of FUDGE used for the translations. Version 6.2 was used in the first three cases with the arguments shown in the second column. The FUDGE/Brownies module was subsequently modified to ignore the problems associated with MF 8, 10 and 40. These are associated with radioactive production cross sections but they are redundant and are not necessary for transport applications. The resulting translations are shown in the last two cases below. "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| FUDGE Version             | Translation Script Arguments                    | alphas | deuterons | gammas | helions | neutrons | protons | tritons |\n",
    "| --------------            | ----------------------------------------------- | ------ | --------- | ------ | ------- | -------- | ------- | ------- |\n",
    "| 6.2                       | No Arguments                                    | 194    | 237       | 71     | 232     | 306      | 217     | 269     |\n",
    "| 6.2                       | --acceptBadMF10FissionZAP                       | 194    | 236       | 71     | 232     | 306      | 217     | 269     |\n",
    "| 6.2                       | --continuumSpectraFix                           | 194    | 236       | 71     | 232     | 245      | 216     | 269     |\n",
    "| 6.2 with Brownies updates | No Arguments                                    | 2      | 2         | 0      | 2       | 84       | 4       | 1       |\n",
    "| 6.2 with Brownies updates | --acceptBadMF10FissionZAP --continuumSpectraFix | 2      | 2         | 0      | 2       | 23       | 3       | 1       |"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The remaining cases that failed to translate are the following:\n",
    "\n",
    "- $^1H$ projectile: $^2H$, $^{237}Pa$ and $^{238}Pa$ targets\n",
    "\n",
    "- $^2H$ projectile: $^3H$ and $^{237}U$ targets\n",
    "\n",
    "- $^3H$ projectile: $^{236}U$ targets\n",
    "\n",
    "- $^3He$ projectile: $^{236}Pa$ and $^{236}Th$ targets\n",
    "\n",
    "- $^4He$ projectile: $^{233}Pa$ and $^{233}Th$ targets\n",
    "\n",
    "- $n$ projectiles:\n",
    "\n",
    "  - $^{2}H$\n",
    "  - $^{241}Am$\n",
    "  - $^{10}B$  \n",
    "  - $^{9}Be$  \n",
    "  - $^{243}Cm$\n",
    "  - $^{262}Db$, $^{263}Db$, $^{264}Db$\n",
    "  - $^{233}Pa$\n",
    "  - $^{237}Pu$, $^{238}Pu$, $^{239}Pu$, $^{240}Pu$\n",
    "  - $^{272}Sg$, $^{273}Sg$\n",
    "  - $^{232}Th$\n",
    "  - $^{232}U$, $^{234}U$, $^{235}U$, $^{236}U$, $^{237}U$, $^{239}U$, $^{240}U$"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
