# Path: veidt/abstract.py
# class Describer(BaseEstimator, MSONable, TransformerMixin):
#     """
#     Base class for a Describer, i.e., something that converts an object to a
#     describer, typically a numerical representation useful for machine
#     learning.
#     """
# 
#     def fit(self, objs, targets=None):
#         """Fit the describer.
#         In the case that the describer relies on parameters calculated from training data,
#         this method should be rewritten to store the fitted parameters
#         """
#         return self
# 
#     def transform(self, objs):
#         """Transform the input objects"""
#         return self.describe_all(objs).values
# 
#     @abc.abstractmethod
#     def describe(self, obj):
#         """
#         Converts an obj to a descriptor vector.
# 
#         :param obj: Object
#         :return: Descriptor for a structure. Recommended format is a pandas
#             Dataframe object with the column names as intuitive names.
#             For example, a simple site describer of the fractional coordinates
#             (this is usually a bad describer, so it is just for illustration
#             purposes) can be generated as::
# 
#                 print(pd.DataFrame(s.frac_coords, columns=["a", "b", "c"]))
#                           a         b         c
#                 0  0.000000  0.000000  0.000000
#                 1  0.750178  0.750178  0.750178
#                 2  0.249822  0.249822  0.249822
# 
#             Pandas dataframes can be dumped to a variety of formats (json, csv,
#             etc.) easily. Note that a dataframe should be used even if you have
#             only one line, i.e., do not use Series objects unless you know
#             what you are doing.
#         """
#         pass
# 
#     def describe_all(self, objs):
#         """
#         Convenience method to convert a list of objects to a list of
#         descriptors. Default implementation simply loops a call to describe, but
#         in some instances, a batch implementation may be more efficient.
# 
#         :param objs: List of objects
# 
#         :return: Concatenated descriptors for all objects. Recommended format
#             is a pandas DataFrame. Default implement returns a list of
#             descriptors generated by a loop call to describe for each obj.
#         """
#         return pd.concat([self.describe(o) for o in objs])
# 
# Path: veidt/potential/processing.py
# def pool_from(structures, energies=None, forces=None, stresses=None):
#     """
#     Method to convert structures and their properties in to
#     datapool format.
#     Args:
#         structures ([Structure]): The list of Pymatgen Structure object.
#         energies ([float]): The list of total energies of each structure
#             in structures list.
#         forces ([np.array]): List of (m, 3) forces array of each structure
#             with m atoms in structures list. m can be varied with each
#             single structure case.
#         stresses (list): List of (6, ) virial stresses of each
#             structure in structures list.
#     Returns:
#         ([dict])
#     """
#     energies = energies if energies else [None] * len(structures)
#     forces = forces if forces else [None] * len(structures)
#     stresses = stresses if stresses else [None] * len(structures)
#     datapool = [doc_from(structure, energy, force, stress)
#                 for structure, energy, force, stress
#                 in zip(structures, energies, forces, stresses)]
#     return datapool


