Instruction:
Make a summary of the following Python 3 code
def get_gap(self, tol=0.001, abs_tol=False, spin=None):
        (cbm, vbm) = self.get_cbm_vbm(tol, abs_tol, spin)
        return max(cbm - vbm, 0.0)

Response: Returns the gap in the sequence of cbm and vbm in the sequence of n - 1s.


Instruction:
Here you have a function in Python 3, explain what it does
def get_densities(self, spin=None):
        if self.densities is None:
            result = None
        elif spin is None:
            if Spin.down in self.densities:
                result = self.densities[Spin.up] + self.densities[Spin.down]
            else:
                result = self.densities[Spin.up]
        else:
            result = self.densities[spin]
        return result

Response: Returns the density of states for a particular spin.


Instruction:
How would you explain what the following Python 3 function does
def get_smeared_densities(self, sigma):
        from scipy.ndimage.filters import gaussian_filter1d
        smeared_dens = {}
        diff = [self.energies[i + 1] - self.energies[i]
                for i in range(len(self.energies) - 1)]
        avgdiff = sum(diff) / len(diff)
        for spin, dens in self.densities.items():
            smeared_dens[spin] = gaussian_filter1d(dens, sigma / avgdiff)
        return smeared_dens

Response:
Returns the densities of the energy of the current entry in the n - level tree with Gaussian smearing applied about the fermi
        level.


Instruction:
Can you create a Python 3 function that
returns the interpolated value for a particular energy.

Response:
def get_interpolated_value(self, energy):
        """
        Returns interpolated density for a particular energy.

        Args:
            energy: Energy to return the density for.
        """
        f = {}
        for spin in self.densities.keys():
            f[spin] = get_linear_interpolated_value(self.energies,
                                                    self.densities[spin],
                                                    energy)
        return f


Instruction:
Write a Python 3 script to
return the cbm and vbm of the entry in the tree.

Response:
def get_cbm_vbm(self, tol=0.001, abs_tol=False, spin=None):
        """
        Expects a DOS object and finds the cbm and vbm.

        Args:
            tol: tolerance in occupations for determining the gap
            abs_tol: An absolute tolerance (True) and a relative one (False)
            spin: Possible values are None - finds the gap in the summed
                densities, Up - finds the gap in the up spin channel,
                Down - finds the gap in the down spin channel.

        Returns:
            (cbm, vbm): float in eV corresponding to the gap
        """
        # determine tolerance
        tdos = self.get_densities(spin)
        if not abs_tol:
            tol = tol * tdos.sum() / tdos.shape[0]

        # find index of fermi energy
        i_fermi = 0
        while self.energies[i_fermi] <= self.efermi:
            i_fermi += 1

        # work backwards until tolerance is reached
        i_gap_start = i_fermi
        while i_gap_start - 1 >= 0 and tdos[i_gap_start - 1] <= tol:
            i_gap_start -= 1

        # work forwards until tolerance is reached
        i_gap_end = i_gap_start
        while i_gap_end < tdos.shape[0] and tdos[i_gap_end] <= tol:
            i_gap_end += 1
        i_gap_end -= 1
        return self.energies[i_gap_end], self.energies[i_gap_start]


Instruction:
Write a Python 3 function for
returning a new Dos object from dict representation of Dos.

Response:
def from_dict(cls, d):
        """
        Returns Dos object from dict representation of Dos.
        """
        return Dos(d["efermi"], d["energies"],
                   {Spin(int(k)): v
                    for k, v in d["densities"].items()})


Instruction:
Make a summary of the following Python 3 code
def as_dict(self):
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__, "efermi": self.efermi,
                "energies": list(self.energies),
                "densities": {str(spin): list(dens)
                              for spin, dens in self.densities.items()}}

Response: Json - serializable dict representation of Dos.


Instruction:
Create a Python 3 function for
calculating the doping of the majority carrier concentration at a given fermi level and temperature.

Response:
def get_doping(self, fermi, T):
        """
        Calculate the doping (majority carrier concentration) at a given fermi
        level and temperature. A simple Left Riemann sum is used for integrating
        the density of states over energy & equilibrium Fermi-Dirac distribution

        Args:
            fermi (float): the fermi level in eV
            T (float): the temperature in Kelvin

        Returns (float): in units 1/cm3. If negative it means that the majority
            carriers are electrons (n-type doping) and if positive holes/p-type
        """
        cb_integral = np.sum(self.tdos[self.idx_cbm:]
                             * f0(self.energies[self.idx_cbm:], fermi, T)
                             * self.de[self.idx_cbm:], axis=0)
        vb_integral = np.sum(self.tdos[:self.idx_vbm + 1]
                             * (1 - f0(self.energies[:self.idx_vbm + 1], fermi, T))
                             * self.de[:self.idx_vbm + 1], axis=0)
        return (vb_integral - cb_integral) / (self.volume * self.A_to_cm ** 3)


Instruction:
Here you have a function in Python 3, explain what it does
def get_fermi(self, c, T, rtol=0.01, nstep=50, step=0.1, precision=8):
        fermi = self.efermi  # initialize target fermi
        for _ in range(precision):
            frange = np.arange(-nstep, nstep + 1) * step + fermi
            calc_doping = np.array([self.get_doping(f, T) for f in frange])
            relative_error = abs(calc_doping / c - 1.0)
            fermi = frange[np.argmin(relative_error)]
            step /= 10.0
        if min(relative_error) > rtol:
            raise ValueError('Could not find fermi within {}% of c={}'.format(
                rtol * 100, c))
        return fermi

Response: This function returns the fermi level at which the doping concentration at the given temperature is equal to c.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_site_orbital_dos(self, site, orbital):
        return Dos(self.efermi, self.energies, self.pdos[site][orbital])

Response: Returns the Dos for a particular orbital of a particular site.


Instruction:
How would you code a function in Python 3 to
return the total Dos for a specific site.

Response:
def get_site_dos(self, site):
        """
        Get the total Dos for a site (all orbitals).

        Args:
            site: Site in Structure associated with CompleteDos.

        Returns:
            Dos containing summed orbital densities for site.
        """
        site_dos = functools.reduce(add_densities, self.pdos[site].values())
        return Dos(self.efermi, self.energies, site_dos)


Instruction:
Here you have a function in Python 3, explain what it does
def get_site_spd_dos(self, site):
        spd_dos = dict()
        for orb, pdos in self.pdos[site].items():
            orbital_type = _get_orb_type(orb)
            if orbital_type in spd_dos:
                spd_dos[orbital_type] = add_densities(spd_dos[orbital_type], pdos)
            else:
                spd_dos[orbital_type] = pdos
        return {orb: Dos(self.efermi, self.energies, densities)
                for orb, densities in spd_dos.items()}

Response: Get orbital projected Dos of a particular site in Structure associated with CompleteDos.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_site_t2g_eg_resolved_dos(self, site):
        t2g_dos = []
        eg_dos = []
        for s, atom_dos in self.pdos.items():
            if s == site:
                for orb, pdos in atom_dos.items():
                    if orb in (Orbital.dxy, Orbital.dxz, Orbital.dyz):
                        t2g_dos.append(pdos)
                    elif orb in (Orbital.dx2, Orbital.dz2):
                        eg_dos.append(pdos)
        return {"t2g": Dos(self.efermi, self.energies,
                           functools.reduce(add_densities, t2g_dos)),
                "e_g": Dos(self.efermi, self.energies,
                           functools.reduce(add_densities, eg_dos))}

Response: Get the t2g eg projected DOS for a particular site.


Instruction:
Write a Python 3 function for
getting orbital projected Dos.

Response:
def get_spd_dos(self):
        """
        Get orbital projected Dos.

        Returns:
            dict of {orbital: Dos}, e.g. {"s": Dos object, ...}
        """
        spd_dos = {}
        for atom_dos in self.pdos.values():
            for orb, pdos in atom_dos.items():
                orbital_type = _get_orb_type(orb)
                if orbital_type not in spd_dos:
                    spd_dos[orbital_type] = pdos
                else:
                    spd_dos[orbital_type] = \
                        add_densities(spd_dos[orbital_type], pdos)
        return {orb: Dos(self.efermi, self.energies, densities)
                for orb, densities in spd_dos.items()}


Instruction:
Explain what the following Python 3 code does
def get_element_dos(self):

        el_dos = {}
        for site, atom_dos in self.pdos.items():
            el = site.specie
            for pdos in atom_dos.values():
                if el not in el_dos:
                    el_dos[el] = pdos
                else:
                    el_dos[el] = add_densities(el_dos[el], pdos)
        return {el: Dos(self.efermi, self.energies, densities)
                for el, densities in el_dos.items()}

Response: Get element projected Dos.


Instruction:
Make a summary of the following Python 3 code
def spin_polarization(self):
        n_F = self.get_interpolated_value(self.efermi)

        n_F_up = n_F[Spin.up]
        n_F_down = n_F[Spin.down]

        if (n_F_up + n_F_down) == 0:
            # only well defined for metals or half-mteals
            return float('NaN')

        spin_polarization = (n_F_up - n_F_down) / (n_F_up + n_F_down)

        return abs(spin_polarization)

Response: Calculates the spin polarization at Fermi level.


Instruction:
Explain what the following Python 3 code does
def get_element_spd_dos(self, el):
        el = get_el_sp(el)
        el_dos = {}
        for site, atom_dos in self.pdos.items():
            if site.specie == el:
                for orb, pdos in atom_dos.items():
                    orbital_type = _get_orb_type_lobster(orb)
                    if orbital_type not in el_dos:
                        el_dos[orbital_type] = pdos
                    else:
                        el_dos[orbital_type] = \
                            add_densities(el_dos[orbital_type], pdos)

        return {orb: Dos(self.efermi, self.energies, densities)
                for orb, densities in el_dos.items()}

Response: Get element and spd projected Dos.


Instruction:
Create a Python 3 function for
returning a CompleteDos object from dict representation.

Response:
def from_dict(cls, d):
        """
        Returns: CompleteDos object from dict representation.
        """
        tdos = Dos.from_dict(d)
        struct = Structure.from_dict(d["structure"])
        pdoss = {}
        for i in range(len(d["pdos"])):
            at = struct[i]
            orb_dos = {}
            for orb_str, odos in d["pdos"][i].items():
                orb = orb_str
                orb_dos[orb] = {Spin(int(k)): v
                                for k, v in odos["densities"].items()}
            pdoss[at] = orb_dos
        return LobsterCompleteDos(struct, tdos, pdoss)


Instruction:
Can you generate the documentation for the following Python 3 function
def get_prototypes(self, structure):

        tags = self._match_single_prototype(structure)

        if len(tags) == 0:
            return None
        else:
            return tags

