# Path: veidt/potential/abstract.py
# class Potential(MSONable):
#     """
#     Abstract Base class for a interatomic Potential.
#     """
# 
#     @abc.abstractmethod
#     def train(self, train_structures, energies, forces, stresses, **kwargs):
#         """
#         Train interatomic potential with energies, forces and
#         stresses corresponding to structures.
#         :param train_structures: List of Pymatgen Structure objects.
#         :param energies: List of DFT-calculated total energies of each structure
#             in structures list.
#         :param forces: List of DFT-calculated (m, 3) forces of each structure
#             with m atoms in structures list. m can be varied with each single
#             structure case.
#         :param stresses: List of DFT-calculated (6, ) virial stresses of each
#             structure in structures list.
#         """
#         pass
# 
#     @abc.abstractmethod
#     def evaluate(self, test_structures, ref_energies, ref_forces, ref_stresses):
#         """
#         Evaluate energies, forces and stresses of structures with trained
#         interatomic potential.
#         :param test_structures: List of Pymatgen Structure Objects.
#         :param ref_energies: List of DFT-calculated total energies of each
#             structure in structures list.
#         :param ref_forces: List of DFT-calculated (m, 3) forces of each
#             structure with m atoms in structures list. m can be varied with
#             each single structure case.
#         :param ref_stresses: List of DFT-calculated (6, ) viriral stresses of
#             each structure in structures list.
#         :return: DataFrame of original data and DataFrame of predicted data.
#         """
#         pass


import os
import abc
import io
import subprocess
import itertools
import numpy as np
from monty.tempfile import ScratchDir
from pymatgen import Element
from pymatgen.io.lammps.data import LammpsData
from veidt.potential.abstract import Potential
                        error_msg += ', '.join([e for e in msg[error_line:]])
                    except Exception:
                        error_msg += msg[-1]
                    raise RuntimeError(error_msg)
                results = self._parse()
                data.append(results)
        return data


class EnergyForceStress(LMPStaticCalculator):
    """
    Calculate energy, forces and virial stress of structures.
    """

    def __init__(self, ff_settings):
        """
        Args:
            ff_settings (list/Potential): Configure the force field settings for LAMMPS
                calculation, if given a Potential object, should apply
                Potential.write_param method to get the force field setting.
        """
        self.ff_settings = ff_settings

    def _setup(self):
        template_dir = os.path.join(os.path.dirname(__file__), 'templates', 'efs')
        with open(os.path.join(template_dir, 'in.efs'), 'r') as f:
            input_template = f.read()

        input_file = 'in.efs'


# Path: veidt/potential/abstract.py
# class Potential(MSONable):
#     """
#     Abstract Base class for a interatomic Potential.
#     """
# 
#     @abc.abstractmethod
#     def train(self, train_structures, energies, forces, stresses, **kwargs):
#         """
#         Train interatomic potential with energies, forces and
#         stresses corresponding to structures.
#         :param train_structures: List of Pymatgen Structure objects.
#         :param energies: List of DFT-calculated total energies of each structure
#             in structures list.
#         :param forces: List of DFT-calculated (m, 3) forces of each structure
#             with m atoms in structures list. m can be varied with each single
#             structure case.
#         :param stresses: List of DFT-calculated (6, ) virial stresses of each
#             structure in structures list.
#         """
#         pass
# 
#     @abc.abstractmethod
#     def evaluate(self, test_structures, ref_energies, ref_forces, ref_stresses):
#         """
#         Evaluate energies, forces and stresses of structures with trained
#         interatomic potential.
#         :param test_structures: List of Pymatgen Structure Objects.
#         :param ref_energies: List of DFT-calculated total energies of each
#             structure in structures list.
#         :param ref_forces: List of DFT-calculated (m, 3) forces of each
#             structure with m atoms in structures list. m can be varied with
#             each single structure case.
#         :param ref_stresses: List of DFT-calculated (6, ) viriral stresses of
#             each structure in structures list.
#         :return: DataFrame of original data and DataFrame of predicted data.
#         """
#         pass


# Path: veidt/potential/lammps/calcs.py
import os
import abc
import io
import subprocess
import itertools
import numpy as np
from monty.tempfile import ScratchDir
from pymatgen import Element
from pymatgen.io.lammps.data import LammpsData
from veidt.potential.abstract import Potential

                        error_msg += ', '.join([e for e in msg[error_line:]])
                    except Exception:
                        error_msg += msg[-1]
                    raise RuntimeError(error_msg)
                results = self._parse()
                data.append(results)
        return data


class EnergyForceStress(LMPStaticCalculator):
    """
    Calculate energy, forces and virial stress of structures.
    """

    def __init__(self, ff_settings):
        """
        Args:
            ff_settings (list/Potential): Configure the force field settings for LAMMPS
                calculation, if given a Potential object, should apply
                Potential.write_param method to get the force field setting.
        """
        self.ff_settings = ff_settings

    def _setup(self):
        template_dir = os.path.join(os.path.dirname(__file__), 'templates', 'efs')
        with open(os.path.join(template_dir, 'in.efs'), 'r') as f:
            input_template = f.read()

        input_file = 'in.efs'


        if isinstance(self.ff_settings, Potential):