import itertools
import subprocess
import io
import re
import numpy as np
import pandas as pd
from monty.io import zopen
from monty.os.path import which
from monty.tempfile import ScratchDir
from pymatgen.core.periodic_table import get_el_sp
from veidt.abstract import Describer
from veidt.potential.processing import pool_from
        from veidt.potential.lammps.calcs import SpectralNeighborAnalysis
        from veidt.potential.soap import SOAPotential
        from veidt.potential.nnp import NNPotential
        """
        if not which('quip'):
            raise RuntimeError("quip has not been found.\n",
                               "Please refer to https://github.com/libAtoms/QUIP for ",
                               "further detail.")
        atoms_filename = 'structure.xyz'

        exe_command = ['quip']
        exe_command.append('atoms_filename={}'.format(atoms_filename))

        descriptor_command = ['soap']
        descriptor_command.append("cutoff" + '=' + '{}'.format(self.cutoff))
        descriptor_command.append("l_max" + '=' + '{}'.format(self.l_max))
        descriptor_command.append("n_max" + '=' + '{}'.format(self.n_max))
        descriptor_command.append("atom_sigma" + '=' + '{}'.format(self.atom_sigma))
        atomic_numbers = [str(num) for num in np.unique(structure.atomic_numbers)]
        n_Z = len(atomic_numbers)
        n_species = len(atomic_numbers)
        Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        species_Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        descriptor_command.append("n_Z" + '=' + str(n_Z))
        descriptor_command.append("Z" + '=' + Z)
        descriptor_command.append("n_species" + '=' + str(n_species))
        descriptor_command.append("species_Z" + '=' + species_Z)

        exe_command.append("descriptor_str=" + "{" +
                           "{}".format(' '.join(descriptor_command)) + "}")

        with ScratchDir('.'):
            atoms_filename = self.operator.write_cfgs(filename=atoms_filename,

# Path: veidt/abstract.py
# class Describer(BaseEstimator, MSONable, TransformerMixin):
#     """
#     Base class for a Describer, i.e., something that converts an object to a
#     describer, typically a numerical representation useful for machine
#     learning.
#     """
# 
#     def fit(self, objs, targets=None):
#         """Fit the describer.
#         In the case that the describer relies on parameters calculated from training data,
#         this method should be rewritten to store the fitted parameters
#         """
#         return self
# 
#     def transform(self, objs):
#         """Transform the input objects"""
#         return self.describe_all(objs).values
# 
#     @abc.abstractmethod
#     def describe(self, obj):
#         """
#         Converts an obj to a descriptor vector.
# 
#         :param obj: Object
#         :return: Descriptor for a structure. Recommended format is a pandas
#             Dataframe object with the column names as intuitive names.
#             For example, a simple site describer of the fractional coordinates
#             (this is usually a bad describer, so it is just for illustration
#             purposes) can be generated as::
# 
#                 print(pd.DataFrame(s.frac_coords, columns=["a", "b", "c"]))
#                           a         b         c
#                 0  0.000000  0.000000  0.000000
#                 1  0.750178  0.750178  0.750178
#                 2  0.249822  0.249822  0.249822
# 
#             Pandas dataframes can be dumped to a variety of formats (json, csv,
#             etc.) easily. Note that a dataframe should be used even if you have
#             only one line, i.e., do not use Series objects unless you know
#             what you are doing.
#         """
#         pass
# 
#     def describe_all(self, objs):
#         """
#         Convenience method to convert a list of objects to a list of
#         descriptors. Default implementation simply loops a call to describe, but
#         in some instances, a batch implementation may be more efficient.
# 
#         :param objs: List of objects
# 
#         :return: Concatenated descriptors for all objects. Recommended format
#             is a pandas DataFrame. Default implement returns a list of
#             descriptors generated by a loop call to describe for each obj.
#         """
#         return pd.concat([self.describe(o) for o in objs])
# 
# Path: veidt/potential/processing.py
# def pool_from(structures, energies=None, forces=None, stresses=None):
#     """
#     Method to convert structures and their properties in to
#     datapool format.
#     Args:
#         structures ([Structure]): The list of Pymatgen Structure object.
#         energies ([float]): The list of total energies of each structure
#             in structures list.
#         forces ([np.array]): List of (m, 3) forces array of each structure
#             with m atoms in structures list. m can be varied with each
#             single structure case.
#         stresses (list): List of (6, ) virial stresses of each
#             structure in structures list.
#     Returns:
#         ([dict])
#     """
#     energies = energies if energies else [None] * len(structures)
#     forces = forces if forces else [None] * len(structures)
#     stresses = stresses if stresses else [None] * len(structures)
#     datapool = [doc_from(structure, energy, force, stress)
#                 for structure, energy, force, stress
#                 in zip(structures, energies, forces, stresses)]
#     return datapool


# Path: veidt/describer/atomic_describer.py
import itertools
import subprocess
import io
import re
import numpy as np
import pandas as pd
from monty.io import zopen
from monty.os.path import which
from monty.tempfile import ScratchDir
from pymatgen.core.periodic_table import get_el_sp
from veidt.abstract import Describer
from veidt.potential.processing import pool_from
        from veidt.potential.lammps.calcs import SpectralNeighborAnalysis
        from veidt.potential.soap import SOAPotential
        from veidt.potential.nnp import NNPotential

        """
        if not which('quip'):
            raise RuntimeError("quip has not been found.\n",
                               "Please refer to https://github.com/libAtoms/QUIP for ",
                               "further detail.")
        atoms_filename = 'structure.xyz'

        exe_command = ['quip']
        exe_command.append('atoms_filename={}'.format(atoms_filename))

        descriptor_command = ['soap']
        descriptor_command.append("cutoff" + '=' + '{}'.format(self.cutoff))
        descriptor_command.append("l_max" + '=' + '{}'.format(self.l_max))
        descriptor_command.append("n_max" + '=' + '{}'.format(self.n_max))
        descriptor_command.append("atom_sigma" + '=' + '{}'.format(self.atom_sigma))
        atomic_numbers = [str(num) for num in np.unique(structure.atomic_numbers)]
        n_Z = len(atomic_numbers)
        n_species = len(atomic_numbers)
        Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        species_Z = '{' + '{}'.format(' '.join(atomic_numbers)) + '}'
        descriptor_command.append("n_Z" + '=' + str(n_Z))
        descriptor_command.append("Z" + '=' + Z)
        descriptor_command.append("n_species" + '=' + str(n_species))
        descriptor_command.append("species_Z" + '=' + species_Z)

        exe_command.append("descriptor_str=" + "{" +
                           "{}".format(' '.join(descriptor_command)) + "}")

        with ScratchDir('.'):
            atoms_filename = self.operator.write_cfgs(filename=atoms_filename,

                                                      cfg_pool=pool_from([structure]))