Response:
Returns a list of dicts with keys
        snl and tags for that prototype and a list of tags for that prototype and None if there is no match.


Instruction:
Write a Python 3 script to
parse the input string for a specific pattern in a specific table.

Response:
def read_table_pattern(text_str,
                       header_pattern,
                       row_pattern,
                       footer_pattern,
                       postprocess=str,
                       attribute_name=None,
                       last_one_only=False):
    """
    Parse table-like data. A table composes of three parts: header,
    main body, footer. All the data matches "row pattern" in the main body
    will be returned.

    Args:
        text_str (str): the input string to search for patterns
        header_pattern (str): The regular expression pattern matches the
            table header. This pattern should match all the text
            immediately before the main body of the table. For multiple
            sections table match the text until the section of
            interest. MULTILINE and DOTALL options are enforced, as a
            result, the "." meta-character will also match "\n" in this
            section.
        row_pattern (str): The regular expression matches a single line in
            the table. Capture interested field using regular expression
            groups.
        footer_pattern (str): The regular expression matches the end of the
            table. E.g. a long dash line.
        postprocess (callable): A post processing function to convert all
            matches. Defaults to str, i.e., no change.
        attribute_name (str): Name of this table. If present the parsed data
            will be attached to "data. e.g. self.data["efg"] = [...]
        last_one_only (bool): All the tables will be parsed, if this option
            is set to True, only the last table will be returned. The
            enclosing list will be removed. i.e. Only a single table will
            be returned. Default to be True.

    Returns:
        List of tables. 1) A table is a list of rows. 2) A row if either a list of
        attribute values in case the the capturing group is defined without name in
        row_pattern, or a dict in case that named capturing groups are defined by
        row_pattern.
    """

    table_pattern_text = header_pattern + \
        r"\s*(?P<table_body>(?:" + row_pattern + r")+)\s*" + footer_pattern
    table_pattern = re.compile(table_pattern_text, re.MULTILINE | re.DOTALL)
    rp = re.compile(row_pattern)
    data = {}
    tables = []
    for mt in table_pattern.finditer(text_str):
        table_body_text = mt.group("table_body")
        table_contents = []
        for ml in rp.finditer(table_body_text):
            d = ml.groupdict()
            if len(d) > 0:
                processed_line = {k: postprocess(v) for k, v in d.items()}
            else:
                processed_line = [postprocess(v) for v in ml.groups()]
            table_contents.append(processed_line)
        tables.append(table_contents)
    if last_one_only:
        retained_data = tables[-1]
    else:
        retained_data = tables
    if attribute_name is not None:
        data[attribute_name] = retained_data
        return data
    return retained_data


Instruction:
Write a Python 3 script to
take a dictionary and makes all the keys lower case and checks that all the keys are unique.

Response:
def lower_and_check_unique(dict_to_check):
    """
    Takes a dictionary and makes all the keys lower case. Also replaces
    "jobtype" with "job_type" just so that key specifically can be called
    elsewhere without ambiguity. Finally, ensures that multiple identical
    keys, that differed only due to different capitalizations, are not
    present. If there are multiple equivalent keys, an Exception is raised.

    Args:
        dict_to_check (dict): The dictionary to check and standardize

    Returns:
        to_return (dict): An identical dictionary but with all keys made
            lower case and no identical keys present.
    """
    if dict_to_check == None:
        return None
    else:
        to_return = {}
        for key in dict_to_check:
            new_key = key.lower()
            if new_key == "jobtype":
                new_key = "job_type"
            if new_key in to_return:
                raise Exception(
                    "Multiple instances of key " + new_key + " found!")
            else:
                try:
                    to_return[new_key] = dict_to_check.get(key).lower()
                except AttributeError:
                    to_return[new_key] = dict_to_check.get(key)
        return to_return


Instruction:
How would you implement a function in Python 3 that
takes a set of parsed coordinates which come as an array of strings and returns a numpy array of floats.

Response:
def process_parsed_coords(coords):
    """
    Takes a set of parsed coordinates, which come as an array of strings,
    and returns a numpy array of floats.
    """
    geometry = np.zeros(shape=(len(coords), 3), dtype=float)
    for ii, entry in enumerate(coords):
        for jj in range(3):
            geometry[ii, jj] = float(entry[jj])
    return geometry


Instruction:
Here you have a function in Python 3, explain what it does
def gen_sl_transform_matricies(area_multiple):
    return [np.array(((i, j), (0, area_multiple / i)))
            for i in get_factors(area_multiple)
            for j in range(area_multiple // i)]

Response: Generates the list of transformation matricies that covert unit vectors to super lattice vectors.


Instruction:
Can you create a Python 3 function that
calculates angle between two vectors a and b

Response:
def vec_angle(a, b):
    """
    Calculate angle between two vectors
    """
    cosang = np.dot(a, b)
    sinang = fast_norm(np.cross(a, b))
    return np.arctan2(sinang, cosang)


Instruction:
Implement a Python 3 function for
generating independent and unique basis vectors based on the Zur and McGill methodology of Zur and McGill

Response:
def reduce_vectors(a, b):
    """
    Generate independent and unique basis vectors based on the
    methodology of Zur and McGill
    """
    if np.dot(a, b) < 0:
        return reduce_vectors(a, -b)

    if fast_norm(a) > fast_norm(b):
        return reduce_vectors(b, a)

    if fast_norm(b) > fast_norm(np.add(b, a)):
        return reduce_vectors(a, np.add(b, a))

    if fast_norm(b) > fast_norm(np.subtract(b, a)):
        return reduce_vectors(a, np.subtract(b, a))

    return [a, b]


Instruction:
Write a Python 3 script to
return True if two sets of vectors are the same within length and angle of the current session.

Response:
def is_same_vectors(self, vec_set1, vec_set2):
        """
        Determine if two sets of vectors are the same within length and angle
        tolerances

        Args:
            vec_set1(array[array]): an array of two vectors
            vec_set2(array[array]): second array of two vectors
        """
        if (np.absolute(rel_strain(vec_set1[0], vec_set2[0])) >
                self.max_length_tol):
            return False
        elif (np.absolute(rel_strain(vec_set1[1], vec_set2[1])) >
                  self.max_length_tol):
            return False
        elif (np.absolute(rel_angle(vec_set1, vec_set2)) >
                  self.max_angle_tol):
            return False
        else:
            return True


Instruction:
How would you implement a function in Python 3 that
generates the list of all the SL transformation sets for the film and substrate pair.

Response:
def generate_sl_transformation_sets(self, film_area, substrate_area):
        """
        Generates transformation sets for film/substrate pair given the
        area of the unit cell area for the film and substrate. The
        transformation sets map the film and substrate unit cells to super
        lattices with a maximum area

        Args:
            film_area(int): the unit cell area for the film
            substrate_area(int): the unit cell area for the substrate

        Returns:
            transformation_sets: a set of transformation_sets defined as:
                1.) the transformation matricies for the film to create a
                super lattice of area i*film area
                2.) the tranformation matricies for the substrate to create
                a super lattice of area j*film area
        """
        transformation_indicies = [(i, j)
                                   for i in range(1, int(self.max_area / film_area))
                                   for j in range(1, int(self.max_area / substrate_area))
                                   if np.absolute(film_area / substrate_area - float(j) / i) < self.max_area_ratio_tol]

        # Sort sets by the square of the matching area and yield in order
        # from smallest to largest
        for x in sorted(transformation_indicies, key=lambda x: x[0] * x[1]):
            yield (gen_sl_transform_matricies(x[0]),
                   gen_sl_transform_matricies(x[1]))


Instruction:
Create a Python 3 function for
returning all possible transformation sets that are equivalent to the film and substrate vectors.

Response:
def get_equiv_transformations(self, transformation_sets, film_vectors,
                                  substrate_vectors):
        """
        Applies the transformation_sets to the film and substrate vectors
        to generate super-lattices and checks if they matches.
        Returns all matching vectors sets.

        Args:
            transformation_sets(array): an array of transformation sets:
                each transformation set is an array with the (i,j)
                indicating the area multipes of the film and subtrate it
                corresponds to, an array with all possible transformations
                for the film area multiple i and another array for the
                substrate area multiple j.

            film_vectors(array): film vectors to generate super lattices
            substrate_vectors(array): substrate vectors to generate super
                lattices
        """

        for (film_transformations, substrate_transformations) in \
                transformation_sets:
            # Apply transformations and reduce using Zur reduce methodology
            films = [reduce_vectors(*np.dot(f, film_vectors)) for f in film_transformations]

            substrates = [reduce_vectors(*np.dot(s, substrate_vectors)) for s in substrate_transformations]

            # Check if equivelant super lattices
            for f, s in product(films, substrates):
                if self.is_same_vectors(f, s):
                    yield [f, s]


Instruction:
Can you create a Python 3 function that
returns a dictionary which contains ZSL match.

Response:
def match_as_dict(self, film_sl_vectors, substrate_sl_vectors, film_vectors, substrate_vectors, match_area):
        """
        Returns dict which contains ZSL match

        Args:
            film_miller(array)
            substrate_miller(array)
        """
        d = {}
        d["film_sl_vecs"] = np.asarray(film_sl_vectors)
        d["sub_sl_vecs"] = np.asarray(substrate_sl_vectors)
        d["match_area"] = match_area
        d["film_vecs"] = np.asarray(film_vectors)
        d["sub_vecs"] = np.asarray(substrate_vectors)

        return d


Instruction:
Here you have a function in Python 3, explain what it does
def calculate(self, film, substrate, elasticity_tensor=None,
                  film_millers=None, substrate_millers=None,
                  ground_state_energy=0, lowest=False):
        """
        Finds all topological matches for the substrate and calculates elastic
        strain energy and total energy for the film if elasticity tensor and
        ground state energy are provided:

        Args:
            film(Structure): conventional standard structure for the film
            substrate(Structure): conventional standard structure for the
                substrate
            elasticity_tensor(ElasticTensor): elasticity tensor for the film
                in the IEEE orientation
            film_millers(array): film facets to consider in search as defined by
                miller indicies
            substrate_millers(array): substrate facets to consider in search as
                defined by miller indicies
            ground_state_energy(float): ground state energy for the film
            lowest(bool): only consider lowest matching area for each surface
        """
        self.film = film
        self.substrate = substrate

        # Generate miller indicies if none specified for film
        if film_millers is None:
            film_millers = sorted(get_symmetrically_distinct_miller_indices(
                self.film, self.film_max_miller))

        # Generate miller indicies if none specified for substrate
        if substrate_millers is None:
            substrate_millers = sorted(
                get_symmetrically_distinct_miller_indices(self.substrate,
                                                          self.substrate_max_miller))

        # Check each miller index combination
        surface_vector_sets = self.generate_surface_vectors(film_millers, substrate_millers)
        for [film_vectors, substrate_vectors, film_miller, substrate_miller] in surface_vector_sets:
            for match in self.zsl(film_vectors, substrate_vectors, lowest):
                match['film_miller'] = film_miller
                match['sub_miller'] = substrate_miller
                if (elasticity_tensor is not None):
                    energy, strain = self.calculate_3D_elastic_energy(
                        film, match, elasticity_tensor, include_strain=True)
                    match["elastic_energy"] = energy
                    match["strain"] = strain
                if (ground_state_energy is not 0):
                    match['total_energy'] = match.get('elastic_energy', 0) + ground_state_energy

                yield match

Response: Calculates the topological matches for the given film and substrate.


Instruction:
Implement a Python 3 function for
calculating the multi - plane elastic energy for a single - plane film.

Response:
def calculate_3D_elastic_energy(self, film, match, elasticity_tensor=None,
                                    include_strain=False):
        """
        Calculates the multi-plane elastic energy. Returns 999 if no elastic
        tensor was given on init

        Args:
            film(Structure): conventional standard structure for the film
            match(dictionary) : match dictionary from substrate analyzer
            elasticity_tensor(ElasticTensor): elasticity tensor for the film
            include_strain(bool): include strain in the output or not; changes
             return from just the energy to a tuple with the energy and strain
             in voigt notation
        """
        if elasticity_tensor is None:
            return 9999

        # Get the appropriate surface structure
        struc = SlabGenerator(self.film, match['film_miller'], 20, 15,
                              primitive=False).get_slab().oriented_unit_cell

        # Generate 3D lattice vectors for film super lattice
        film_matrix = list(match['film_sl_vecs'])
        film_matrix.append(np.cross(film_matrix[0], film_matrix[1]))

        # Generate 3D lattice vectors for substrate super lattice
        # Out of plane substrate super lattice has to be same length as
        # Film out of plane vector to ensure no extra deformation in that
        # direction
        substrate_matrix = list(match['sub_sl_vecs'])
        temp_sub = np.cross(substrate_matrix[0], substrate_matrix[1])
        temp_sub = temp_sub * fast_norm(film_matrix[2]) / fast_norm(temp_sub)
        substrate_matrix.append(temp_sub)

        transform_matrix = np.transpose(np.linalg.solve(film_matrix,
                                                        substrate_matrix))

        dfm = Deformation(transform_matrix)

        strain = dfm.green_lagrange_strain.convert_to_ieee(struc, initial_fit=False)

        energy_density = elasticity_tensor.energy_density(
            strain)

        if include_strain:
            return (film.volume * energy_density / len(film.sites), strain.von_mises_strain)
        else:
            return film.volume * energy_density / len(film.sites)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _from_frame_string(contents):
        lines = contents.split("\n")
        num_sites = int(lines[0])
        coords = []
        sp = []
        coord_patt = re.compile(
            r"(\w+)\s+([0-9\-\+\.eEdD]+)\s+([0-9\-\+\.eEdD]+)\s+([0-9\-\+\.eEdD]+)"
        )
        for i in range(2, 2 + num_sites):
            m = coord_patt.search(lines[i])
            if m:
                sp.append(m.group(1))  # this is 1-indexed
                # this is 0-indexed
                # in case of 0.0D+00 or 0.00d+01 old double precision writing
                # replace d or D by e for ten power exponent
                xyz = [val.lower().replace("d", "e") for val in m.groups()[1:4]]
                coords.append([float(val) for val in xyz])
        return Molecule(sp, coords)

Response: Convert a single frame XYZ string to a molecule


Instruction:
Explain what the following Python 3 code does
def from_string(contents):
        if contents[-1] != "\n":
            contents += "\n"
        white_space = r"[ \t\r\f\v]"
        natoms_line = white_space + r"*\d+" + white_space + r"*\n"
        comment_line = r"[^\n]*\n"
        coord_lines = r"(\s*\w+\s+[0-9\-\+\.eEdD]+\s+[0-9\-\+\.eEdD]+\s+[0-9\-\+\.eEdD]+\s*\n)+"
        frame_pattern_text = natoms_line + comment_line + coord_lines
        pat = re.compile(frame_pattern_text, re.MULTILINE)
        mols = []
        for xyz_match in pat.finditer(contents):
            xyz_text = xyz_match.group(0)
            mols.append(XYZ._from_frame_string(xyz_text))
        return XYZ(mols)

Response: Creates an XYZ object from a string.


Instruction:
Implement a function in Python 3 to
return a chemical shielding tensor aligned to the principle axis system

Response:
def principal_axis_system(self):
        """
        Returns a chemical shielding tensor aligned to the principle axis system
        so that only the 3 diagnol components are non-zero
        """
        return ChemicalShielding(np.diag(np.sort(np.linalg.eigvals(self))))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def haeberlen_values(self):
        pas=self.principal_axis_system
        sigma_iso=pas.trace() / 3
        sigmas=np.diag(pas)
        sigmas=sorted(sigmas, key=lambda x: np.abs(x - sigma_iso))
        sigma_yy, sigma_xx, sigma_zz=sigmas
        delta_sigma=sigma_zz - 0.5 * (sigma_xx + sigma_yy)
        zeta=sigma_zz - sigma_iso
        eta=(sigma_yy - sigma_xx) / zeta
        return self.HaeberlenNotation(sigma_iso, delta_sigma, zeta, eta)

Response: Returns the Chemical shielding tensor in Haeberlen Notation


Instruction:
How would you explain what the following Python 3 function does
def mehring_values(self):
        pas=self.principal_axis_system
        sigma_iso=pas.trace() / 3
        sigma_11, sigma_22, sigma_33=np.diag(pas)
        return self.MehringNotation(sigma_iso, sigma_11, sigma_22, sigma_33)

Response: Returns the Chemical shielding tensor in Mehring Notation


Instruction:
How would you code a function in Python 3 to
return the Chemical shielding tensor in Maryland Notation

Response:
def maryland_values(self):
        """
        Returns: the Chemical shielding tensor in Maryland Notation
        """
        pas=self.principal_axis_system
        sigma_iso=pas.trace() / 3
        omega=np.diag(pas)[2] - np.diag(pas)[0]
        # There is a typo in equation 20 from Magn. Reson. Chem. 2008, 46, 582–598, the sign is wrong.
        # There correct order is presented in Solid State Nucl. Magn. Reson. 1993, 2, 285-288.
        kappa=3.0 * (np.diag(pas)[1] - sigma_iso) / omega
        return self.MarylandNotation(sigma_iso, omega, kappa)


Instruction:
How would you explain what the following Python 3 function does
def principal_axis_system(self):
        return ElectricFieldGradient(np.diag(np.sort(np.linalg.eigvals(self))))

Response: Returns a electric field gradient tensor aligned to the principle axis system.


Instruction:
Given the following Python 3 function, write the documentation
def asymmetry(self):
        diags=np.diag(self.principal_axis_system)
        V=sorted(diags, key=np.abs)
        return np.abs((V[1] - V[0]) / V[2])

Response: Asymmetry of the electric field tensor defined as :


Instruction:
Explain what the following Python 3 code does
def coupling_constant(self, specie):
        planks_constant=FloatWithUnit(6.62607004E-34, "m^2 kg s^-1")
        Vzz=FloatWithUnit(self.V_zz, "V ang^-2")
        e=FloatWithUnit(-1.60217662E-19, "C")

        # Convert from string to Specie object
        if isinstance(specie, str):
            # isotope was provided in string format
            if len(specie.split("-")) > 1:
                isotope=str(specie)
                specie=Specie(specie.split("-")[0])
                Q=specie.get_nmr_quadrupole_moment(isotope)
            else:
                specie=Specie(specie)
                Q=specie.get_nmr_quadrupole_moment()
        elif isinstance(specie, Site):
            specie=specie.specie
            Q=specie.get_nmr_quadrupole_moment()
        elif isinstance(specie, Specie):
            Q=specie.get_nmr_quadrupole_moment()
        else:
            raise ValueError("Invalid speciie provided for quadrupolar coupling constant calcuations")

        return (e * Q * Vzz / planks_constant).to("MHz")

Response: This function calculates the coupling constant for a specific species at a specific site.


Instruction:
How would you code a function in Python 3 to
return an analysis of a given structure and the structure with the key strength which may be strong weak or unknown.

Response:
def get_analysis_and_structure(self,
                                   structure,
                                   calculate_valences=True,
                                   guesstimate_spin=False,
                                   op_threshold=0.1):
        """
        Obtain an analysis of a given structure and if it may be Jahn-Teller
        active or not. This is a heuristic, and may give false positives and
        false negatives (false positives are preferred).

        :param structure: input structure
        :param calculate_valences (bool): whether to attempt to calculate valences or not, structure
        should have oxidation states to perform analysis
        :param guesstimate_spin (bool): whether to guesstimate spin state from magnetic moments
        or not, use with caution
        :param op_threshold (float): threshold for order parameter above which to consider site
        to match an octahedral or tetrahedral motif, since Jahn-Teller structures can often be
        quite distorted, this threshold is smaller than one might expect
        :return (dict): analysis of structure, with key 'strength' which may be 'none', 'strong',
        'weak', or 'unknown'
        """

        structure = structure.get_primitive_structure()

        if calculate_valences:
            bva = BVAnalyzer()
            structure = bva.get_oxi_state_decorated_structure(structure)

        # no point testing multiple equivalent sites, doesn't make any difference to analysis
        # but makes returned
        symmetrized_structure = SpacegroupAnalyzer(structure).get_symmetrized_structure()

        # to detect structural motifs of a given site
        op = LocalStructOrderParams(['oct', 'tet'])

        # dict of site index to the Jahn-Teller analysis of that site
        jt_sites = []
        non_jt_sites = []

        for indices in symmetrized_structure.equivalent_indices:

            idx = indices[0]
            site = symmetrized_structure[idx]

            # only interested in sites with oxidation states
            if isinstance(site.specie, Specie) and site.specie.element.is_transition_metal:

                # get motif around site
                order_params = op.get_order_parameters(symmetrized_structure, idx)

                if order_params[0] > order_params[1] and order_params[0] > op_threshold:
                    motif = 'oct'
                    motif_order_parameter = order_params[0]
                elif order_params[1] > op_threshold:
                    motif = 'tet'
                    motif_order_parameter = order_params[1]
                else:
                    motif = 'unknown'
                    motif_order_parameter = None

                if motif == "oct" or motif == "tet":

                    # guess spin of metal ion
                    if guesstimate_spin and 'magmom' in site.properties:

                        # estimate if high spin or low spin
                        magmom = site.properties['magmom']
                        spin_state = self._estimate_spin_state(site.specie, motif, magmom)
                    else:
                        spin_state = "unknown"

                    magnitude = self.get_magnitude_of_effect_from_species(site.specie,
                                                                          spin_state,
                                                                          motif)

                    if magnitude != "none":

                        ligands = get_neighbors_of_site_with_index(structure, idx,
                                                                   approach="min_dist",
                                                                   delta=0.15)
                        ligand_bond_lengths = [ligand.distance(structure[idx])
                                               for ligand in ligands]
                        ligands_species = list(set([str(ligand.specie) for ligand in ligands]))
                        ligand_bond_length_spread = max(ligand_bond_lengths) - \
                                                    min(ligand_bond_lengths)

                        def trim(f):
                            # avoid storing to unreasonable precision, hurts readability
                            return float("{:.4f}".format(f))

                        # to be Jahn-Teller active, all ligands have to be the same
                        if len(ligands_species) == 1:
                            jt_sites.append({'strength': magnitude,
                                             'motif': motif,
                                             'motif_order_parameter': trim(motif_order_parameter),
                                             'spin_state': spin_state,
                                             'species': str(site.specie),
                                             'ligand': ligands_species[0],
                                             'ligand_bond_lengths': [trim(length) for length in
                                                                     ligand_bond_lengths],
                                             'ligand_bond_length_spread':
                                                 trim(ligand_bond_length_spread),
                                             'site_indices': indices})

                    # store reasons for not being J-T active
                    else:
                        non_jt_sites.append({'site_indices': indices,
                                             'strength': "none",
                                             'reason': "Not Jahn-Teller active for this "
                                                       "electronic configuration."})
                else:
                    non_jt_sites.append({'site_indices': indices,
                                         'strength': "none",
                                         'reason': "motif is {}".format(motif)})

        # perform aggregation of all sites
        if jt_sites:
            analysis = {'active': True}
            # if any site could exhibit 'strong' Jahn-Teller effect
            # then mark whole structure as strong
            strong_magnitudes = [site['strength'] == "strong" for site in jt_sites]
            if any(strong_magnitudes):
                analysis['strength'] = "strong"
            else:
                analysis['strength'] = "weak"
            analysis['sites'] = jt_sites
            return analysis, structure
        else:
            return {'active': False, 'sites': non_jt_sites}, structure


Instruction:
Write a Python 3 function that can
get magnitude of Jahn - Teller effect from provided species spin state and motife.

Response:
def get_magnitude_of_effect_from_species(self, species, spin_state, motif):
        """
        Get magnitude of Jahn-Teller effect from provided species, spin state and motife.

        :param species: e.g. Fe2+
        :param spin_state (str): "high" or "low"
        :param motif (str): "oct" or "tet"

        :return (str):
        """

        magnitude = "none"

        sp = get_el_sp(species)

        # has to be Specie; we need to know the oxidation state
        if isinstance(sp, Specie) and sp.element.is_transition_metal:

            d_electrons = self._get_number_of_d_electrons(sp)

            if motif in self.spin_configs:
                if spin_state not in self.spin_configs[motif][d_electrons]:
                    spin_state = self.spin_configs[motif][d_electrons]['default']
                spin_config = self.spin_configs[motif][d_electrons][spin_state]
                magnitude = JahnTellerAnalyzer.get_magnitude_of_effect_from_spin_config(motif,
                                                                                spin_config)
        else:
            warnings.warn("No data for this species.")

        return magnitude


Instruction:
Write a Python 3 function for
returning the magnitude of effect from the given spin configuration.

Response:
def get_magnitude_of_effect_from_spin_config(motif, spin_config):
        """
        Roughly, the magnitude of Jahn-Teller distortion will be:
        * in octahedral environments, strong if e_g orbitals
        unevenly occupied but weak if t_2g orbitals unevenly
        occupied
        * in tetrahedral environments always weaker
        :param motif (str): "oct" or "tet"
        :param spin_config (dict): dict of 'e' (e_g) and 't' (t2_g)
        with number of electrons in each state
        """
        magnitude = "none"
        if motif == "oct":
            e_g = spin_config["e_g"]
            t_2g = spin_config["t_2g"]
            if (e_g % 2 != 0) or (t_2g % 3 != 0):
                magnitude = "weak"
                if e_g % 2 == 1:
                    magnitude = "strong"
        elif motif == "tet":
            e = spin_config["e"]
            t_2 = spin_config["t_2"]
            if (e % 3 != 0) or (t_2 % 2 != 0):
                magnitude = "weak"
        return magnitude


Instruction:
Can you generate the documentation for the following Python 3 function
def _estimate_spin_state(species, motif, known_magmom):
        mu_so_high = JahnTellerAnalyzer.mu_so(species, motif=motif, spin_state="high")
        mu_so_low = JahnTellerAnalyzer.mu_so(species, motif=motif, spin_state="low")
        if mu_so_high == mu_so_low:
            return "undefined"  # undefined or only one spin state possible
        elif mu_so_high is None:
            return "low"
        elif mu_so_low is None:
            return "high"
        else:
            diff = mu_so_high - mu_so_low
            # WARNING! this heuristic has not been robustly tested or benchmarked
            # using 'diff*0.25' as arbitrary measure, if known magmom is
            # too far away from expected value, we don't try to classify it
            if known_magmom > mu_so_high or abs(mu_so_high - known_magmom) < diff * 0.25:
                return "high"
            elif known_magmom < mu_so_low or abs(mu_so_low - known_magmom) < diff * 0.25:
                return "low"
            else:
                return "unknown"

Response: Simple heuristic to estimate spin state for a given species and motif.


Instruction:
Here you have a function in Python 3, explain what it does
def mu_so(species, motif, spin_state):
        try:
            sp = get_el_sp(species)
            n = sp.get_crystal_field_spin(coordination=motif, spin_config=spin_state)
            # calculation spin-only magnetic moment for this number of unpaired spins
            return np.sqrt(n * (n + 2))
        except AttributeError:
            return None

Response: Calculates the spin - only magnetic moment for a specific species. Only supports transition metals.


Instruction:
Given the following Python 3 function, write the documentation
def get_conversion_factor(structure, species, temperature):
    df_sp = get_el_sp(species)
    if hasattr(df_sp, "oxi_state"):
        z = df_sp.oxi_state
    else:
        z = df_sp.full_electronic_structure[-1][2]

    n = structure.composition[species]

    vol = structure.volume * 1e-24  # units cm^3
    return 1000 * n / (vol * const.N_A) * z ** 2 * (const.N_A * const.e) ** 2 \
        / (const.R * temperature)

Response: Returns the conversion factor for a diffusion run in Kelvin.


Instruction:
How would you implement a function in Python 3 that
fits the Arrhenius model to obtain the standard error of Ea from the Arrhenius fit.

Response:
def fit_arrhenius(temps, diffusivities):
    """
    Returns Ea, c, standard error of Ea from the Arrhenius fit:
        D = c * exp(-Ea/kT)

    Args:
        temps ([float]): A sequence of temperatures. units: K
        diffusivities ([float]): A sequence of diffusivities (e.g.,
            from DiffusionAnalyzer.diffusivity). units: cm^2/s
    """
    t_1 = 1 / np.array(temps)
    logd = np.log(diffusivities)
    # Do a least squares regression of log(D) vs 1/T
    a = np.array([t_1, np.ones(len(temps))]).T
    w, res, _, _ = np.linalg.lstsq(a, logd, rcond=None)
    w = np.array(w)
    n = len(temps)
    if n > 2:
        std_Ea = (res[0] / (n - 2) / (
        n * np.var(t_1))) ** 0.5 * const.k / const.e
    else:
        std_Ea = None
    return -w[0] * const.k / const.e, np.exp(w[1]), std_Ea


Instruction:
Write a Python 3 script for
returning the extrapolated diffusivity at new_temp

Response:
def get_extrapolated_diffusivity(temps, diffusivities, new_temp):
    """
    Returns (Arrhenius) extrapolated diffusivity at new_temp

    Args:
        temps ([float]): A sequence of temperatures. units: K
        diffusivities ([float]): A sequence of diffusivities (e.g.,
            from DiffusionAnalyzer.diffusivity). units: cm^2/s
        new_temp (float): desired temperature. units: K

    Returns:
        (float) Diffusivity at extrapolated temp in mS/cm.
    """
    Ea, c, _ = fit_arrhenius(temps, diffusivities)
    return c * np.exp(-Ea / (const.k / const.e * new_temp))


Instruction:
How would you code a function in Python 3 to
return the extrapolated mS and cm conductivity at a given temperature.

Response:
def get_extrapolated_conductivity(temps, diffusivities, new_temp, structure,
                                  species):
    """
    Returns extrapolated mS/cm conductivity.

    Args:
        temps ([float]): A sequence of temperatures. units: K
        diffusivities ([float]): A sequence of diffusivities (e.g.,
            from DiffusionAnalyzer.diffusivity). units: cm^2/s
        new_temp (float): desired temperature. units: K
        structure (structure): Structure used for the diffusivity calculation
        species (string/Specie): conducting species

    Returns:
        (float) Conductivity at extrapolated temp in mS/cm.
    """
    return get_extrapolated_diffusivity(temps, diffusivities, new_temp) \
        * get_conversion_factor(structure, species, new_temp)


Instruction:
How would you explain what the following Python 3 function does
def get_arrhenius_plot(temps, diffusivities, diffusivity_errors=None,
                       **kwargs):
    """
    Returns an Arrhenius plot.

    Args:
        temps ([float]): A sequence of temperatures.
        diffusivities ([float]): A sequence of diffusivities (e.g.,
            from DiffusionAnalyzer.diffusivity).
        diffusivity_errors ([float]): A sequence of errors for the
            diffusivities. If None, no error bar is plotted.
        \\*\\*kwargs:
            Any keyword args supported by matplotlib.pyplot.plot.

    Returns:
        A matplotlib.pyplot object. Do plt.show() to show the plot.
    """
    Ea, c, _ = fit_arrhenius(temps, diffusivities)

    from pymatgen.util.plotting import pretty_plot
    plt = pretty_plot(12, 8)

    # log10 of the arrhenius fit
    arr = c * np.exp(-Ea / (const.k / const.e * np.array(temps)))

    t_1 = 1000 / np.array(temps)

    plt.plot(t_1, diffusivities, 'ko', t_1, arr, 'k--', markersize=10,
             **kwargs)
    if diffusivity_errors is not None:
        n = len(diffusivity_errors)
        plt.errorbar(t_1[0:n], diffusivities[0:n], yerr=diffusivity_errors,
                     fmt='ko', ecolor='k', capthick=2, linewidth=2)
    ax = plt.axes()
    ax.set_yscale('log')
    plt.text(0.6, 0.85, "E$_a$ = {:.0f} meV".format(Ea * 1000),
             fontsize=30, transform=plt.axes().transAxes)
    plt.ylabel("D (cm$^2$/s)")
    plt.xlabel("1000/T (K$^{-1}$)")
    plt.tight_layout()
    return plt

Response: Returns an Arrhenius plot for the given temperatures and diffusivities.


Instruction:
Write a Python 3 function for
returning an iterator for the drift - corrected structures in the MD.

Response:
def get_drift_corrected_structures(self, start=None, stop=None, step=None):
        """
        Returns an iterator for the drift-corrected structures. Use of
        iterator is to reduce memory usage as # of structures in MD can be
        huge. You don't often need all the structures all at once.

        Args:
            start, stop, step (int): applies a start/stop/step to the iterator.
                Faster than applying it after generation, as it reduces the
                number of structures created.
        """
        coords = np.array(self.structure.cart_coords)
        species = self.structure.species_and_occu
        lattices = self.lattices
        nsites, nsteps, dim = self.corrected_displacements.shape

        for i in range(start or 0, stop or nsteps, step or 1):
            latt = lattices[0] if len(lattices) == 1 else lattices[i]
            yield Structure(
                latt, species,
                coords + self.corrected_displacements[:, i, :],
                coords_are_cartesian=True)


Instruction:
Write a Python 3 function for
returning a dictionary containing the diffusion and conductivity information.

Response:
def get_summary_dict(self, include_msd_t=False, include_mscd_t=False):
        """
        Provides a summary of diffusion information.

        Args:
            include_msd_t (bool): Whether to include mean square displace and
                time data with the data.
            include_msd_t (bool): Whether to include mean square charge displace and
                time data with the data.

        Returns:
            (dict) of diffusion and conductivity data.
        """
        d = {
            "D": self.diffusivity,
            "D_sigma": self.diffusivity_std_dev,
            "D_charge": self.chg_diffusivity,
            "D_charge_sigma": self.chg_diffusivity_std_dev,
            "S": self.conductivity,
            "S_sigma": self.conductivity_std_dev,
            "S_charge": self.chg_conductivity,
            "D_components": self.diffusivity_components.tolist(),
            "S_components": self.conductivity_components.tolist(),
            "D_components_sigma": self.diffusivity_components_std_dev.tolist(),
            "S_components_sigma": self.conductivity_components_std_dev.tolist(),
            "specie": str(self.specie),
            "step_skip": self.step_skip,
            "time_step": self.time_step,
            "temperature": self.temperature,
            "max_framework_displacement": self.max_framework_displacement,
            "Haven_ratio": self.haven_ratio
        }
        if include_msd_t:
            d["msd"] = self.msd.tolist()
            d["msd_components"] = self.msd_components.tolist()
            d["dt"] = self.dt.tolist()
        if include_mscd_t:
            d["mscd"] = self.mscd.tolist()
        return d


Instruction:
Make a summary of the following Python 3 code
def get_framework_rms_plot(self, plt=None, granularity=200,
                               matching_s=None):
        """
        Get the plot of rms framework displacement vs time. Useful for checking
        for melting, especially if framework atoms can move via paddle-wheel
        or similar mechanism (which would show up in max framework displacement
        but doesn't constitute melting).

        Args:
            plt (matplotlib.pyplot): If plt is supplied, changes will be made
                to an existing plot. Otherwise, a new plot will be created.
            granularity (int): Number of structures to match
            matching_s (Structure): Optionally match to a disordered structure
                instead of the first structure in the analyzer. Required when
                a secondary mobile ion is present.
        Notes:
            The method doesn't apply to NPT-AIMD simulation analysis.
        """
        from pymatgen.util.plotting import pretty_plot
        if self.lattices is not None and len(self.lattices) > 1:
            warnings.warn("Note the method doesn't apply to NPT-AIMD "
                          "simulation analysis!")

        plt = pretty_plot(12, 8, plt=plt)
        step = (self.corrected_displacements.shape[1] - 1) // (granularity - 1)
        f = (matching_s or self.structure).copy()
        f.remove_species([self.specie])
        sm = StructureMatcher(primitive_cell=False, stol=0.6,
                              comparator=OrderDisorderElementComparator(),
                              allow_subset=True)
        rms = []
        for s in self.get_drift_corrected_structures(step=step):
            s.remove_species([self.specie])
            d = sm.get_rms_dist(f, s)
            if d:
                rms.append(d)
            else:
                rms.append((1, 1))
        max_dt = (len(rms) - 1) * step * self.step_skip * self.time_step
        if max_dt > 100000:
            plot_dt = np.linspace(0, max_dt / 1000, len(rms))
            unit = 'ps'
        else:
            plot_dt = np.linspace(0, max_dt, len(rms))
            unit = 'fs'
        rms = np.array(rms)
        plt.plot(plot_dt, rms[:, 0], label='RMS')
        plt.plot(plot_dt, rms[:, 1], label='max')
        plt.legend(loc='best')
        plt.xlabel("Timestep ({})".format(unit))
        plt.ylabel("normalized distance")
        plt.tight_layout()
        return plt

Response: Returns a matplotlib. pyplot object for the framework displacement vs time.


Instruction:
Write a Python 3 script for
returning a plot of the smoothed msd vs time graph.

Response:
def get_msd_plot(self, plt=None, mode="specie"):
        """
        Get the plot of the smoothed msd vs time graph. Useful for
        checking convergence. This can be written to an image file.

        Args:
            plt: A plot object. Defaults to None, which means one will be
                generated.
            mode (str): Determines type of msd plot. By "species", "sites",
                or direction (default). If mode = "mscd", the smoothed mscd vs.
                time will be plotted.
        """
        from pymatgen.util.plotting import pretty_plot
        plt = pretty_plot(12, 8, plt=plt)
        if np.max(self.dt) > 100000:
            plot_dt = self.dt / 1000
            unit = 'ps'
        else:
            plot_dt = self.dt
            unit = 'fs'

        if mode == "species":
            for sp in sorted(self.structure.composition.keys()):
                indices = [i for i, site in enumerate(self.structure) if
                           site.specie == sp]
                sd = np.average(self.sq_disp_ions[indices, :], axis=0)
                plt.plot(plot_dt, sd, label=sp.__str__())
            plt.legend(loc=2, prop={"size": 20})
        elif mode == "sites":
            for i, site in enumerate(self.structure):
                sd = self.sq_disp_ions[i, :]
                plt.plot(plot_dt, sd, label="%s - %d" % (
                    site.specie.__str__(), i))
            plt.legend(loc=2, prop={"size": 20})
        elif mode == "mscd":
            plt.plot(plot_dt, self.mscd, 'r')
            plt.legend(["Overall"], loc=2, prop={"size": 20})
        else:
            # Handle default / invalid mode case
            plt.plot(plot_dt, self.msd, 'k')
            plt.plot(plot_dt, self.msd_components[:, 0], 'r')
            plt.plot(plot_dt, self.msd_components[:, 1], 'g')
            plt.plot(plot_dt, self.msd_components[:, 2], 'b')
            plt.legend(["Overall", "a", "b", "c"], loc=2, prop={"size": 20})

        plt.xlabel("Timestep ({})".format(unit))
        if mode == "mscd":
            plt.ylabel("MSCD ($\\AA^2$)")
        else:
            plt.ylabel("MSD ($\\AA^2$)")
        plt.tight_layout()
        return plt


Instruction:
Implement a Python 3 function for
exporting MSD data to a csv file.

Response:
def export_msdt(self, filename):
        """
        Writes MSD data to a csv file that can be easily plotted in other
        software.

        Args:
            filename (str): Filename. Supported formats are csv and dat. If
                the extension is csv, a csv file is written. Otherwise,
                a dat format is assumed.
        """
        fmt = "csv" if filename.lower().endswith(".csv") else "dat"
        delimiter = ", " if fmt == "csv" else " "
        with open(filename, "wt") as f:
            if fmt == "dat":
                f.write("# ")
            f.write(delimiter.join(["t", "MSD", "MSD_a", "MSD_b", "MSD_c",
                                    "MSCD"]))
            f.write("\n")
            for dt, msd, msdc, mscd in zip(self.dt, self.msd,
                                           self.msd_components, self.mscd):
                f.write(delimiter.join(["%s" % v for v in [dt, msd] + list(
                    msdc) + [mscd]]))
                f.write("\n")


Instruction:
Create a Python 3 function for
returning a new instance of the class _DiffusionAnalyzer_ with the given vasprun and specie.

Response:
def from_vaspruns(cls, vaspruns, specie, initial_disp=None,
                      initial_structure=None, **kwargs):
        """
        Convenient constructor that takes in a list of Vasprun objects to
        perform diffusion analysis.

        Args:
            vaspruns ([Vasprun]): List of Vaspruns (must be ordered  in
                sequence of MD simulation). E.g., you may have performed
                sequential VASP runs to obtain sufficient statistics.
            specie (Element/Specie): Specie to calculate diffusivity for as a
                String. E.g., "Li".
            initial_disp (np.ndarray): Sometimes, you need to iteratively
                compute estimates of the diffusivity. This supplies an
                initial displacement that will be added on to the initial
                displacements. Note that this makes sense only when
                smoothed=False.
            initial_structure (Structure): Like initial_disp, this is used
                for iterative computations of estimates of the diffusivity. You
                typically need to supply both variables. This stipulates the
                initial stricture from which the current set of displacements
                are computed.
            \\*\\*kwargs: kwargs supported by the :class:`DiffusionAnalyzer`_.
                Examples include smoothed, min_obs, avg_nsteps.
        """

        def get_structures(vaspruns):
            for i, vr in enumerate(vaspruns):
                if i == 0:
                    step_skip = vr.ionic_step_skip or 1
                    final_structure = vr.initial_structure
                    temperature = vr.parameters['TEEND']
                    time_step = vr.parameters['POTIM']
                    yield step_skip, temperature, time_step
                # check that the runs are continuous
                fdist = pbc_diff(vr.initial_structure.frac_coords,
                                 final_structure.frac_coords)
                if np.any(fdist > 0.001):
                    raise ValueError('initial and final structures do not '
                                     'match.')
                final_structure = vr.final_structure

                assert (vr.ionic_step_skip or 1) == step_skip
                for s in vr.ionic_steps:
                    yield s['structure']

        s = get_structures(vaspruns)
        step_skip, temperature, time_step = next(s)

        return cls.from_structures(
            structures=list(s), specie=specie, temperature=temperature,
            time_step=time_step, step_skip=step_skip,
            initial_disp=initial_disp, initial_structure=initial_structure,
            **kwargs)


Instruction:
How would you explain what the following Python 3 function does
def from_files(cls, filepaths, specie, step_skip=10, ncores=None,
                   initial_disp=None, initial_structure=None, **kwargs):
        """
        Convenient constructor that takes in a list of vasprun.xml paths to
        perform diffusion analysis.

        Args:
            filepaths ([str]): List of paths to vasprun.xml files of runs. (
                must be ordered in sequence of MD simulation). For example,
                you may have done sequential VASP runs and they are in run1,
                run2, run3, etc. You should then pass in
                ["run1/vasprun.xml", "run2/vasprun.xml", ...].
            specie (Element/Specie): Specie to calculate diffusivity for as a
                String. E.g., "Li".
            step_skip (int): Sampling frequency of the displacements (
                time_step is multiplied by this number to get the real time
                between measurements)
            ncores (int): Numbers of cores to use for multiprocessing. Can
                speed up vasprun parsing considerably. Defaults to None,
                which means serial. It should be noted that if you want to
                use multiprocessing, the number of ionic steps in all vasprun
                .xml files should be a multiple of the ionic_step_skip.
                Otherwise, inconsistent results may arise. Serial mode has no
                such restrictions.
            initial_disp (np.ndarray): Sometimes, you need to iteratively
                compute estimates of the diffusivity. This supplies an
                initial displacement that will be added on to the initial
                displacements. Note that this makes sense only when
                smoothed=False.
            initial_structure (Structure): Like initial_disp, this is used
                for iterative computations of estimates of the diffusivity. You
                typically need to supply both variables. This stipulates the
                initial structure from which the current set of displacements
                are computed.
            \\*\\*kwargs: kwargs supported by the :class:`DiffusionAnalyzer`_.
                Examples include smoothed, min_obs, avg_nsteps.
        """
        if ncores is not None and len(filepaths) > 1:
            import multiprocessing
            p = multiprocessing.Pool(ncores)
            vaspruns = p.imap(_get_vasprun,
                              [(fp, step_skip) for fp in filepaths])
            analyzer = cls.from_vaspruns(
                vaspruns, specie=specie, initial_disp=initial_disp,
                initial_structure=initial_structure, **kwargs)
            p.close()
            p.join()
            return analyzer
        else:
            def vr(filepaths):
                offset = 0
                for p in filepaths:
                    v = Vasprun(p, ionic_step_offset=offset,
                                ionic_step_skip=step_skip)
                    yield v
                    # Recompute offset.
                    offset = (-(v.nionic_steps - offset)) % step_skip

            return cls.from_vaspruns(
                vr(filepaths), specie=specie, initial_disp=initial_disp,
                initial_structure=initial_structure, **kwargs)

Response: This is a convenience method that takes in a list of filepaths and specie and returns a new instance of the class I_n_iterations and I_n_displacements.


Instruction:
How would you code a function in Python 3 to
apply the strategy to the structure_environments object in order to define the coordination environment of a given site. :param site: Site for which the coordination environment is looked for :return: The coordination environment of the site. For complex strategies, where one allows multiple solutions, this can return a list of coordination environments for the site

Response:
def get_site_coordination_environments_fractions(self, site, isite=None, dequivsite=None, dthissite=None,
                                                     mysym=None, ordered=True, min_fraction=0.0, return_maps=True,
                                                     return_strategy_dict_info=False):
        """
        Applies the strategy to the structure_environments object in order to define the coordination environment of
        a given site.
        :param site: Site for which the coordination environment is looked for
        :return: The coordination environment of the site. For complex strategies, where one allows multiple
        solutions, this can return a list of coordination environments for the site
        """
        raise NotImplementedError()


Instruction:
How would you implement a function in Python 3 that
applies the strategy to the structure_environments object to get the coordination environments fraction csm geometry_info and neighbors of the site.

Response:
def get_site_ce_fractions_and_neighbors(self, site, full_ce_info=False, strategy_info=False):
        """
        Applies the strategy to the structure_environments object in order to get coordination environments, their
        fraction, csm, geometry_info, and neighbors
        :param site: Site for which the above information is seeked
        :return: The list of neighbors of the site. For complex strategies, where one allows multiple solutions, this
        can return a list of list of neighbors
        """
        [isite, dequivsite, dthissite, mysym] = self.equivalent_site_index_and_transform(site)
        geoms_and_maps_list = self.get_site_coordination_environments_fractions(site=site, isite=isite,
                                                                                dequivsite=dequivsite,
                                                                                dthissite=dthissite, mysym=mysym,
                                                                                return_maps=True,
                                                                                return_strategy_dict_info=True)
        if geoms_and_maps_list is None:
            return None
        site_nbs_sets = self.structure_environments.neighbors_sets[isite]
        ce_and_neighbors = []
        for fractions_dict in geoms_and_maps_list:
            ce_map = fractions_dict['ce_map']
            ce_nb_set = site_nbs_sets[ce_map[0]][ce_map[1]]
            neighbors = [{'site': nb_site_and_index['site'],
                          'index': nb_site_and_index['index']}
                         for nb_site_and_index in ce_nb_set.neighb_sites_and_indices]
            fractions_dict['neighbors'] = neighbors
            ce_and_neighbors.append(fractions_dict)
        return ce_and_neighbors


Instruction:
Make a summary of the following Python 3 code
def as_dict(self):
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "distance_cutoff": float(self._distance_cutoff),
                "angle_cutoff": float(self._angle_cutoff),
                "additional_condition": int(self._additional_condition),
                "continuous_symmetry_measure_cutoff": float(self._continuous_symmetry_measure_cutoff),
                "symmetry_measure_type": self._symmetry_measure_type}

Response: Returns a dict representation of the SimplestChemenvStrategy object.


Instruction:
Create a Python 3 function for
reconstructing the SimplestChemenvStrategy object from a dict representation of the SimplestChemenvStrategy object.

Response:
def from_dict(cls, d):
        """
        Reconstructs the SimplestChemenvStrategy object from a dict representation of the SimplestChemenvStrategy object
        created using the as_dict method.
        :param d: dict representation of the SimplestChemenvStrategy object
        :return: StructureEnvironments object
        """
        return cls(distance_cutoff=d["distance_cutoff"], angle_cutoff=d["angle_cutoff"],
                   additional_condition=d["additional_condition"],
                   continuous_symmetry_measure_cutoff=d["continuous_symmetry_measure_cutoff"],
                   symmetry_measure_type=d["symmetry_measure_type"])


Instruction:
Can you implement a function in Python 3 that
returns a dict representation of the SimpleAbundanceChemenvStrategy object.

Response:
def as_dict(self):
        """
        Bson-serializable dict representation of the SimpleAbundanceChemenvStrategy object.
        :return: Bson-serializable dict representation of the SimpleAbundanceChemenvStrategy object.
        """
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "additional_condition": self._additional_condition}


Instruction:
Make a summary of the following Python 3 code
def as_dict(self):
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "additional_condition": self._additional_condition,
                "max_nabundant": self.max_nabundant,
                "target_environments": self.target_environments,
                "target_penalty_type": self.target_penalty_type,
                "max_csm": self.max_csm}

Response: Return a dict representation of the TargettedPenaltiedAbundanceChemenvStrategy object.


Instruction:
Write a Python 3 script for
reconstructing the TargettedPenaltiedAbundanceChemenvStrategy object from a dictionary representation of the targetted penaltied abundance chemical hierarchy.

Response:
def from_dict(cls, d):
        """
        Reconstructs the TargettedPenaltiedAbundanceChemenvStrategy object from a dict representation of the
        TargettedPenaltiedAbundanceChemenvStrategy object created using the as_dict method.
        :param d: dict representation of the TargettedPenaltiedAbundanceChemenvStrategy object
        :return: TargettedPenaltiedAbundanceChemenvStrategy object
        """
        return cls(additional_condition=d["additional_condition"],
                   max_nabundant=d["max_nabundant"],
                   target_environments=d["target_environments"],
                   target_penalty_type=d["target_penalty_type"],
                   max_csm=d["max_csm"])


Instruction:
Can you write a function in Python 3 where it
returns a dictionary representation of the WeightedNbSetChemenvStrategy object.

Response:
def as_dict(self):
        """
        Bson-serializable dict representation of the WeightedNbSetChemenvStrategy object.
        :return: Bson-serializable dict representation of the WeightedNbSetChemenvStrategy object.
        """
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "additional_condition": self._additional_condition,
                "symmetry_measure_type": self.symmetry_measure_type,
                "nb_set_weights": [nb_set_weight.as_dict() for nb_set_weight in self.nb_set_weights],
                "ce_estimator": self.ce_estimator,
                }


Instruction:
Implement a function in Python 3 to
reconstruct the WeightedNbSetChemenvStrategy object from a dict representation of the WeightedNbSetChemenvStrategy object created using the as_dict method.

Response:
def from_dict(cls, d):
        """
        Reconstructs the WeightedNbSetChemenvStrategy object from a dict representation of the
        WeightedNbSetChemenvStrategy object created using the as_dict method.
        :param d: dict representation of the WeightedNbSetChemenvStrategy object
        :return: WeightedNbSetChemenvStrategy object
        """
        return cls(additional_condition=d["additional_condition"],
                   symmetry_measure_type=d["symmetry_measure_type"],
                   nb_set_weights=d["nb_set_weights"],
                   ce_estimator=d["ce_estimator"])


Instruction:
Create a Python 3 function for
returning a dict representation of the MultiWeightsChemenvStrategy object.

Response:
def as_dict(self):
        """
        Bson-serializable dict representation of the MultiWeightsChemenvStrategy object.
        :return: Bson-serializable dict representation of the MultiWeightsChemenvStrategy object.
        """
        return {"@module": self.__class__.__module__,
                "@class": self.__class__.__name__,
                "additional_condition": self._additional_condition,
                "symmetry_measure_type": self.symmetry_measure_type,
                "dist_ang_area_weight": self.dist_ang_area_weight.as_dict()
                if self.dist_ang_area_weight is not None else None,
                "self_csm_weight": self.self_csm_weight.as_dict()
                if self.self_csm_weight is not None else None,
                "delta_csm_weight": self.delta_csm_weight.as_dict()
                if self.delta_csm_weight is not None else None,
                "cn_bias_weight": self.cn_bias_weight.as_dict()
                if self.cn_bias_weight is not None else None,
                "angle_weight": self.angle_weight.as_dict()
                if self.angle_weight is not None else None,
                "normalized_angle_distance_weight": self.normalized_angle_distance_weight.as_dict()
                if self.normalized_angle_distance_weight is not None else None,
                "ce_estimator": self.ce_estimator,
                }


Instruction:
Explain what the following Python 3 code does
def from_dict(cls, d):
        if d["normalized_angle_distance_weight"] is not None:
            nad_w = NormalizedAngleDistanceNbSetWeight.from_dict(d["normalized_angle_distance_weight"])
        else:
            nad_w = None
        return cls(additional_condition=d["additional_condition"],
                   symmetry_measure_type=d["symmetry_measure_type"],
                   dist_ang_area_weight=DistanceAngleAreaNbSetWeight.from_dict(d["dist_ang_area_weight"])
                   if d["dist_ang_area_weight"] is not None else None,
                   self_csm_weight=SelfCSMNbSetWeight.from_dict(d["self_csm_weight"])
                   if d["self_csm_weight"] is not None else None,
                   delta_csm_weight=DeltaCSMNbSetWeight.from_dict(d["delta_csm_weight"])
                   if d["delta_csm_weight"] is not None else None,
                   cn_bias_weight=CNBiasNbSetWeight.from_dict(d["cn_bias_weight"])
                   if d["cn_bias_weight"] is not None else None,
                   angle_weight=AngleNbSetWeight.from_dict(d["angle_weight"])
                   if d["angle_weight"] is not None else None,
                   normalized_angle_distance_weight=nad_w,
                   ce_estimator=d["ce_estimator"])

Response: Reconstructs the MultiWeightsChemenvStrategy object from a dictionary representation of the MultiWeightsChemenvStrategy object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pauling_stability_ratio(self):
        if self._pauling_stability_ratio is None:
            if self.ce_symbol in ['S:1', 'L:2']:
                self._pauling_stability_ratio = 0.0
            else:
                mindist_anions = 1000000.0
                mindist_cation_anion = 1000000.0
                for ipt1 in range(len(self.points)):
                    pt1 = np.array(self.points[ipt1])
                    mindist_cation_anion = min(mindist_cation_anion,
                                               np.linalg.norm(pt1-self.central_site))
                    for ipt2 in range(ipt1+1, len(self.points)):
                        pt2 = np.array(self.points[ipt2])
                        mindist_anions = min(mindist_anions,
                                             np.linalg.norm(pt1-pt2))
                anion_radius = mindist_anions / 2.0
                cation_radius = mindist_cation_anion - anion_radius
                self._pauling_stability_ratio = cation_radius / anion_radius
        return self._pauling_stability_ratio

Response: Returns the theoretical Pauling stability ratio for this environment.


Instruction:
Can you generate the documentation for the following Python 3 function
def number_of_permutations(self):
        if self.permutations_safe_override:
            return factorial(self.coordination)
        elif self.permutations is None:
            return factorial(self.coordination)
        return len(self.permutations)

Response: Returns the number of permutations of this coordination geometry.


Instruction:
How would you implement a function in Python 3 that
returns the list of faces of this coordination geometry. Each face is given as a list of its vertices coordinates.

Response:
def faces(self, sites, permutation=None):
        """
        Returns the list of faces of this coordination geometry. Each face is given as a
        list of its vertices coordinates.
        """
        if permutation is None:
            coords = [site.coords for site in sites]
        else:
            coords = [sites[ii].coords for ii in permutation]
        return [[coords[ii] for ii in f] for f in self._faces]


Instruction:
Can you generate the documentation for the following Python 3 function
def edges(self, sites, permutation=None, input='sites'):
        if input == 'sites':
            coords = [site.coords for site in sites]
        elif input == 'coords':
            coords = sites
        # if permutation is None:
        #     coords = [site.coords for site in sites]
        # else:
        #     coords = [sites[ii].coords for ii in permutation]
        if permutation is not None:
            coords = [coords[ii] for ii in permutation]
        return [[coords[ii] for ii in e] for e in self._edges]

Response:
Returns the list of edges of this coordination geometry. Each edge is given as a
        list of its end vertices coordinates.


Instruction:
Here you have a function in Python 3, explain what it does
def solid_angles(self, permutation=None):
        if permutation is None:
            return self._solid_angles
        else:
            return [self._solid_angles[ii] for ii in permutation]

Response: Returns the list of perfect solid angles.


Instruction:
Here you have a function in Python 3, explain what it does
def get_pmeshes(self, sites, permutation=None):
        pmeshes = []
        # _vertices = [site.coords for site in sites]
        if permutation is None:
            _vertices = [site.coords for site in sites]
        else:
            _vertices = [sites[ii].coords for ii in permutation]
        _face_centers = []
        number_of_faces = 0
        for face in self._faces:
            if len(face) in [3, 4]:
                number_of_faces += 1
            else:
                number_of_faces += len(face)

            _face_centers.append(np.array([np.mean([_vertices[face_vertex][ii]
                                                    for face_vertex in face])
                                           for ii in range(3)]))

        out = '{}\n'.format(len(_vertices) + len(_face_centers))
        for vv in _vertices:
            out += '{:15.8f} {:15.8f} {:15.8f}\n'.format(vv[0], vv[1], vv[2])
        for fc in _face_centers:
            out += '{:15.8f} {:15.8f} {:15.8f}\n'.format(fc[0], fc[1], fc[2])
        out += '{:d}\n'.format(number_of_faces)
        for iface, face in enumerate(self._faces):
            if len(face) == 3:
                out += '4\n'
            elif len(face) == 4:
                out += '5\n'
            else:
                for ii in range(len(face)):
                    out += '4\n'
                    out += '{:d}\n'.format(len(_vertices) + iface)
                    out += '{:d}\n'.format(face[ii])
                    out += '{:d}\n'.format(face[np.mod(ii + 1, len(face))])
                    out += '{:d}\n'.format(len(_vertices) + iface)
            if len(face) in [3, 4]:
                for face_vertex in face:
                    out += '{:d}\n'.format(face_vertex)
                out += '{:d}\n'.format(face[0])
        pmeshes.append({"pmesh_string": out})
        return pmeshes

Response: Returns the pmesh strings used for jmol to show this geometry.


Instruction:
Write a Python 3 function that can
return a list of coordination geometries with the given coordination number.

Response:
def get_geometries(self, coordination=None, returned='cg'):
        """
        Returns a list of coordination geometries with the given coordination number.
        :param coordination: The coordination number of which the list of coordination geometries are returned.
        """
        geom = list()
        if coordination is None:
            for gg in self.cg_list:
                if returned == 'cg':
                    geom.append(gg)
                elif returned == 'mp_symbol':
                    geom.append(gg.mp_symbol)
        else:
            for gg in self.cg_list:
                if gg.get_coordination_number() == coordination:
                    if returned == 'cg':
                        geom.append(gg)
                    elif returned == 'mp_symbol':
                        geom.append(gg.mp_symbol)
        return geom


Instruction:
Here you have a function in Python 3, explain what it does
def get_implemented_geometries(self, coordination=None, returned='cg',
                                   include_deactivated=False):
        """
        Returns a list of the implemented coordination geometries with the given coordination number.
        :param coordination: The coordination number of which the list of implemented coordination geometries
        are returned.
        """
        geom = list()
        if coordination is None:
            for gg in self.cg_list:
                if gg.points is not None and (
                            (not gg.deactivate) or include_deactivated):
                    if returned == 'cg':
                        geom.append(gg)
                    elif returned == 'mp_symbol':
                        geom.append(gg.mp_symbol)
        else:
            for gg in self.cg_list:
                if gg.get_coordination_number() == coordination and gg.points is not None and \
                        ((not gg.deactivate) or include_deactivated):
                    if returned == 'cg':
                        geom.append(gg)
                    elif returned == 'mp_symbol':
                        geom.append(gg.mp_symbol)
        return geom

Response: Returns a list of the implemented coordination geometries with the given coordination number.


Instruction:
Explain what the following Python 3 code does
def get_not_implemented_geometries(self, coordination=None,
                                       returned='mp_symbol'):
        """
        Returns a list of the implemented coordination geometries with the given coordination number.
        :param coordination: The coordination number of which the list of implemented coordination geometries
        are returned.
        """
        geom = list()
        if coordination is None:
            for gg in self.cg_list:
                if gg.points is None:
                    if returned == 'cg':
                        geom.append(gg)
                    elif returned == 'mp_symbol':
                        geom.append(gg.mp_symbol)
        else:
            for gg in self.cg_list:
                if gg.get_coordination_number() == coordination and gg.points is None:
                    if returned == 'cg':
                        geom.append(gg)
                    elif returned == 'mp_symbol':
                        geom.append(gg.mp_symbol)
        return geom

Response: Returns a list of the implemented coordination geometries with the given coordination number.


Instruction:
Can you tell what is the following Python 3 function doing
def get_geometry_from_name(self, name):
        for gg in self.cg_list:
            if gg.name == name or name in gg.alternative_names:
                return gg
        raise LookupError(
            'No coordination geometry found with name "{name}"'.format(
                name=name))

Response: Returns the coordination geometry of the given name.


Instruction:
Explain what the following Python 3 code does
def get_geometry_from_IUPAC_symbol(self, IUPAC_symbol):
        for gg in self.cg_list:
            if gg.IUPAC_symbol == IUPAC_symbol:
                return gg
        raise LookupError(
            'No coordination geometry found with IUPAC symbol "{symbol}"'.format(
                symbol=IUPAC_symbol))

Response: Returns the coordination geometry of the given IUPAC symbol.


Instruction:
Here you have a function in Python 3, explain what it does
def get_geometry_from_IUCr_symbol(self, IUCr_symbol):
        for gg in self.cg_list:
            if gg.IUCr_symbol == IUCr_symbol:
                return gg
        raise LookupError(
            'No coordination geometry found with IUCr symbol "{symbol}"'.format(
                symbol=IUCr_symbol))

Response: Returns the coordination geometry of the given IUCr symbol.


Instruction:
Write a Python 3 script for
returning the coordination geometry of the given mp_symbol.

Response:
def get_geometry_from_mp_symbol(self, mp_symbol):
        """
        Returns the coordination geometry of the given mp_symbol.
        :param mp_symbol: The mp_symbol of the coordination geometry.
        """
        for gg in self.cg_list:
            if gg.mp_symbol == mp_symbol:
                return gg
        raise LookupError(
            'No coordination geometry found with mp_symbol "{symbol}"'.format(
                symbol=mp_symbol))


Instruction:
Make a summary of the following Python 3 code
def is_a_valid_coordination_geometry(self, mp_symbol=None,
                                         IUPAC_symbol=None, IUCr_symbol=None,
                                         name=None, cn=None):
        """
        Checks whether a given coordination geometry is valid (exists) and whether the parameters are coherent with
        each other.
        :param IUPAC_symbol:
        :param IUCr_symbol:
        :param name:
        :param cn:
        :param mp_symbol: The mp_symbol of the coordination geometry.
        """
        if name is not None:
            raise NotImplementedError(
                'is_a_valid_coordination_geometry not implemented for the name')
        if mp_symbol is None and IUPAC_symbol is None and IUCr_symbol is None:
            raise SyntaxError(
                'missing argument for is_a_valid_coordination_geometry : at least one of mp_symbol, '
                'IUPAC_symbol and IUCr_symbol must be passed to the function')
        if mp_symbol is not None:
            try:
                cg = self.get_geometry_from_mp_symbol(mp_symbol)
                if IUPAC_symbol is not None:
                    if IUPAC_symbol != cg.IUPAC_symbol:
                        return False
                if IUCr_symbol is not None:
                    if IUCr_symbol != cg.IUCr_symbol:
                        return False
                if cn is not None:
                    if int(cn) != int(cg.coordination_number):
                        return False
                return True
            except LookupError:
                return False
        elif IUPAC_symbol is not None:
            try:
                cg = self.get_geometry_from_IUPAC_symbol(IUPAC_symbol)
                if IUCr_symbol is not None:
                    if IUCr_symbol != cg.IUCr_symbol:
                        return False
                if cn is not None:
                    if cn != cg.coordination_number:
                        return False
                return True
            except LookupError:
                return False
        elif IUCr_symbol is not None:
            try:
                cg = self.get_geometry_from_IUCr_symbol(IUCr_symbol)
                if cn is not None:
                    if cn != cg.coordination_number:
                        return False
                return True
            except LookupError:
                return True
        raise Exception('Should not be here !')

Response: Checks whether a given coordination geometry is valid.


Instruction:
How would you code a function in Python 3 to
test whether two species are exactly the same.

Response:
def are_equal(self, sp1, sp2):
        """
        True if species are exactly the same, i.e., Fe2+ == Fe2+ but not
        Fe3+. and the spins are reversed. i.e., spin up maps to spin down,
        and vice versa.

        Args:
            sp1: First species. A dict of {specie/element: amt} as per the
                definition in Site and PeriodicSite.
            sp2: Second species. A dict of {specie/element: amt} as per the
                definition in Site and PeriodicSite.

        Returns:
            Boolean indicating whether species are equal.
        """
        for s1 in sp1.keys():
            spin1 = getattr(s1, "spin", 0)
            oxi1 = getattr(s1, "oxi_state", 0)
            for s2 in sp2.keys():
                spin2 = getattr(s2, "spin", 0)
                oxi2 = getattr(s2, "oxi_state", 0)
                if (s1.symbol == s2.symbol and oxi1 == oxi2 and
                        spin2 == -spin1):
                    break
            else:
                return False
        return True


Instruction:
Given the following Python 3 function, write the documentation
def are_equal(self, sp1, sp2):
        comp1 = Composition(sp1)
        comp2 = Composition(sp2)
        return comp1.get_el_amt_dict() == comp2.get_el_amt_dict()

Response: Returns True if element : amounts are exactly the same i. e. element : amounts are not considered.


Instruction:
Here you have a function in Python 3, explain what it does
def are_equal(self, sp1, sp2):
        set1 = set(sp1.elements)
        set2 = set(sp2.elements)
        return set1.issubset(set2) or set2.issubset(set1)

Response: Returns True if there is some overlap in composition between the species


Instruction:
Here you have a function in Python 3, explain what it does
def are_equal(self, sp1, sp2):
        set1 = set(sp1.element_composition.values())
        set2 = set(sp2.element_composition.values())
        if set1 == set2:
            return True
        else:
            return False

Response: Returns True if sets of occupancies ( amt ) are equal on both sites.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _get_supercell_size(self, s1, s2):
        if self._supercell_size == 'num_sites':
            fu = s2.num_sites / s1.num_sites
        elif self._supercell_size == 'num_atoms':
            fu = s2.composition.num_atoms / s1.composition.num_atoms
        elif self._supercell_size == 'volume':
            fu = s2.volume / s1.volume
        else:
            try:
                el = get_el_sp(self._supercell_size)
                fu = s2.composition[el] / s1.composition[el]
            except:
                raise ValueError('Invalid argument for supercell_size.')

        if fu < 2/3:
            return int(round(1/fu)), False
        else:
            return int(round(fu)), True

Response:
Returns the supercell size and whether the supercell should
        be applied to s1.


Instruction:
Create a Python 3 function for
yielding lattices for s with lengths and angles close to the lattice of target_s.

Response:
def _get_lattices(self, target_lattice, s, supercell_size=1):
        """
        Yields lattices for s with lengths and angles close to the
        lattice of target_s. If supercell_size is specified, the
        returned lattice will have that number of primitive cells
        in it

        Args:
            s, target_s: Structure objects
        """
        lattices = s.lattice.find_all_mappings(
            target_lattice, ltol=self.ltol, atol=self.angle_tol,
            skip_rotation_matrix=True)
        for l, _, scale_m in lattices:
            if abs(abs(np.linalg.det(scale_m)) - supercell_size) < 0.5:
                yield l, scale_m


Instruction:
Make a summary of the following Python 3 code
def _get_supercells(self, struct1, struct2, fu, s1_supercell):
        def av_lat(l1, l2):
            params = (np.array(l1.lengths_and_angles) +
                      np.array(l2.lengths_and_angles)) / 2
            return Lattice.from_lengths_and_angles(*params)

        def sc_generator(s1, s2):
            s2_fc = np.array(s2.frac_coords)
            if fu == 1:
                cc = np.array(s1.cart_coords)
                for l, sc_m in self._get_lattices(s2.lattice, s1, fu):
                    fc = l.get_fractional_coords(cc)
                    fc -= np.floor(fc)
                    yield fc, s2_fc, av_lat(l, s2.lattice), sc_m
            else:
                fc_init = np.array(s1.frac_coords)
                for l, sc_m in self._get_lattices(s2.lattice, s1, fu):
                    fc = np.dot(fc_init, np.linalg.inv(sc_m))
                    lp = lattice_points_in_supercell(sc_m)
                    fc = (fc[:, None, :] + lp[None, :, :]).reshape((-1, 3))
                    fc -= np.floor(fc)
                    yield fc, s2_fc, av_lat(l, s2.lattice), sc_m
        if s1_supercell:
            for x in sc_generator(struct1, struct2):
                yield x
        else:
            for x in sc_generator(struct2, struct1):
                # reorder generator output so s1 is still first
                yield x[1], x[0], x[2], x[3]

Response: Returns all supercells of two structures.


Instruction:
How would you explain what the following Python 3 function does
def _cmp_fstruct(self, s1, s2, frac_tol, mask):
        if len(s2) > len(s1):
            raise ValueError("s1 must be larger than s2")
        if mask.shape != (len(s2), len(s1)):
            raise ValueError("mask has incorrect shape")

        return is_coord_subset_pbc(s2, s1, frac_tol, mask)

Response: Compare two sets of time fields.


Instruction:
Here you have a function in Python 3, explain what it does
def _cart_dists(self, s1, s2, avg_lattice, mask, normalization, lll_frac_tol=None):
        if len(s2) > len(s1):
            raise ValueError("s1 must be larger than s2")
        if mask.shape != (len(s2), len(s1)):
            raise ValueError("mask has incorrect shape")

        # vectors are from s2 to s1
        vecs, d_2 = pbc_shortest_vectors(avg_lattice, s2, s1, mask,
                                         return_d2=True,
                                         lll_frac_tol=lll_frac_tol)
        lin = LinearAssignment(d_2)
        s = lin.solution
        short_vecs = vecs[np.arange(len(s)), s]
        translation = np.average(short_vecs, axis=0)
        f_translation = avg_lattice.get_fractional_coords(translation)
        new_d2 = np.sum((short_vecs - translation) ** 2, axis=-1)

        return new_d2 ** 0.5 * normalization, f_translation, s

Response: Returns the set of dissimilarities between two sets of species s1 and s2.


Instruction:
Can you tell what is the following Python 3 function doing
def _get_mask(self, struct1, struct2, fu, s1_supercell):
        mask = np.zeros((len(struct2), len(struct1), fu), dtype=np.bool)

        inner = []
        for sp2, i in itertools.groupby(enumerate(struct2.species_and_occu),
                                        key=lambda x: x[1]):
            i = list(i)
            inner.append((sp2, slice(i[0][0], i[-1][0]+1)))

        for sp1, j in itertools.groupby(enumerate(struct1.species_and_occu),
                                        key=lambda x: x[1]):
            j = list(j)
            j = slice(j[0][0], j[-1][0]+1)
            for sp2, i in inner:
                mask[i, j, :] = not self._comparator.are_equal(sp1, sp2)

        if s1_supercell:
            mask = mask.reshape((len(struct2), -1))
        else:
            # supercell is of struct2, roll fu axis back to preserve
            # correct ordering
            mask = np.rollaxis(mask, 2, 1)
            mask = mask.reshape((-1, len(struct1)))

        # find the best translation indices
        i = np.argmax(np.sum(mask, axis=-1))
        inds = np.where(np.invert(mask[i]))[0]
        if s1_supercell:
            # remove the symmetrically equivalent s1 indices
            inds = inds[::fu]
        return np.array(mask, dtype=np.int_), inds, i

Response: Returns a mask for matching struct1 to struct2.


Instruction:
Given the following Python 3 function, write the documentation
def fit(self, struct1, struct2):
        struct1, struct2 = self._process_species([struct1, struct2])

        if not self._subset and self._comparator.get_hash(struct1.composition) \
                != self._comparator.get_hash(struct2.composition):
            return None

        struct1, struct2, fu, s1_supercell = self._preprocess(struct1, struct2)
        match = self._match(struct1, struct2, fu, s1_supercell,
                            break_on_match=True)

        if match is None:
            return False
        else:
            return match[0] <= self.stol

Response:
Fit two structures.

        Args:
            struct1 (Structure): 1st structure
            struct2 (Structure): 2nd structure

        Returns:
            True or False.


Instruction:
Here you have a function in Python 3, explain what it does
def get_rms_dist(self, struct1, struct2):
        struct1, struct2 = self._process_species([struct1, struct2])
        struct1, struct2, fu, s1_supercell = self._preprocess(struct1, struct2)
        match = self._match(struct1, struct2, fu, s1_supercell, use_rms=True,
                            break_on_match=False)

        if match is None:
            return None
        else:
            return match[0], max(match[1])

Response: Calculates the RMS displacement between two structures.