Instruction:
How would you code a function in Python 3 to
get specific COHP object.

Response:
def get_cohp_by_label(self, label):
        """
        Get specific COHP object.

        Args:
            label: string (for newer Lobster versions: a number)

        Returns:
            Returns the COHP object to simplify plotting
        """
        if label.lower() == "average":
            return Cohp(efermi=self.efermi, energies=self.energies,
                        cohp=self.cohp, are_coops=self.are_coops, icohp=self.icohp)
        else:
            try:
                return Cohp(efermi=self.efermi, energies=self.energies,
                            cohp=self.all_cohps[label].get_cohp(spin=None, integrated=False),
                            are_coops=self.are_coops,
                            icohp=self.all_cohps[label].get_icohp(spin=None))

            except KeyError:
                print("The label does not exist")


Instruction:
Write a Python 3 function that can
return a COHP object that includes a summed COHP divided by divisor.

Response:
def get_summed_cohp_by_label_list(self, label_list, divisor=1):
        """
        Returns a COHP object that includes a summed COHP divided by divisor

        Args:
            label_list: list of labels for the COHP that should be included in the summed cohp
            divisor: float/int, the summed cohp will be divided by this divisor
        Returns:
            Returns a COHP object including a summed COHP
        """
        # check if cohps are spinpolarized or not
        first_cohpobject = self.get_cohp_by_label(label_list[0])
        summed_cohp = first_cohpobject.cohp.copy()
        summed_icohp = first_cohpobject.icohp.copy()
        for label in label_list[1:]:
            cohp_here = self.get_cohp_by_label(label)
            summed_cohp[Spin.up] = np.sum([summed_cohp[Spin.up], cohp_here.cohp[Spin.up]], axis=0)
            if Spin.down in summed_cohp:
                summed_cohp[Spin.down] = np.sum([summed_cohp[Spin.down], cohp_here.cohp[Spin.down]], axis=0)
            summed_icohp[Spin.up] = np.sum([summed_icohp[Spin.up], cohp_here.icohp[Spin.up]], axis=0)
            if Spin.down in summed_icohp:
                summed_icohp[Spin.down] = np.sum([summed_icohp[Spin.down], cohp_here.icohp[Spin.down]], axis=0)

        divided_cohp = {}
        divided_icohp = {}
        divided_cohp[Spin.up] = np.divide(summed_cohp[Spin.up], divisor)
        divided_icohp[Spin.up] = np.divide(summed_icohp[Spin.up], divisor)
        if Spin.down in summed_cohp:
            divided_cohp[Spin.down] = np.divide(summed_cohp[Spin.down], divisor)
            divided_icohp[Spin.down] = np.divide(summed_icohp[Spin.down], divisor)

        return Cohp(efermi=first_cohpobject.efermi, energies=first_cohpobject.energies, cohp=divided_cohp,
                    are_coops=first_cohpobject.are_coops,
                    icohp=divided_icohp)


Instruction:
Can you implement a function in Python 3 that
returns a COHP object that includes a summed COHP divided by divisor.

Response:
def get_summed_cohp_by_label_and_orbital_list(self, label_list, orbital_list, divisor=1):
        """
        Returns a COHP object that includes a summed COHP divided by divisor

        Args:
            label_list: list of labels for the COHP that should be included in the summed cohp
            orbital_list: list of orbitals for the COHPs that should be included in the summed cohp (same order as label_list)
            divisor: float/int, the summed cohp will be divided by this divisor
        Returns:
            Returns a COHP object including a summed COHP
        """
        # check if cohps are spinpolarized or not
        first_cohpobject = self.get_orbital_resolved_cohp(label_list[0], orbital_list[0])
        summed_cohp = first_cohpobject.cohp.copy()
        summed_icohp = first_cohpobject.icohp.copy()
        for ilabel, label in enumerate(label_list[1:], 1):
            cohp_here = self.get_orbital_resolved_cohp(label, orbital_list[ilabel])
            summed_cohp[Spin.up] = np.sum([summed_cohp[Spin.up], cohp_here.cohp.copy()[Spin.up]], axis=0)
            if Spin.down in summed_cohp:
                summed_cohp[Spin.down] = np.sum([summed_cohp[Spin.down], cohp_here.cohp.copy()[Spin.down]], axis=0)
            summed_icohp[Spin.up] = np.sum([summed_icohp[Spin.up], cohp_here.icohp.copy()[Spin.up]], axis=0)
            if Spin.down in summed_icohp:
                summed_icohp[Spin.down] = np.sum([summed_icohp[Spin.down], cohp_here.icohp.copy()[Spin.down]], axis=0)

        divided_cohp = {}
        divided_icohp = {}
        divided_cohp[Spin.up] = np.divide(summed_cohp[Spin.up], divisor)
        divided_icohp[Spin.up] = np.divide(summed_icohp[Spin.up], divisor)
        if Spin.down in summed_cohp:
            divided_cohp[Spin.down] = np.divide(summed_cohp[Spin.down], divisor)
            divided_icohp[Spin.down] = np.divide(summed_icohp[Spin.down], divisor)

        return Cohp(efermi=first_cohpobject.efermi, energies=first_cohpobject.energies, cohp=divided_cohp,
                    are_coops=first_cohpobject.are_coops,
                    icohp=divided_icohp)


Instruction:
Implement a Python 3 function for
returning a cohp object with the orbital - resolved COHP.

Response:
def get_orbital_resolved_cohp(self, label, orbitals):
        """
        Get orbital-resolved COHP.

        Args:
            label: bond label (Lobster: labels as in ICOHPLIST/ICOOPLIST.lobster).

            orbitals: The orbitals as a label, or list or tuple of the form
                [(n1, orbital1), (n2, orbital2)]. Orbitals can either be str,
                int, or Orbital.

        Returns:
            A Cohp object if CompleteCohp contains orbital-resolved cohp,
            or None if it doesn't.

        Note: It currently assumes that orbitals are str if they aren't the
            other valid types. This is not ideal, but the easiest way to
            avoid unicode issues between python 2 and python 3.
        """
        if self.orb_res_cohp is None:
            return None
        elif isinstance(orbitals, list) or isinstance(orbitals, tuple):
            cohp_orbs = [d["orbitals"] for d in
                         self.orb_res_cohp[label].values()]
            orbs = []
            for orbital in orbitals:
                if isinstance(orbital[1], int):
                    orbs.append(tuple((orbital[0], Orbital(orbital[1]))))
                elif isinstance(orbital[1], Orbital):
                    orbs.append(tuple((orbital[0], orbital[1])))
                elif isinstance(orbital[1], str):
                    orbs.append(tuple((orbital[0], Orbital[orbital[1]])))
                else:
                    raise TypeError("Orbital must be str, int, or Orbital.")
            orb_index = cohp_orbs.index(orbs)
            orb_label = list(self.orb_res_cohp[label].keys())[orb_index]
        elif isinstance(orbitals, str):
            orb_label = orbitals
        else:
            raise TypeError("Orbitals must be str, list, or tuple.")
        try:
            icohp = self.orb_res_cohp[label][orb_label]["ICOHP"]
        except KeyError:
            icohp = None
        return Cohp(self.efermi, self.energies,
                    self.orb_res_cohp[label][orb_label]["COHP"],
                    icohp=icohp, are_coops=self.are_coops)


Instruction:
Can you tell what is the following Python 3 function doing
def from_dict(cls, d):
        cohp_dict = {}
        efermi = d["efermi"]
        energies = d["energies"]
        structure = Structure.from_dict(d["structure"])
        if "bonds" in d.keys():
            bonds = {bond: {"length": d["bonds"][bond]["length"],
                            "sites": tuple(PeriodicSite.from_dict(site)
                                           for site in d["bonds"][bond]["sites"])}
                     for bond in d["bonds"]}
        else:
            bonds = None
        for label in d["COHP"]:
            cohp = {Spin(int(spin)): np.array(d["COHP"][label][spin])
                    for spin in d["COHP"][label]}
            try:
                icohp = {Spin(int(spin)): np.array(d["ICOHP"][label][spin])
                         for spin in d["ICOHP"][label]}
            except KeyError:
                icohp = None
            if label == "average":
                avg_cohp = Cohp(efermi, energies, cohp, icohp=icohp)
            else:
                cohp_dict[label] = Cohp(efermi, energies, cohp, icohp=icohp)

        if "orb_res_cohp" in d.keys():
            orb_cohp = {}
            for label in d["orb_res_cohp"]:
                orb_cohp[label] = {}
                for orb in d["orb_res_cohp"][label]:
                    cohp = {Spin(int(s)): np.array(
                        d["orb_res_cohp"][label][orb]["COHP"][s],
                        dtype=float)
                        for s in d["orb_res_cohp"][label][orb]["COHP"]}
                    try:
                        icohp = {Spin(int(s)): np.array(
                            d["orb_res_cohp"][label][orb]["ICOHP"][s],
                            dtype=float)
                            for s in d["orb_res_cohp"][label][orb]["ICOHP"]}
                    except KeyError:
                        icohp = None
                    orbitals = [tuple((int(o[0]), Orbital[o[1]])) for o in
                                d["orb_res_cohp"][label][orb]["orbitals"]]
                    orb_cohp[label][orb] = {"COHP": cohp, "ICOHP": icohp,
                                            "orbitals": orbitals}
                # If no total COHPs are present, calculate the total
                # COHPs from the single-orbital populations. Total COHPs
                # may not be present when the cohpgenerator keyword is used
                # in LOBSTER versions 2.2.0 and earlier.
                if label not in d["COHP"] or d["COHP"][label] is None:
                    cohp = {Spin.up: np.sum(np.array(
                        [orb_cohp[label][orb]["COHP"][Spin.up]
                         for orb in orb_cohp[label]]), axis=0)}
                    try:
                        cohp[Spin.down] = np.sum(np.array(
                            [orb_cohp[label][orb]["COHP"][Spin.down]
                             for orb in orb_cohp[label]]), axis=0)
                    except KeyError:
                        pass

                orb_res_icohp = None in [orb_cohp[label][orb]["ICOHP"]
                                         for orb in orb_cohp[label]]
                if (label not in d["ICOHP"] or
                    d["ICOHP"][label] is None) and orb_res_icohp:
                    icohp = {Spin.up: np.sum(np.array(
                        [orb_cohp[label][orb]["ICOHP"][Spin.up]
                         for orb in orb_cohp[label]]), axis=0)}
                    try:
                        icohp[Spin.down] = np.sum(np.array(
                            [orb_cohp[label][orb]["ICOHP"][Spin.down]
                             for orb in orb_cohp[label]]), axis=0)
                    except KeyError:
                        pass
        else:
            orb_cohp = None

        if "average" not in d["COHP"].keys():
            # calculate average
            cohp = np.array([np.array(c)
                             for c in d["COHP"].values()]).mean(axis=0)
            try:
                icohp = np.array([np.array(c)
                                  for c in d["ICOHP"].values()]).mean(axis=0)
            except KeyError:
                icohp = None
            avg_cohp = Cohp(efermi, energies, cohp, icohp=icohp)

        return CompleteCohp(structure, avg_cohp, cohp_dict, bonds=bonds,
                            are_coops=d["are_coops"], orb_res_cohp=orb_cohp)

Response: Returns a CompleteCohp object from a dictionary representation.


Instruction:
Write a Python 3 function that can
create a CompleteCohp object from an output file of a COHP.

Response:
def from_file(cls, fmt, filename=None,
                  structure_file=None, are_coops=False):
        """
        Creates a CompleteCohp object from an output file of a COHP
        calculation. Valid formats are either LMTO (for the Stuttgart
        LMTO-ASA code) or LOBSTER (for the LOBSTER code).

        Args:
            cohp_file: Name of the COHP output file. Defaults to COPL
                for LMTO and COHPCAR.lobster/COOPCAR.lobster for LOBSTER.

            are_coops: Indicates whether the populations are COOPs or
                COHPs. Defaults to False for COHPs.

            fmt: A string for the code that was used to calculate
                the COHPs so that the output file can be handled
                correctly. Can take the values "LMTO" or "LOBSTER".

            structure_file: Name of the file containing the structure.
                If no file name is given, use CTRL for LMTO and POSCAR
                for LOBSTER.

        Returns:
            A CompleteCohp object.
        """
        fmt = fmt.upper()
        if fmt == "LMTO":
            # LMTO COOPs and orbital-resolved COHP cannot be handled yet.
            are_coops = False
            orb_res_cohp = None
            if structure_file is None:
                structure_file = "CTRL"
            if filename is None:
                filename = "COPL"
            cohp_file = LMTOCopl(filename=filename, to_eV=True)
        elif fmt == "LOBSTER":
            if structure_file is None:
                structure_file = "POSCAR"
            if filename is None:
                filename = "COOPCAR.lobster" if are_coops \
                    else "COHPCAR.lobster"
            warnings.warn(
                "The bond labels are currently consistent with ICOHPLIST.lobster/ICOOPLIST.lobster, not with COHPCAR.lobster/COOPCAR.lobster. Please be aware!")
            cohp_file = Cohpcar(filename=filename, are_coops=are_coops)
            orb_res_cohp = cohp_file.orb_res_cohp
        else:
            raise ValueError("Unknown format %s. Valid formats are LMTO "
                             "and LOBSTER." % fmt)

        structure = Structure.from_file(structure_file)
        efermi = cohp_file.efermi
        cohp_data = cohp_file.cohp_data
        energies = cohp_file.energies

        # Lobster shifts the energies so that the Fermi energy is at zero.
        # Shifting should be done by the plotter object though.

        spins = [Spin.up, Spin.down] if cohp_file.is_spin_polarized \
            else [Spin.up]
        if fmt == "LOBSTER":
            energies += efermi

        if orb_res_cohp is not None:
            # If no total COHPs are present, calculate the total
            # COHPs from the single-orbital populations. Total COHPs
            # may not be present when the cohpgenerator keyword is used
            # in LOBSTER versions 2.2.0 and earlier.
            # TODO: Test this more extensively
            for label in orb_res_cohp:
                if cohp_file.cohp_data[label]["COHP"] is None:
                    # print(label)
                    cohp_data[label]["COHP"] = {
                        sp: np.sum([orb_res_cohp[label][orbs]["COHP"][sp] for orbs in orb_res_cohp[label]], axis=0) for
                        sp
                        in spins}
                if cohp_file.cohp_data[label]["ICOHP"] is None:
                    cohp_data[label]["ICOHP"] = \
                        {sp: np.sum([orb_res_cohp[label][orbs]["ICOHP"][sp]
                                     for orbs in orb_res_cohp[label]],
                                    axis=0) for sp in spins}

        if fmt == "LMTO":
            # Calculate the average COHP for the LMTO file to be
            # consistent with LOBSTER output.
            avg_data = {"COHP": {}, "ICOHP": {}}
            for i in avg_data:
                for spin in spins:
                    rows = np.array([cohp_data[label][i][spin]
                                     for label in cohp_data])
                    avg = np.average(rows, axis=0)
                    # LMTO COHPs have 5 significant figures
                    avg_data[i].update({spin:
                                            np.array([round_to_sigfigs(a, 5)
                                                      for a in avg],
                                                     dtype=float)})
            avg_cohp = Cohp(efermi, energies,
                            avg_data["COHP"],
                            icohp=avg_data["ICOHP"])
        else:
            avg_cohp = Cohp(efermi, energies,
                            cohp_data["average"]["COHP"],
                            icohp=cohp_data["average"]["COHP"],
                            are_coops=are_coops)
            del cohp_data["average"]

        cohp_dict = {label: Cohp(efermi, energies,
                                 cohp_data[label]["COHP"],
                                 icohp=cohp_data[label]["ICOHP"],
                                 are_coops=are_coops)
                     for label in cohp_data}

        bond_dict = {label: {"length": cohp_data[label]["length"],
                             "sites": [structure.sites[site]
                                       for site in cohp_data[label]["sites"]]}
                     for label in cohp_data}

        return CompleteCohp(structure, avg_cohp, cohp_dict, bonds=bond_dict,
                            are_coops=are_coops, orb_res_cohp=orb_res_cohp)


Instruction:
Given the following Python 3 function, write the documentation
def icohpvalue(self, spin=Spin.up):
        if not self.is_spin_polarized and spin == Spin.down:
            raise ValueError("The calculation was not performed with spin polarization")

        return self._icohp[spin]

Response: Returns the icohpvalue corresponding to the chosen spin


Instruction:
Can you write a function in Python 3 where it
returns the sum of ICOHPs of both spin channels for polarized compounds

Response:
def summed_icohp(self):
        """
        Adds ICOHPs of both spin channels for spin polarized compounds
        Returns:
             icohp value in eV
        """
        if self._is_spin_polarized:
            sum_icohp = self._icohp[Spin.down] + self._icohp[Spin.up]
        else:
            sum_icohp = self._icohp[Spin.up]
        return sum_icohp


Instruction:
Given the following Python 3 function, write the documentation
def get_icohp_by_label(self, label, summed_spin_channels=True, spin=Spin.up):

        icohp_here = self._icohplist[label]
        if icohp_here._is_spin_polarized:
            if summed_spin_channels:
                return icohp_here.summed_icohp
            else:
                return icohp_here.icohpvalue(spin)
        else:
            return icohp_here.icohpvalue(spin)

Response: get an icohp value for a certain label


Instruction:
Implement a function in Python 3 to
get the sum of all ICOHPs in a list of labels

Response:
def get_summed_icohp_by_label_list(self, label_list, divisor=1.0, summed_spin_channels=True, spin=Spin.up):
        """
        get the sum of several ICOHP values that are indicated by a list of labels (labels of the bonds are the same as in ICOHPLIST/ICOOPLIST)
        Args:
            label_list: list of labels of the ICOHPs/ICOOPs that should be summed
            divisor: is used to divide the sum
            summed_spin_channels: Boolean to indicate whether the ICOHPs/ICOOPs of both spin channels should be summed
            spin: if summed_spin_channels is equal to False, this spin indicates which spin channel should be returned

        Returns:
             float that is a sum of all ICOHPs/ICOOPs as indicated with label_list
        """
        sum_icohp = 0
        for label in label_list:
            icohp_here = self._icohplist[label]
            if icohp_here.num_bonds != 1:
                warnings.warn("One of the ICOHP values is an average over bonds. This is currently not considered.")
            # prints warning if num_bonds is not equal to 1
            if icohp_here._is_spin_polarized:
                if summed_spin_channels:
                    sum_icohp = sum_icohp + icohp_here.summed_icohp
                else:
                    sum_icohp = sum_icohp + icohp_here.icohpvalue(spin)
            else:
                sum_icohp = sum_icohp + icohp_here.icohpvalue(spin)
        return sum_icohp / divisor


Instruction:
Can you tell what is the following Python 3 function doing
def get_icohp_dict_by_bondlengths(self, minbondlength=0.0, maxbondlength=8.0):
        newicohp_dict = {}
        for value in self._icohplist.values():
            if value._length >= minbondlength and value._length <= maxbondlength:
                newicohp_dict[value._label] = value
        return newicohp_dict

Response: get a dict of IcohpValues corresponding to certaind bond lengths


Instruction:
Explain what the following Python 3 code does
def get_icohp_dict_of_site(self, site, minsummedicohp=None, maxsummedicohp=None, minbondlength=0.0,
                               maxbondlength=8.0, only_bonds_to=None):
        """
        get a dict of IcohpValue for a certain site (indicated by integer)
        Args:
            site: integer describing the site of interest, order as in Icohplist.lobster/Icooplist.lobster, starts at 0
            minsummedicohp: float, minimal icohp/icoop of the bonds that are considered. It is the summed ICOHP value from both spin channels for spin polarized cases
            maxsummedicohp: float, maximal icohp/icoop of the bonds that are considered. It is the summed ICOHP value from both spin channels for spin polarized cases
            minbondlength: float, defines the minimum of the bond lengths of the bonds
            maxbondlength: float, defines the maximum of the bond lengths of the bonds
            only_bonds_to: list of strings describing the bonding partners that are allowed, e.g. ['O']
        Returns:
             dict of IcohpValues, the keys correspond to the values from the initial list_labels
        """

        newicohp_dict = {}
        for key, value in self._icohplist.items():
            atomnumber1 = int(re.split(r'(\d+)', value._atom1)[1]) - 1
            atomnumber2 = int(re.split(r'(\d+)', value._atom2)[1]) - 1
            if site == atomnumber1 or site == atomnumber2:
                # manipulate order of atoms so that searched one is always atom1
                if site == atomnumber2:
                    save = value._atom1
                    value._atom1 = value._atom2
                    value._atom2 = save

                if only_bonds_to is None:
                    second_test = True
                else:
                    second_test = (re.split(r'(\d+)', value._atom2)[0] in only_bonds_to)
                if value._length >= minbondlength and value._length <= maxbondlength and second_test:
                    if minsummedicohp is not None:
                        if value.summed_icohp >= minsummedicohp:
                            if maxsummedicohp is not None:
                                if value.summed_icohp <= maxsummedicohp:
                                    newicohp_dict[key] = value
                            else:
                                newicohp_dict[key] = value
                    else:
                        if maxsummedicohp is not None:
                            if value.summed_icohp <= maxsummedicohp:
                                newicohp_dict[key] = value
                        else:
                            newicohp_dict[key] = value

        return newicohp_dict

Response: get a dict of ICOHP values for a certain site


Instruction:
Here you have a function in Python 3, explain what it does
def extremum_icohpvalue(self, summed_spin_channels=True, spin=Spin.up):
        if not self._are_coops:
            extremum = sys.float_info.max
        else:
            extremum = -sys.float_info.max

        if not self._is_spin_polarized:
            if spin == Spin.down:
                warnings.warn("This spin channel does not exist. I am switching to Spin.up")
            spin = Spin.up

        for value in self._icohplist.values():
            if not value.is_spin_polarized or not summed_spin_channels:
                if not self._are_coops:
                    if value.icohpvalue(spin) < extremum:
                        extremum = value.icohpvalue(spin)
                        # print(extremum)
                else:
                    if value.icohpvalue(spin) > extremum:
                        extremum = value.icohpvalue(spin)
                        # print(extremum)
            else:
                if not self._are_coops:
                    if value.summed_icohp < extremum:
                        extremum = value.summed_icohp
                        # print(extremum)
                else:
                    if value.summed_icohp > extremum:
                        extremum = value.summed_icohp
                        # print(extremum)
        return extremum

Response: get the extremum value of the ICOHP of strongest bond


Instruction:
Make a summary of the following Python 3 code
def distance(self, other):
        return np.linalg.norm(other.coords - self.coords)

Response: Get distance between two sites.


Instruction:
Can you tell what is the following Python 3 function doing
def distance_from_point(self, pt):
        return np.linalg.norm(np.array(pt) - self.coords)

Response: Returns the distance between the site and a point in space.


Instruction:
Can you generate the documentation for the following Python 3 function
def species_string(self):
        if self.is_ordered:
            return list(self.species.keys())[0].__str__()
        else:
            sorted_species = sorted(self.species.keys())
            return ", ".join(["{}:{:.3f}".format(sp, self.species[sp])
                              for sp in sorted_species])

Response: Returns a string representation of the species of the current object.


Instruction:
Write a Python 3 script for
truing if site is an ordered site i. e. with a single species with occupancy 1.

Response:
def is_ordered(self):
        """
        True if site is an ordered site, i.e., with a single species with
        occupancy 1.
        """
        totaloccu = self.species.num_atoms
        return totaloccu == 1 and len(self.species) == 1


Instruction:
Write a Python 3 function for
creating a Site object from a dictionary representation.

Response:
def from_dict(cls, d):
        """
        Create Site from dict representation
        """
        atoms_n_occu = {}
        for sp_occu in d["species"]:
            if "oxidation_state" in sp_occu and Element.is_valid_symbol(
                    sp_occu["element"]):
                sp = Specie.from_dict(sp_occu)
            elif "oxidation_state" in sp_occu:
                sp = DummySpecie.from_dict(sp_occu)
            else:
                sp = Element(sp_occu["element"])
            atoms_n_occu[sp] = sp_occu["occu"]
        props = d.get("properties", None)
        return cls(atoms_n_occu, d["xyz"], properties=props)


Instruction:
Can you create a Python 3 function that
sets the lattice associated with this object

Response:
def lattice(self, lattice):
        """
        Sets Lattice associated with PeriodicSite
        """
        self._lattice = lattice
        self._coords = self._lattice.get_cartesian_coords(self._frac_coords)


Instruction:
How would you explain what the following Python 3 function does
def coords(self, coords):
        self._coords = np.array(coords)
        self._frac_coords = self._lattice.get_fractional_coords(self._coords)

Response: Set the coordinates of the log entry


Instruction:
Write a Python 3 function that can
set the fractional coordinates of the log entries

Response:
def frac_coords(self, frac_coords):
        """
        Fractional a coordinate
        """
        self._frac_coords = np.array(frac_coords)
        self._coords = self._lattice.get_cartesian_coords(self._frac_coords)


Instruction:
Can you write a function in Python 3 where it
returns a PeriodicSite object that is a unit cell cell.

Response:
def to_unit_cell(self, in_place=False):
        """
        Move frac coords to within the unit cell cell.
        """
        frac_coords = np.mod(self.frac_coords, 1)
        if in_place:
            self.frac_coords = frac_coords
        else:
            return PeriodicSite(self.species, frac_coords, self.lattice,
                                properties=self.properties)


Instruction:
Can you tell what is the following Python 3 function doing
def is_periodic_image(self, other, tolerance=1e-8, check_lattice=True):
        if check_lattice and self.lattice != other.lattice:
            return False
        if self.species != other.species:
            return False

        frac_diff = pbc_diff(self.frac_coords, other.frac_coords)
        return np.allclose(frac_diff, [0, 0, 0], atol=tolerance)

Response: Returns True if the two sites are periodic images of each other.


Instruction:
Can you implement a function in Python 3 that
gets the distance between site and a fractional coordinate assuming the periodic boundary conditions.

Response:
def distance_and_image_from_frac_coords(self, fcoords, jimage=None):
        """
        Gets distance between site and a fractional coordinate assuming
        periodic boundary conditions. If the index jimage of two sites atom j
        is not specified it selects the j image nearest to the i atom and
        returns the distance and jimage indices in terms of lattice vector
        translations. If the index jimage of atom j is specified it returns the
        distance between the i atom and the specified jimage atom, the given
        jimage is also returned.

        Args:
            fcoords (3x1 array): fcoords to get distance from.
            jimage (3x1 array): Specific periodic image in terms of
                lattice translations, e.g., [1,0,0] implies to take periodic
                image that is one a-lattice vector away. If jimage is None,
                the image that is nearest to the site is found.

        Returns:
            (distance, jimage): distance and periodic lattice translations
            of the other site for which the distance applies.
        """
        return self.lattice.get_distance_and_image(self.frac_coords, fcoords,
                                                   jimage=jimage)


Instruction:
Make a summary of the following Python 3 code
def as_dict(self, verbosity=0):
        species_list = []
        for spec, occu in self._species.items():
            d = spec.as_dict()
            del d["@module"]
            del d["@class"]
            d["occu"] = occu
            species_list.append(d)

        d = {"species": species_list,
             "abc": [float(c) for c in self._frac_coords],
             "lattice": self._lattice.as_dict(verbosity=verbosity),
             "@module": self.__class__.__module__,
             "@class": self.__class__.__name__}

        if verbosity > 0:
            d["xyz"] = [float(c) for c in self.coords]
            d["label"] = self.species_string

        d["properties"] = self.properties
        return d

Response: Json - serializable dict representation of the PeriodicSite.


Instruction:
Implement a Python 3 function for
getting the energy of the entry in the system.

Response:
def get_energies(rootdir, reanalyze, verbose, detailed, sort, fmt):
    """
    Doc string.
    """
    if verbose:
        logformat = "%(relativeCreated)d msecs : %(message)s"
        logging.basicConfig(level=logging.INFO, format=logformat)

    if not detailed:
        drone = SimpleVaspToComputedEntryDrone(inc_structure=True)
    else:
        drone = VaspToComputedEntryDrone(inc_structure=True,
                                         data=["filename",
                                               "initial_structure"])

    ncpus = multiprocessing.cpu_count()
    logging.info("Detected {} cpus".format(ncpus))
    queen = BorgQueen(drone, number_of_drones=ncpus)
    if os.path.exists(SAVE_FILE) and not reanalyze:
        msg = "Using previously assimilated data from {}.".format(SAVE_FILE) \
            + " Use -r to force re-analysis."
        queen.load_data(SAVE_FILE)
    else:
        if ncpus > 1:
            queen.parallel_assimilate(rootdir)
        else:
            queen.serial_assimilate(rootdir)
        msg = "Analysis results saved to {} for faster ".format(SAVE_FILE) + \
              "subsequent loading."
        queen.save_data(SAVE_FILE)

    entries = queen.get_data()
    if sort == "energy_per_atom":
        entries = sorted(entries, key=lambda x: x.energy_per_atom)
    elif sort == "filename":
        entries = sorted(entries, key=lambda x: x.data["filename"])

    all_data = []
    for e in entries:
        if not detailed:
            delta_vol = "{:.2f}".format(e.data["delta_volume"] * 100)
        else:
            delta_vol = e.structure.volume / \
                e.data["initial_structure"].volume - 1
            delta_vol = "{:.2f}".format(delta_vol * 100)
        all_data.append((e.data["filename"].replace("./", ""),
                         re.sub(r"\s+", "", e.composition.formula),
                         "{:.5f}".format(e.energy),
                         "{:.5f}".format(e.energy_per_atom),
                         delta_vol))
    if len(all_data) > 0:
        headers = ("Directory", "Formula", "Energy", "E/Atom", "% vol chg")
        print(tabulate(all_data, headers=headers, tablefmt=fmt))
        print("")
        print(msg)
    else:
        print("No valid vasp run found.")
        os.unlink(SAVE_FILE)


Instruction:
Explain what the following Python 3 code does
def get_pattern(self, structure, scaled=True, two_theta_range=(0, 90)):
        if self.symprec:
            finder = SpacegroupAnalyzer(structure, symprec=self.symprec)
            structure = finder.get_refined_structure()

        wavelength = self.wavelength
        latt = structure.lattice
        is_hex = latt.is_hexagonal()

        # Obtained from Bragg condition. Note that reciprocal lattice
        # vector length is 1 / d_hkl.
        min_r, max_r = (0, 2 / wavelength) if two_theta_range is None else \
            [2 * sin(radians(t / 2)) / wavelength for t in two_theta_range]

        # Obtain crystallographic reciprocal lattice points within range
        recip_latt = latt.reciprocal_lattice_crystallographic
        recip_pts = recip_latt.get_points_in_sphere(
            [[0, 0, 0]], [0, 0, 0], max_r)
        if min_r:
            recip_pts = [pt for pt in recip_pts if pt[1] >= min_r]

        # Create a flattened array of coeffs, fcoords and occus. This is
        # used to perform vectorized computation of atomic scattering factors
        # later. Note that these are not necessarily the same size as the
        # structure as each partially occupied specie occupies its own
        # position in the flattened array.
        coeffs = []
        fcoords = []
        occus = []
        dwfactors = []

        for site in structure:
            for sp, occu in site.species.items():
                try:
                    c = ATOMIC_SCATTERING_LEN[sp.symbol]
                except KeyError:
                    raise ValueError("Unable to calculate ND pattern as "
                                     "there is no scattering coefficients for"
                                     " %s." % sp.symbol)
                coeffs.append(c)
                dwfactors.append(self.debye_waller_factors.get(sp.symbol, 0))
                fcoords.append(site.frac_coords)
                occus.append(occu)

        coeffs = np.array(coeffs)
        fcoords = np.array(fcoords)
        occus = np.array(occus)
        dwfactors = np.array(dwfactors)
        peaks = {}
        two_thetas = []

        for hkl, g_hkl, ind, _ in sorted(
                recip_pts, key=lambda i: (i[1], -i[0][0], -i[0][1], -i[0][2])):
            # Force miller indices to be integers.
            hkl = [int(round(i)) for i in hkl]
            if g_hkl != 0:

                d_hkl = 1 / g_hkl

                # Bragg condition
                theta = asin(wavelength * g_hkl / 2)

                # s = sin(theta) / wavelength = 1 / 2d = |ghkl| / 2 (d =
                # 1/|ghkl|)
                s = g_hkl / 2

                # Calculate Debye-Waller factor
                dw_correction = np.exp(-dwfactors * (s**2))

                # Vectorized computation of g.r for all fractional coords and
                # hkl.
                g_dot_r = np.dot(fcoords, np.transpose([hkl])).T[0]

                # Structure factor = sum of atomic scattering factors (with
                # position factor exp(2j * pi * g.r and occupancies).
                # Vectorized computation.
                f_hkl = np.sum(coeffs * occus * np.exp(2j * pi * g_dot_r)
                               * dw_correction)

                # Lorentz polarization correction for hkl
                lorentz_factor = 1 / (sin(theta) ** 2 * cos(theta))

                # Intensity for hkl is modulus square of structure factor.
                i_hkl = (f_hkl * f_hkl.conjugate()).real

                two_theta = degrees(2 * theta)

                if is_hex:
                    # Use Miller-Bravais indices for hexagonal lattices.
                    hkl = (hkl[0], hkl[1], - hkl[0] - hkl[1], hkl[2])
                # Deal with floating point precision issues.
                ind = np.where(np.abs(np.subtract(two_thetas, two_theta)) <
                               self.TWO_THETA_TOL)
                if len(ind[0]) > 0:
                    peaks[two_thetas[ind[0][0]]][0] += i_hkl * lorentz_factor
                    peaks[two_thetas[ind[0][0]]][1].append(tuple(hkl))
                else:
                    peaks[two_theta] = [i_hkl * lorentz_factor, [tuple(hkl)],
                                        d_hkl]
                    two_thetas.append(two_theta)

        # Scale intensities so that the max intensity is 100.
        max_intensity = max([v[0] for v in peaks.values()])
        x = []
        y = []
        hkls = []
        d_hkls = []
        for k in sorted(peaks.keys()):
            v = peaks[k]
            fam = get_unique_families(v[1])
            if v[0] / max_intensity * 100 > self.SCALED_INTENSITY_TOL:
                x.append(k)
                y.append(v[0])
                hkls.append(fam)
                d_hkls.append(v[2])
        nd = DiffractionPattern(x, y, hkls, d_hkls)
        if scaled:
            nd.normalize(mode="max", value=100)
        return nd

Response: Calculates the powder neutron diffraction pattern for a structure.


Instruction:
Given the following Python 3 function, write the documentation
def find_equivalent_sites(self, site):
        for sites in self.equivalent_sites:
            if site in sites:
                return sites

        raise ValueError("Site not in structure")

Response: Finds all symmetrically equivalent sites for a particular site in the structure.


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

        init_folder = os.getcwd()
        os.chdir(self.folder)

        with zopen(self.log_file, 'w') as fout:
            subprocess.call([self._NWCHEM2FIESTA_cmd, self._nwcheminput_fn,
                             self._nwchemoutput_fn, self._nwchemmovecs_fn],
                            stdout=fout)

        os.chdir(init_folder)

Response: Runs actual NWCHEM2FIESTA run


Instruction:
How would you explain what the following Python 3 function does
def gw_run(self):

        if self.folder != os.getcwd():
            init_folder = os.getcwd()
            os.chdir(self.folder)

        with zopen(self.log_file, 'w') as fout:
            subprocess.call(["mpirun", "-n", str(self.mpi_procs), "fiesta",
                             str(self.grid[0]), str(self.grid[1]),
                             str(self.grid[2])], stdout=fout)

        if self.folder != os.getcwd():
            os.chdir(init_folder)

Response: Performs FIESTA ( gw ) run


Instruction:
Create a Python 3 function for
returning the number of nlm orbitals for the basis set

Response:
def set_n_nlmo(self):
        """
                :return: the number of nlm orbitals for the basis set
        """

        nnlmo = 0

        data_tmp = self.data
        data_tmp.pop('lmax')
        data_tmp.pop('n_nlo')
        data_tmp.pop('preamble')

        for l_zeta_ng in data_tmp:
            l = l_zeta_ng.split("_")[0]
            nnlmo = nnlmo + (2 * int(l) + 1)

        return str(nnlmo)


Instruction:
Create a Python 3 function for
returning a string with the information on the basis set

Response:
def infos_on_basis_set(self):
        """
        infos on the basis set as in Fiesta log
        """
        o = []
        o.append("=========================================")
        o.append("Reading basis set:")
        o.append("")
        o.append(" Basis set for {} atom ".format(str(self.filename)))
        o.append(" Maximum angular momentum = {}".format(self.data['lmax']))
        o.append(" Number of atomics orbitals = {}".format(self.data['n_nlo']))
        o.append(" Number of nlm orbitals = {}".format(self.data['n_nlmo']))
        o.append("=========================================")

        return str(0)


Instruction:
Implement a function in Python 3 to
copy in the desired folder the needed auxiliary basis set X2. ion

Response:
def set_auxiliary_basis_set(self, folder, auxiliary_folder,
                                auxiliary_basis_set_type="aug_cc_pvtz"):
        """
        copy in the desired folder the needed auxiliary basis set "X2.ion" where X is a specie.
        :param auxiliary_folder: folder where the auxiliary basis sets are stored
        :param auxiliary_basis_set_type: type of basis set (string to be found in the extension of the file name; must be in lower case)
               ex: C2.ion_aug_cc_pvtz_RI_Weigend find "aug_cc_pvtz"
        """

        list_files = os.listdir(auxiliary_folder)

        for specie in self._mol.symbol_set:
            for file in list_files:
                if file.upper().find(
                                specie.upper() + "2") != -1 and file.lower().find(
                        auxiliary_basis_set_type) != -1:
                    shutil.copyfile(auxiliary_folder + "/" + file,
                                    folder + "/" + specie + "2.ion")


Instruction:
Can you generate a brief explanation for the following Python 3 code
def set_GW_options(self, nv_band=10, nc_band=10, n_iteration=5, n_grid=6,
                       dE_grid=0.5):
        """
        Set parameters in cell.in for a GW computation
        :param nv__band: number of valence bands to correct with GW
        :param nc_band: number of conduction bands to correct with GW
        :param n_iteration: number of iteration
        :param n_grid and dE_grid:: number of points and spacing in eV for correlation grid
        """

        self.GW_options.update(nv_corr=nv_band, nc_corr=nc_band,
                               nit_gw=n_iteration)
        self.correlation_grid.update(dE_grid=dE_grid, n_grid=n_grid)

Response: Set parameters in cell. in for a GW computation


Instruction:
Write a Python 3 script for
making the full BSE Densities folder.

Response:
def make_FULL_BSE_Densities_folder(self, folder):
        """
        mkdir "FULL_BSE_Densities" folder (needed for bse run) in the desired folder
        """

        if os.path.exists(folder + "/FULL_BSE_Densities"):
            return "FULL_BSE_Densities folder already exists"
        else:
            os.makedirs(folder + "/FULL_BSE_Densities")
            return "makedirs FULL_BSE_Densities folder"


Instruction:
Make a summary of the following Python 3 code
def set_BSE_options(self, n_excitations=10, nit_bse=200):

        self.BSE_TDDFT_options.update(npsi_bse=n_excitations, nit_bse=nit_bse)

Response: Set parameters in cell. in for a BSE computation


Instruction:
Implement a Python 3 function for
dumping the BSE data in the GW run

Response:
def dump_BSE_data_in_GW_run(self, BSE_dump=True):
        """
        :param BSE_dump: boolean
        :return: set the "do_bse" variable to one in cell.in
        """

        if BSE_dump:
            self.BSE_TDDFT_options.update(do_bse=1, do_tddft=0)
        else:
            self.BSE_TDDFT_options.update(do_bse=0, do_tddft=0)


Instruction:
Write a Python 3 script to
dump the TDDFT data in the GW run

Response:
def dump_TDDFT_data_in_GW_run(self, TDDFT_dump=True):
        """
        :param TDDFT_dump: boolen
        :return: set the do_tddft variable to one in cell.in
        """
        if TDDFT_dump == True:
            self.BSE_TDDFT_options.update(do_bse=0, do_tddft=1)
        else:
            self.BSE_TDDFT_options.update(do_bse=0, do_tddft=0)


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

        o = []
        o.append("=========================================")
        o.append("Reading infos on system:")
        o.append("")
        o.append(" Number of atoms = {} ; number of species = {}".format(
            int(self._mol.composition.num_atoms), len(self._mol.symbol_set)))
        o.append(" Number of valence bands = {}".format(
            int(self._mol.nelectrons / 2)))
        o.append(" Sigma grid specs: n_grid = {} ;  dE_grid = {} (eV)".format(
            self.correlation_grid['n_grid'], self.correlation_grid['dE_grid']))
        if int(self.Exc_DFT_option['rdVxcpsi']) == 1:
            o.append(" Exchange and correlation energy read from Vxcpsi.mat")
        elif int(self.Exc_DFT_option['rdVxcpsi']) == 0:
            o.append(" Exchange and correlation energy re-computed")

        if self.COHSEX_options['eigMethod'] == "C":
            o.append(
                " Correcting  {} valence bands and   {} conduction bands at COHSEX level".format(
                    self.COHSEX_options['nv_cohsex'],
                    self.COHSEX_options['nc_cohsex']))
            o.append(" Performing   {} diagonal COHSEX iterations".format(
                self.COHSEX_options['nit_cohsex']))
        elif self.COHSEX_options['eigMethod'] == "HF":
            o.append(
                " Correcting  {} valence bands and   {} conduction bands at HF level".format(
                    self.COHSEX_options['nv_cohsex'],
                    self.COHSEX_options['nc_cohsex']))
            o.append(" Performing   {} diagonal HF iterations".format(
                self.COHSEX_options['nit_cohsex']))

        o.append(" Using resolution of identity : {}".format(
            self.COHSEX_options['resMethod']))
        o.append(
            " Correcting  {} valence bands and  {} conduction bands at GW level".format(
                self.GW_options['nv_corr'], self.GW_options['nc_corr']))
        o.append(
            " Performing   {} GW iterations".format(self.GW_options['nit_gw']))

        if int(self.BSE_TDDFT_options['do_bse']) == 1:
            o.append(" Dumping data for BSE treatment")

        if int(self.BSE_TDDFT_options['do_tddft']) == 1:
            o.append(" Dumping data for TD-DFT treatment")
        o.append("")
        o.append(" Atoms in cell cartesian A:")
        symbols = []
        for syb in self._mol.symbol_set:
            symbols.append(syb)

        for site in self._mol:
            o.append(" {} {} {} {}".format(site.x, site.y,
                                           site.z, int(
                    symbols.index(site.specie.symbol)) + 1))

        o.append("=========================================")

        return str(o)

Response: Returns a list of infos on the initial parameters as in the log file of Fiesta


Instruction:
Create a Python 3 function to
read an FiestaInput from a string.

Response:
def from_string(cls, string_input):
        """
        Read an FiestaInput from a string. Currently tested to work with
        files generated from this class itself.

        Args:
            string_input: string_input to parse.
        Returns:
            FiestaInput object
        """

        correlation_grid = {}
        Exc_DFT_option = {}
        COHSEX_options = {}
        GW_options = {}
        BSE_TDDFT_options = {}

        lines = string_input.strip().split("\n")

        # number of atoms and species
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        nat = toks[0]
        nsp = toks[1]
        # number of valence bands
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        nvbands = toks[0]

        # correlation_grid
        # number of points and spacing in eV for correlation grid
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        correlation_grid['n_grid'] = toks[0]
        correlation_grid['dE_grid'] = toks[1]

        # Exc DFT
        # relire=1 ou recalculer=0 Exc DFT
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        Exc_DFT_option['rdVxcpsi'] = toks[0]

        # COHSEX
        # number of COHSEX corrected occp and unoccp bands: C=COHSEX  H=HF
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        COHSEX_options['nv_cohsex'] = toks[0]
        COHSEX_options['nc_cohsex'] = toks[1]
        COHSEX_options['eigMethod'] = toks[2]
        # number of COHSEX iter, scf on wfns, mixing coeff; V=RI-V  I=RI-D
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        COHSEX_options['nit_cohsex'] = toks[0]
        COHSEX_options['resMethod'] = toks[1]
        COHSEX_options['scf_cohsex_wf'] = toks[2]
        COHSEX_options['mix_cohsex'] = toks[3]

        # GW
        # number of GW corrected occp and unoccp bands
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        GW_options['nv_corr'] = toks[0]
        GW_options['nc_corr'] = toks[1]
        # number of GW iterations
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        GW_options['nit_gw'] = toks[0]

        # BSE
        # dumping for BSE and TDDFT
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['do_bse'] = toks[0]
        BSE_TDDFT_options['do_tddft'] = toks[1]
        # number of occp. and virtual bands fo BSE: nocore and up to 40 eVs
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['nv_bse'] = toks[0]
        BSE_TDDFT_options['nc_bse'] = toks[1]
        # number of excitations needed and number of iterations
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        BSE_TDDFT_options['npsi_bse'] = toks[0]
        BSE_TDDFT_options['nit_bse'] = toks[1]

        # Molecule
        # list of symbols in order
        lines.pop(0)
        atname = []
        i = int(nsp)
        while i != 0:
            l = lines.pop(0).strip()
            toks = l.split()
            atname.append(toks[0])
            i -= 1

        # scaling factor
        lines.pop(0)
        l = lines.pop(0).strip()
        toks = l.split()
        scale = toks[0]
        # atoms x,y,z cartesian .. will be multiplied by scale
        lines.pop(0)
        # Parse geometry
        species = []
        coords = []
        i = int(nat)
        while i != 0:
            l = lines.pop(0).strip()
            toks = l.split()
            coords.append([float(j) for j in toks[0:3]])
            species.append(atname[int(toks[3]) - 1])
            i -= 1

        mol = Molecule(species, coords)

        return FiestaInput(mol=mol, correlation_grid=correlation_grid,
                           Exc_DFT_option=Exc_DFT_option,
                           COHSEX_options=COHSEX_options,
                           GW_options=GW_options,
                           BSE_TDDFT_options=BSE_TDDFT_options)


Instruction:
Can you tell what is the following Python 3 function doing
def from_file(cls, filename):
        with zopen(filename) as f:
            return cls.from_string(f.read())

Response:
Read an Fiesta input from a file. Currently tested to work with
            files generated from this class itself.


Instruction:
Write a Python 3 script for
undoing the last change in the TransformedStructure.

Response:
def undo_last_change(self):
        """
        Undo the last change in the TransformedStructure.

        Raises:
            IndexError: If already at the oldest change.
        """
        if len(self.history) == 0:
            raise IndexError("Can't undo. Already at oldest change.")
        if 'input_structure' not in self.history[-1]:
            raise IndexError("Can't undo. Latest history has no "
                             "input_structure")
        h = self.history.pop()
        self._undone.append((h, self.final_structure))
        s = h["input_structure"]
        if isinstance(s, dict):
            s = Structure.from_dict(s)
        self.final_structure = s


Instruction:
Given the following Python 3 function, write the documentation
def redo_next_change(self):
        if len(self._undone) == 0:
            raise IndexError("Can't redo. Already at latest change.")
        h, s = self._undone.pop()
        self.history.append(h)
        self.final_structure = s

Response: Redo the last undone change in the TransformedStructure.


Instruction:
Can you write a function in Python 3 where it
appends a transformation to the TransformedStructure.

Response:
def append_transformation(self, transformation, return_alternatives=False,
                              clear_redo=True):
        """
        Appends a transformation to the TransformedStructure.

        Args:
            transformation: Transformation to append
            return_alternatives: Whether to return alternative
                TransformedStructures for one-to-many transformations.
                return_alternatives can be a number, which stipulates the
                total number of structures to return.
            clear_redo: Boolean indicating whether to clear the redo list.
                By default, this is True, meaning any appends clears the
                history of undoing. However, when using append_transformation
                to do a redo, the redo list should not be cleared to allow
                multiple redos.
        """
        if clear_redo:
            self._undone = []

        if return_alternatives and transformation.is_one_to_many:
            ranked_list = transformation.apply_transformation(
                self.final_structure, return_ranked_list=return_alternatives)

            input_structure = self.final_structure.as_dict()
            alts = []
            for x in ranked_list[1:]:
                s = x.pop("structure")
                actual_transformation = x.pop("transformation", transformation)
                hdict = actual_transformation.as_dict()
                hdict["input_structure"] = input_structure
                hdict["output_parameters"] = x
                self.final_structure = s
                d = self.as_dict()
                d['history'].append(hdict)
                d['final_structure'] = s.as_dict()
                alts.append(TransformedStructure.from_dict(d))

            x = ranked_list[0]
            s = x.pop("structure")
            actual_transformation = x.pop("transformation", transformation)
            hdict = actual_transformation.as_dict()
            hdict["input_structure"] = self.final_structure.as_dict()
            hdict["output_parameters"] = x
            self.history.append(hdict)
            self.final_structure = s
            return alts
        else:
            s = transformation.apply_transformation(self.final_structure)
            hdict = transformation.as_dict()
            hdict["input_structure"] = self.final_structure.as_dict()
            hdict["output_parameters"] = {}
            self.history.append(hdict)
            self.final_structure = s


Instruction:
Write a Python 3 script to
add a filter to the list of entries in the final structure.

Response:
def append_filter(self, structure_filter):
        """
        Adds a filter.

        Args:
            structure_filter (StructureFilter): A filter implementating the
                AbstractStructureFilter API. Tells transmuter waht structures
                to retain.
        """
        hdict = structure_filter.as_dict()
        hdict["input_structure"] = self.final_structure.as_dict()
        self.history.append(hdict)


Instruction:
Make a summary of the following Python 3 code
def extend_transformations(self, transformations,
                               return_alternatives=False):
        """
        Extends a sequence of transformations to the TransformedStructure.

        Args:
            transformations: Sequence of Transformations
            return_alternatives: Whether to return alternative
                TransformedStructures for one-to-many transformations.
                return_alternatives can be a number, which stipulates the
                total number of structures to return.
        """
        for t in transformations:
            self.append_transformation(t,
                                       return_alternatives=return_alternatives)

Response: Extends a sequence of transformations to the TransformedStructure.


Instruction:
Create a Python 3 function for
returning VASP input as a dict of vasp objects.

Response:
def get_vasp_input(self, vasp_input_set=MPRelaxSet, **kwargs):
        """
        Returns VASP input as a dict of vasp objects.

        Args:
            vasp_input_set (pymatgen.io.vaspio_set.VaspInputSet): input set
                to create vasp input files from structures
        """
        d = vasp_input_set(self.final_structure, **kwargs).get_vasp_input()
        d["transformations.json"] = json.dumps(self.as_dict())
        return d


Instruction:
Can you tell what is the following Python 3 function doing
def write_vasp_input(self, vasp_input_set=MPRelaxSet, output_dir=".",
                         create_directory=True, **kwargs):
        """
        Writes VASP input to an output_dir.

        Args:
            vasp_input_set:
                pymatgen.io.vaspio_set.VaspInputSet like object that creates
                vasp input files from structures
            output_dir: Directory to output files
            create_directory: Create the directory if not present. Defaults to
                True.
            \\*\\*kwargs: All keyword args supported by the VASP input set.
        """
        vasp_input_set(self.final_structure, **kwargs).write_input(
            output_dir, make_dir_if_not_present=create_directory)
        with open(os.path.join(output_dir, "transformations.json"), "w") as fp:
            json.dump(self.as_dict(), fp)

Response: Writes VASP input to an output_dir.


Instruction:
Write a Python 3 function that can
return a list of all structures in the TransformedStructure.

Response:
def structures(self):
        """
        Copy of all structures in the TransformedStructure. A
        structure is stored after every single transformation.
        """
        hstructs = [Structure.from_dict(s['input_structure'])
                    for s in self.history if 'input_structure' in s]
        return hstructs + [self.final_structure]


Instruction:
Can you generate the documentation for the following Python 3 function
def from_cif_string(cif_string, transformations=None, primitive=True,
                        occupancy_tolerance=1.):
        """
        Generates TransformedStructure from a cif string.

        Args:
            cif_string (str): Input cif string. Should contain only one
                structure. For cifs containing multiple structures, please use
                CifTransmuter.
            transformations ([Transformations]): Sequence of transformations
                to be applied to the input structure.
            primitive (bool): Option to set if the primitive cell should be
                extracted. Defaults to True. However, there are certain
                instances where you might want to use a non-primitive cell,
                e.g., if you are trying to generate all possible orderings of
                partial removals or order a disordered structure.
            occupancy_tolerance (float): If total occupancy of a site is
                between 1 and occupancy_tolerance, the occupancies will be
                scaled down to 1.

        Returns:
            TransformedStructure
        """
        parser = CifParser.from_string(cif_string, occupancy_tolerance)
        raw_string = re.sub(r"'", "\"", cif_string)
        cif_dict = parser.as_dict()
        cif_keys = list(cif_dict.keys())
        s = parser.get_structures(primitive)[0]
        partial_cif = cif_dict[cif_keys[0]]
        if "_database_code_ICSD" in partial_cif:
            source = partial_cif["_database_code_ICSD"] + "-ICSD"
        else:
            source = "uploaded cif"
        source_info = {"source": source,
                       "datetime": str(datetime.datetime.now()),
                       "original_file": raw_string,
                       "cif_data": cif_dict[cif_keys[0]]}
        return TransformedStructure(s, transformations, history=[source_info])

Response: Generates a TransformedStructure from a string containing only one cifite structure.


Instruction:
How would you code a function in Python 3 to
generate a TransformedStructure from a string containing a POSCAR string.

Response:
def from_poscar_string(poscar_string, transformations=None):
        """
        Generates TransformedStructure from a poscar string.

        Args:
            poscar_string (str): Input POSCAR string.
            transformations ([Transformations]): Sequence of transformations
                to be applied to the input structure.
        """
        p = Poscar.from_string(poscar_string)
        if not p.true_names:
            raise ValueError("Transformation can be craeted only from POSCAR "
                             "strings with proper VASP5 element symbols.")
        raw_string = re.sub(r"'", "\"", poscar_string)
        s = p.structure
        source_info = {"source": "POSCAR",
                       "datetime": str(datetime.datetime.now()),
                       "original_file": raw_string}
        return TransformedStructure(s, transformations, history=[source_info])


Instruction:
Implement a function in Python 3 to
return a dict representation of the TransformedStructure.

Response:
def as_dict(self):
        """
        Dict representation of the TransformedStructure.
        """
        d = self.final_structure.as_dict()
        d["@module"] = self.__class__.__module__
        d["@class"] = self.__class__.__name__
        d["history"] = jsanitize(self.history)
        d["version"] = __version__
        d["last_modified"] = str(datetime.datetime.utcnow())
        d["other_parameters"] = jsanitize(self.other_parameters)
        return d


Instruction:
Implement a Python 3 function for
creating a TransformedStructure from a dict.

Response:
def from_dict(cls, d):
        """
        Creates a TransformedStructure from a dict.
        """
        s = Structure.from_dict(d)
        return cls(s, history=d["history"],
                   other_parameters=d.get("other_parameters", None))


Instruction:
Can you implement a function in Python 3 that
creates TransformedStructure from SNL.

Response:
def from_snl(cls, snl):
        """
        Create TransformedStructure from SNL.

        Args:
            snl (StructureNL): Starting snl

        Returns:
            TransformedStructure
        """
        hist = []
        for h in snl.history:
            d = h.description
            d['_snl'] = {'url': h.url, 'name': h.name}
            hist.append(d)
        return cls(snl.structure, history=hist)


Instruction:
Can you generate the documentation for the following Python 3 function
def from_file(feff_inp_file='feff.inp', ldos_file='ldos'):
        header_str = Header.header_string_from_file(feff_inp_file)
        header = Header.from_string(header_str)
        structure = header.struct
        nsites = structure.num_sites
        parameters = Tags.from_file(feff_inp_file)

        if "RECIPROCAL" in parameters:
            pot_dict = dict()
            pot_readstart = re.compile('.*iz.*lmaxsc.*xnatph.*xion.*folp.*')
            pot_readend = re.compile('.*ExternalPot.*switch.*')
            pot_inp = re.sub(r'feff.inp', r'pot.inp', feff_inp_file)
            dos_index = 1
            begin = 0

            with zopen(pot_inp, "r") as potfile:
                for line in potfile:
                    if len(pot_readend.findall(line)) > 0:
                        break

                    if begin == 1:
                        begin += 1
                        continue

                    if begin == 2:
                        z_number = int(line.strip().split()[0])
                        ele_name = Element.from_Z(z_number).name
                        if ele_name not in pot_dict:
                            pot_dict[ele_name] = dos_index
                        else:
                            pot_dict[ele_name] = min(dos_index, pot_dict[ele_name])
                        dos_index += 1

                    if len(pot_readstart.findall(line)) > 0:
                        begin = 1
        else:
            pot_string = Potential.pot_string_from_file(feff_inp_file)
            dicts = Potential.pot_dict_from_string(pot_string)
            pot_dict = dicts[0]

        with zopen(ldos_file + "00.dat", "r") as fobject:
            f = fobject.readlines()
        efermi = float(f[0].split()[4])

        dos_energies = []
        ldos = {}

        for i in range(1, len(pot_dict) + 1):
            if len(str(i)) == 1:
                ldos[i] = np.loadtxt("{}0{}.dat".format(ldos_file, i))
            else:
                ldos[i] = np.loadtxt("{}{}.dat".format(ldos_file, i))

        for i in range(0, len(ldos[1])):
            dos_energies.append(ldos[1][i][0])

        all_pdos = []
        vorb = {"s": Orbital.s, "p": Orbital.py, "d": Orbital.dxy,
                "f": Orbital.f0}
        forb = {"s": 0, "p": 1, "d": 2, "f": 3}

        dlength = len(ldos[1])

        for i in range(nsites):
            pot_index = pot_dict[structure.species[i].symbol]
            all_pdos.append(defaultdict(dict))
            for k, v in vorb.items():
                density = [ldos[pot_index][j][forb[k] + 1]
                           for j in range(dlength)]
                updos = density
                downdos = None
                if downdos:
                    all_pdos[-1][v] = {Spin.up: updos, Spin.down: downdos}
                else:
                    all_pdos[-1][v] = {Spin.up: updos}

        pdos = all_pdos
        vorb2 = {0: Orbital.s, 1: Orbital.py, 2: Orbital.dxy, 3: Orbital.f0}
        pdoss = {structure[i]: {v: pdos[i][v]
                                for v in vorb2.values()}
                 for i in range(len(pdos))}

        forb = {"s": 0, "p": 1, "d": 2, "f": 3}

        tdos = [0] * dlength
        for i in range(nsites):
            pot_index = pot_dict[structure.species[i].symbol]
            for v in forb.values():
                density = [ldos[pot_index][j][v + 1] for j in range(dlength)]
                for j in range(dlength):
                    tdos[j] = tdos[j] + density[j]
        tdos = {Spin.up: tdos}

        dos = Dos(efermi, dos_energies, tdos)
        complete_dos = CompleteDos(structure, dos, pdoss)
        charge_transfer = LDos.charge_transfer_from_file(feff_inp_file,
                                                         ldos_file)
        return LDos(complete_dos, charge_transfer)

Response: Creates a CFG object from a Feff input file.


Instruction:
Create a Python 3 function to
get charge transfer from feff. inp file and ldos. dat.

Response:
def charge_transfer_from_file(feff_inp_file, ldos_file):
        """
        Get charge transfer from file.

        Args:
            feff_inp_file (str): name of feff.inp file for run
            ldos_file (str): ldos filename for run, assume consequetive order,
                i.e., ldos01.dat, ldos02.dat....

        Returns:
            dictionary of dictionaries in order of potential sites
            ({"p": 0.154, "s": 0.078, "d": 0.0, "tot": 0.232}, ...)
        """
        cht = OrderedDict()
        parameters = Tags.from_file(feff_inp_file)

        if 'RECIPROCAL' in parameters:
            dicts = [dict()]
            pot_dict = dict()
            dos_index = 1
            begin = 0
            pot_inp = re.sub(r'feff.inp', r'pot.inp', feff_inp_file)
            pot_readstart = re.compile('.*iz.*lmaxsc.*xnatph.*xion.*folp.*')
            pot_readend = re.compile('.*ExternalPot.*switch.*')
            with zopen(pot_inp, "r") as potfile:
                for line in potfile:
                    if len(pot_readend.findall(line)) > 0:
                        break
                    if begin == 1:
                        z_number = int(line.strip().split()[0])
                        ele_name = Element.from_Z(z_number).name
                        if len(pot_dict) == 0:
                            pot_dict[0] = ele_name
                        elif len(pot_dict) > 0:
                            pot_dict[max(pot_dict.keys()) + 1] = ele_name
                        begin += 1
                        continue
                    if begin == 2:
                        z_number = int(line.strip().split()[0])
                        ele_name = Element.from_Z(z_number).name
                        dicts[0][ele_name] = dos_index
                        dos_index += 1
                        if len(pot_dict) == 0:
                            pot_dict[0] = ele_name
                        elif len(pot_dict) > 0:
                            pot_dict[max(pot_dict.keys()) + 1] = ele_name
                    if len(pot_readstart.findall(line)) > 0:
                        begin = 1
        else:
            pot_string = Potential.pot_string_from_file(feff_inp_file)
            dicts = Potential.pot_dict_from_string(pot_string)
            pot_dict = dicts[1]

        for i in range(0, len(dicts[0]) + 1):
            if len(str(i)) == 1:
                with zopen("{}0{}.dat".format(ldos_file, i), "rt") \
                        as fobject:
                    f = fobject.readlines()
                    s = float(f[3].split()[2])
                    p = float(f[4].split()[2])
                    d = float(f[5].split()[2])
                    f1 = float(f[6].split()[2])
                    tot = float(f[1].split()[4])
                    cht[str(i)] = {pot_dict[i]: {'s': s, 'p': p, 'd': d,
                                                 'f': f1,
                                                 'tot': tot}}
            else:
                with zopen(ldos_file + str(i) + ".dat", "rt") as fid:
                    f = fid.readlines()
                    s = float(f[3].split()[2])
                    p = float(f[4].split()[2])
                    d = float(f[5].split()[2])
                    f1 = float(f[6].split()[2])
                    tot = float(f[1].split()[4])
                    cht[str(i)] = {pot_dict[i]: {'s': s, 'p': p, 'd': d,
                                                 'f': f1,
                                                 'tot': tot}}

        return cht


Instruction:
How would you implement a function in Python 3 that
returns shrage transfer as string

Response:
def charge_transfer_to_string(self):
        """returns shrage transfer as string"""
        ch = self.charge_transfer
        chts = ['\nCharge Transfer\n\nabsorbing atom']
        for i in range(len(ch)):
            for atom, v2 in ch[str(i)].items():
                a = ['\n', atom, '\n', 's   ', str(v2['s']), '\n',
                     'p   ', str(v2['p']), '\n',
                     'd   ', str(v2['d']), '\n',
                     'f   ', str(v2['f']), '\n',
                     'tot ', str(v2['tot']), '\n']
                chts.extend(a)
        return ''.join(chts)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def from_file(xmu_dat_file="xmu.dat", feff_inp_file="feff.inp"):
        data = np.loadtxt(xmu_dat_file)
        header = Header.from_file(feff_inp_file)
        parameters = Tags.from_file(feff_inp_file)
        pots = Potential.pot_string_from_file(feff_inp_file)
        # site index (Note: in feff it starts from 1)
        if "RECIPROCAL" in parameters:
            absorbing_atom = parameters["TARGET"]
        # species symbol
        else:
            absorbing_atom = pots.splitlines()[3].split()[2]
        return Xmu(header, parameters, absorbing_atom, data)

Response: Get Xmu object from file.


Instruction:
Write a Python 3 function that can
return chemical formula of material from feff. inp file

Response:
def material_formula(self):
        """
        Returns chemical formula of material from feff.inp file
        """
        try:
            form = self.header.formula
        except IndexError:
            form = 'No formula provided'
        return "".join(map(str, form))


Instruction:
Write a Python 3 script for
returning dict representation of Xmu object

Response:
def as_dict(self):
        """
        Returns dict representations of Xmu object
        """
        d = MSONable.as_dict(self)
        d["data"] = self.data.tolist()
        return d


Instruction:
Given the following Python 3 function, write the documentation
def iterlines(s):
    prevnl = -1
    while True:
        nextnl = s.find('\n', prevnl + 1)
        if nextnl < 0:
            yield s[(prevnl+1):]
            break
        else:
            yield s[(prevnl+1):nextnl]
            prevnl = nextnl

Response: A generator form of s split for reducing memory overhead.


Instruction:
Can you create a Python 3 function that
returns the option string.

Response:
def _options_string(self):
        """
        Return the option string.
        """
        if len(self.options) > 0:
            s = ""
            for op in self.options:
                if self._sized_op:
                    s += "{:s}={:s} ".format(*map(str, op))
                else:
                    s += "{:s} ".format(str(op))
            return s.strip()
        else:
            return ""


Instruction:
Can you create a Python 3 function that
returns True if this AdfKey contains the given subkey.

Response:
def has_subkey(self, subkey):
        """
        Return True if this AdfKey contains the given subkey.

        Parameters
        ----------
        subkey : str or AdfKey
            A key name or an AdfKey object.

        Returns
        -------
        has : bool
            True if this key contains the given key. Otherwise False.

        """
        if isinstance(subkey, str):
            key = subkey
        elif isinstance(subkey, AdfKey):
            key = subkey.key
        else:
            raise ValueError("The subkey should be an AdfKey or a string!")
        if len(self.subkeys) > 0:
            if key in map(lambda k: k.key, self.subkeys):
                return True
        return False


Instruction:
Write a Python 3 script to
add a new subkey to this key.

Response:
def add_subkey(self, subkey):
        """
        Add a new subkey to this key.

        Parameters
        ----------
        subkey : AdfKey
            A new subkey.

        Notes
        -----
        Duplicate check will not be performed if this is an 'Atoms' block.

        """
        if self.key.lower() == 'atoms' or not self.has_subkey(subkey):
            self.subkeys.append(subkey)


Instruction:
Here you have a function in Python 3, explain what it does
def remove_subkey(self, subkey):
        if len(self.subkeys) > 0:
            key = subkey if isinstance(subkey, str) else subkey.key
            for i in range(len(self.subkeys)):
                if self.subkeys[i].key == key:
                    self.subkeys.pop(i)
                    break

Response: Removes the given subkey from this AdfKey.


Instruction:
Write a Python 3 script to
add a new option to this key.

Response:
def add_option(self, option):
        """
        Add a new option to this key.

        Parameters
        ----------
        option : Sized or str or int or float
            A new option to add. This must have the same format with exsiting
            options.

        Raises
        ------
        TypeError
            If the format of the given ``option`` is different.

        """
        if len(self.options) == 0:
            self.options.append(option)
        else:
            sized_op = isinstance(option, (list, tuple))
            if self._sized_op != sized_op:
                raise TypeError("Option type is mismatched!")
            self.options.append(option)


Instruction:
Write a Python 3 function that can
remove an option from the log.

Response:
def remove_option(self, option):
        """
        Remove an option.

        Parameters
        ----------
        option : str or int
            The name (str) or index (int) of the option to remove.

        Raises
        ------
        TypeError
            If the option has a wrong type.

        """
        if len(self.options) > 0:
            if self._sized_op:
                if not isinstance(option, str):
                    raise TypeError("``option`` should be a name string!")
                for i in range(len(self.options)):
                    if self.options[i][0] == option:
                        self.options.pop(i)
                        break
            else:
                if not isinstance(option, int):
                    raise TypeError("``option`` should be an integer index!")
                self.options.pop(option)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def has_option(self, option):
        if len(self.options) == 0:
            return False
        for op in self.options:
            if (self._sized_op and op[0] == option) or (op == option):
                return True
        return False

Response: Returns True if the option is included in this key.


Instruction:
Given the following Python 3 function, write the documentation
def as_dict(self):
        d = {"@module": self.__class__.__module__,
             "@class": self.__class__.__name__,
             "name": self.name, "options": self.options}
        if len(self.subkeys) > 0:
            subkeys = []
            for subkey in self.subkeys:
                subkeys.append(subkey.as_dict())
            d.update({"subkeys": subkeys})
        return d

Response: Returns a JSON serializable dict representation of this object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def from_dict(cls, d):
        key = d.get("name")
        options = d.get("options", None)
        subkey_list = d.get("subkeys", [])
        if len(subkey_list) > 0:
            subkeys = list(map(lambda k: AdfKey.from_dict(k), subkey_list))
        else:
            subkeys = None
        return cls(key, options, subkeys)

Response: Constructs an AdfKey object from the JSON dict d.


Instruction:
How would you explain what the following Python 3 function does
def from_string(string):
        def is_float(s):
            if '.' in s or 'E' in s or 'e' in s:
                return True
            else:
                return False

        if string.find("\n") == -1:
            el = string.split()
            if len(el) > 1:
                if string.find("=") != -1:
                    options = list(map(lambda s: s.split("="), el[1:]))
                else:
                    options = el[1:]
                for i, op in enumerate(options):
                    if isinstance(op, list) and is_numeric(op[1]):
                        op[1] = float(op[1]) if is_float(op[1]) else int(op[1])
                    elif is_numeric(op):
                        options[i] = float(op) if is_float(op) else int(op)
            else:
                options = None
            return AdfKey(el[0], options)

        if string.find('subend') != -1:
            raise ValueError("Nested subkeys are not supported!")

        key = None
        for line in iterlines(string):
            if line == "":
                continue
            el = line.strip().split()
            if len(el) == 0:
                continue
            if el[0].upper() in AdfKey.block_keys:
                if key is None:
                    key = AdfKey.from_string(line)
                else:
                    return key
            elif el[0].upper() == 'END':
                return key
            elif key is not None:
                key.add_subkey(AdfKey.from_string(line))
        else:
            raise Exception("IncompleteKey: 'END' is missing!")

Response: Construct an AdfKey object from the string.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _setup_task(self, geo_subkeys):
        self.geo = AdfKey("Geometry", subkeys=geo_subkeys)
        if self.operation.lower() == "energy":
            self.geo.add_option("SinglePoint")
            if self.geo.has_subkey("Frequencies"):
                self.geo.remove_subkey("Frequencies")
        elif self.operation.lower() == "optimize":
            self.geo.add_option("GeometryOptimization")
            if self.geo.has_subkey("Frequencies"):
                self.geo.remove_subkey("Frequencies")
        elif self.operation.lower() == "numerical_frequencies":
            self.geo.add_subkey(AdfKey("Frequencies"))
        else:
            self.other_directives.append(AdfKey("AnalyticalFreq"))
            if self.geo.has_subkey("Frequencies"):
                self.geo.remove_subkey("Frequencies")

Response: Setup the ADF task for the current ADF.


Instruction:
How would you implement a function in Python 3 that
constructs an AdfTask object from the given dictionary.

Response:
def from_dict(cls, d):
        """
        Construct a MSONable AdfTask object from the JSON dict.

        Parameters
        ----------
        d : dict
            A dict of saved attributes.

        Returns
        -------
        task : AdfTask
            An AdfTask object recovered from the JSON dict ``d``.

        """
        def _from_dict(_d):
            return AdfKey.from_dict(_d) if _d is not None else None

        operation = d.get("operation")
        title = d.get("title")
        basis_set = _from_dict(d.get("basis_set"))
        xc = _from_dict(d.get("xc"))
        units = _from_dict(d.get("units"))
        scf = _from_dict(d.get("scf"))
        others = [AdfKey.from_dict(o) for o in d.get("others", [])]
        geo = _from_dict(d.get("geo"))

        return cls(operation, basis_set, xc, title, units, geo.subkeys, scf,
                   others)


Instruction:
Implement a function in Python 3 to
write an ADF input file.

Response:
def write_file(self, molecule, inpfile):
        """
        Write an ADF input file.

        Parameters
        ----------
        molecule : Molecule
            The molecule for this task.
        inpfile : str
            The name where the input file will be saved.

        """

        mol_blocks = []
        atom_block = AdfKey("Atoms", options=["cartesian"])
        for site in molecule:
            atom_block.add_subkey(AdfKey(str(site.specie), list(site.coords)))
        mol_blocks.append(atom_block)

        if molecule.charge != 0:
            netq = molecule.charge
            ab = molecule.spin_multiplicity - 1
            charge_block = AdfKey("Charge", [netq, ab])
            mol_blocks.append(charge_block)
            if ab != 0:
                unres_block = AdfKey("Unrestricted")
                mol_blocks.append(unres_block)

        with open(inpfile, "w+") as f:
            for block in mol_blocks:
                f.write(str(block) + "\n")
            f.write(str(self.task) + "\n")
            f.write("END INPUT")


Instruction:
Make a summary of the following Python 3 code
def _parse(self):
        workdir = os.path.dirname(self.filename)
        logfile = os.path.join(workdir, "logfile")
        if not os.path.isfile(logfile):
            raise IOError("The ADF logfile can not be accessed!")

        self.is_failed = False
        self.error = None
        self.final_energy = None
        self.final_structure = None
        self.energies = []
        self.structures = []
        self.frequencies = []
        self.normal_modes = None
        self.freq_type = None
        self.run_type = None
        self.is_internal_crash = False

        self._parse_logfile(logfile)
        if not self.is_failed and self.run_type != "SinglePoint":
            self._parse_adf_output()

Response: Parse the ADF output file.


Instruction:
Write a Python 3 script to
parse the formatted logfile and return a list of the TAPE13 objects.

Response:
def _parse_logfile(self, logfile):
        """
        Parse the formatted logfile.
        """

        cycle_patt = re.compile(r"Coordinates\sin\sGeometry\sCycle\s(\d+)")
        coord_patt = re.compile(r"\s+([0-9]+)\.([A-Za-z]+)"+3*r"\s+([-\.0-9]+)")
        energy_patt = re.compile(r"<.*>\s<.*>\s+current\senergy\s+([-\.0-9]+)\s"
                                 "Hartree")
        final_energy_patt = re.compile(
            r"<.*>\s<.*>\s+Bond\sEnergy\s+([-\.0-9]+)\sa\.u\.")
        error_patt = re.compile(r"<.*>\s<.*>\s+ERROR\sDETECTED:\s(.*)")
        runtype_patt = re.compile(r"<.*>\s<.*>\s+RunType\s+:\s(.*)")
        end_patt = re.compile(r"<.*>\s<.*>\s+END")
        parse_cycle = False
        sites = []
        last_cycle = -1
        parse_final = False

        # Stop parsing the logfile is this job is not terminated successfully.
        # The last non-empty line of the logfile must match the end pattern.
        # Otherwise the job has some internal failure. The TAPE13 part of the
        # ADF manual has a detailed explanantion.
        with open(logfile, "r") as f:
            for line in reverse_readline(f):
                if line == "":
                    continue
                if end_patt.search(line) is None:
                    self.is_internal_crash = True
                    self.error = "Internal crash. TAPE13 is generated!"
                    self.is_failed = True
                    return
                else:
                    break

        with open(logfile, "r") as f:
            for line in f:
                m = error_patt.search(line)
                if m:
                    self.is_failed = True
                    self.error = m.group(1)
                    break

                if self.run_type is None:
                    m = runtype_patt.search(line)
                    if m:
                        if m.group(1) == 'FREQUENCIES':
                            self.freq_type = "Numerical"
                            self.run_type = "NumericalFreq"
                        elif m.group(1) == 'GEOMETRY OPTIMIZATION':
                            self.run_type = "GeometryOptimization"
                        elif m.group(1) == 'CREATE':
                            self.run_type = None
                        elif m.group(1) == 'SINGLE POINT':
                            self.run_type = 'SinglePoint'
                        else:
                            raise AdfOutputError("Undefined Runtype!")

                elif self.run_type == 'SinglePoint':
                    m = coord_patt.search(line)
                    if m:
                        sites.append([m.groups()[0],
                                      list(map(float, m.groups()[2:]))])
                    else:
                        m = final_energy_patt.search(line)
                        if m:
                            self.final_energy = float(m.group(1))
                            self.final_structure = self._sites_to_mol(sites)

                elif self.run_type == 'GeometryOptimization':
                    m = cycle_patt.search(line)
                    if m:
                        cycle = int(m.group(1))
                        if cycle <= 0:
                            raise AdfOutputError("Wrong cycle {}".format(cycle))
                        if cycle > last_cycle:
                            parse_cycle = True
                            last_cycle = cycle
                        else:
                            parse_final = True
                    elif parse_cycle:
                        m = coord_patt.search(line)
                        if m:
                            sites.append([m.groups()[1],
                                          list(map(float, m.groups()[2:]))])
                        else:
                            m = energy_patt.search(line)
                            if m:
                                self.energies.append(float(m.group(1)))
                                mol = self._sites_to_mol(sites)
                                self.structures.append(mol)
                                parse_cycle = False
                                sites = []
                    elif parse_final:
                        m = final_energy_patt.search(line)
                        if m:
                            self.final_energy = float(m.group(1))

                elif self.run_type == "NumericalFreq":
                    break

        if not self.is_failed:
            if self.run_type == "GeometryOptimization":
                if len(self.structures) > 0:
                    self.final_structure = self.structures[-1]
                if self.final_energy is None:
                    raise AdfOutputError("The final energy can not be read!")
            elif self.run_type == "SinglePoint":
                if self.final_structure is None:
                    raise AdfOutputError("The final structure is missing!")
                if self.final_energy is None:
                    raise AdfOutputError("The final energy can not be read!")


Instruction:
How would you implement a function in Python 3 that
parses the ADF output file.

Response:
def _parse_adf_output(self):
        """
        Parse the standard ADF output file.
        """
        numerical_freq_patt = re.compile(
            r"\s+\*\s+F\sR\sE\sQ\sU\sE\sN\sC\sI\sE\sS\s+\*")
        analytic_freq_patt = re.compile(
            r"\s+\*\s+F\sR\sE\sQ\sU\sE\sN\sC\sY\s+A\sN\sA\sL\sY\sS\sI\sS\s+\*")
        freq_on_patt = re.compile(r"Vibrations\sand\sNormal\sModes\s+\*+.*\*+")
        freq_off_patt = re.compile(r"List\sof\sAll\sFrequencies:")
        mode_patt = re.compile(r"\s+(\d+)\.([A-Za-z]+)\s+(.*)")
        coord_patt = re.compile(r"\s+(\d+)\s+([A-Za-z]+)" + 6 * r"\s+([0-9\.-]+)")
        coord_on_patt = re.compile(r"\s+\*\s+R\sU\sN\s+T\sY\sP\sE\s:\sFREQUENCIES\s+\*")
        parse_freq = False
        parse_mode = False
        nnext = 0
        nstrike = 0
        sites = []

        self.frequencies = []
        self.normal_modes = []

        if self.final_structure is None:
            find_structure = True
            parse_coord = False
            natoms = 0
        else:
            find_structure = False
            parse_coord = False
            natoms = self.final_structure.num_sites

        with open(self.filename, "r") as f:
            for line in f:
                if self.run_type == "NumericalFreq" and find_structure:
                    if not parse_coord:
                        m = coord_on_patt.search(line)
                        if m:
                            parse_coord = True
                    else:
                        m = coord_patt.search(line)
                        if m:
                            sites.append(
                                [m.group(2), list(map(float, m.groups()[2:5]))])
                            nstrike += 1
                        elif nstrike > 0:
                            find_structure = False
                            self.final_structure = self._sites_to_mol(sites)
                            natoms = self.final_structure.num_sites

                elif self.freq_type is None:
                    if numerical_freq_patt.search(line):
                        self.freq_type = "Numerical"
                    elif analytic_freq_patt.search(line):
                        self.freq_type = "Analytical"
                        self.run_type = "AnalyticalFreq"

                elif freq_on_patt.search(line):
                    parse_freq = True

                elif parse_freq:
                    if freq_off_patt.search(line):
                        break
                    el = line.strip().split()
                    if 1 <= len(el) <= 3 and line.find(".") != -1:
                        nnext = len(el)
                        parse_mode = True
                        parse_freq = False
                        self.frequencies.extend(map(float, el))
                        for i in range(nnext):
                            self.normal_modes.append([])

                elif parse_mode:
                    m = mode_patt.search(line)
                    if m:
                        v = list(chunks(map(float, m.group(3).split()), 3))
                        if len(v) != nnext:
                            raise AdfOutputError("Odd Error!")
                        for i, k in enumerate(range(-nnext, 0, 1)):
                            self.normal_modes[k].extend(v[i])
                        if int(m.group(1)) == natoms:
                            parse_freq = True
                            parse_mode = False
        if isinstance(self.final_structure, list):
            self.final_structure = self._sites_to_mol(self.final_structure)

        if self.freq_type is not None:
            if len(self.frequencies) != len(self.normal_modes):
                raise AdfOutputError("The number of normal modes is wrong!")
            if len(self.normal_modes[0]) != natoms * 3:
                raise AdfOutputError("The dimensions of the modes are wrong!")


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_reconstructed_band_structure(list_bs, efermi=None):
    if efermi is None:
        efermi = sum([b.efermi for b in list_bs]) / len(list_bs)

    kpoints = []
    labels_dict = {}
    rec_lattice = list_bs[0].lattice_rec
    nb_bands = min([list_bs[i].nb_bands for i in range(len(list_bs))])

    kpoints = np.concatenate([[k.frac_coords for k in bs.kpoints]
                              for bs in list_bs])
    dicts = [bs.labels_dict for bs in list_bs]
    labels_dict = {k: v.frac_coords for d in dicts for k, v in d.items()}

    eigenvals = {}
    eigenvals[Spin.up] = np.concatenate([bs.bands[Spin.up][:nb_bands]
                                         for bs in list_bs], axis=1)

    if list_bs[0].is_spin_polarized:
        eigenvals[Spin.down] = np.concatenate([bs.bands[Spin.down][:nb_bands]
                                               for bs in list_bs], axis=1)

    projections = {}
    if len(list_bs[0].projections) != 0:
        projs = [bs.projections[Spin.up][:nb_bands] for bs in list_bs]
        projections[Spin.up] = np.concatenate(projs, axis=1)

        if list_bs[0].is_spin_polarized:
            projs = [bs.projections[Spin.down][:nb_bands] for bs in list_bs]
            projections[Spin.down] = np.concatenate(projs, axis=1)

    if isinstance(list_bs[0], BandStructureSymmLine):
        return BandStructureSymmLine(kpoints, eigenvals, rec_lattice,
                                     efermi, labels_dict,
                                     structure=list_bs[0].structure,
                                     projections=projections)
    else:
        return BandStructure(kpoints, eigenvals, rec_lattice, efermi,
                             labels_dict, structure=list_bs[0].structure,
                             projections=projections)

Response: This method takes a list of BandStructureSymmLine objects and reconstructs the corresponding BandStructureSymmLine object from all of them.


Instruction:
Given the following Python 3 function, write the documentation
def get_projection_on_elements(self):
        result = {}
        structure = self.structure
        for spin, v in self.projections.items():
            result[spin] = [[collections.defaultdict(float)
                             for i in range(len(self.kpoints))]
                            for j in range(self.nb_bands)]
            for i, j, k in itertools.product(range(self.nb_bands),
                                             range(len(self.kpoints)),
                                             range(structure.num_sites)):
                result[spin][i][j][str(structure[k].specie)] += np.sum(
                    v[i, j, :, k])
        return result

Response: Method returning a dictionary of projections on elements.


Instruction:
Here you have a function in Python 3, explain what it does
def get_projections_on_elements_and_orbitals(self, el_orb_spec):
        result = {}
        structure = self.structure
        el_orb_spec = {get_el_sp(el): orbs for el, orbs in el_orb_spec.items()}
        for spin, v in self.projections.items():
            result[spin] = [[{str(e): collections.defaultdict(float)
                              for e in el_orb_spec}
                             for i in range(len(self.kpoints))]
                            for j in range(self.nb_bands)]

            for i, j, k in itertools.product(
                    range(self.nb_bands), range(len(self.kpoints)),
                    range(structure.num_sites)):
                sp = structure[k].specie
                for orb_i in range(len(v[i][j])):
                    o = Orbital(orb_i).name[0]
                    if sp in el_orb_spec:
                        if o in el_orb_spec[sp]:
                            result[spin][i][j][str(sp)][o] += v[i][j][
                                orb_i][k]
        return result

Response: Method returns a dictionary of projections on elements and orbitals for which we want to have projections on.


Instruction:
Can you tell what is the following Python 3 function doing
def is_metal(self, efermi_tol=1e-4):
        for spin, values in self.bands.items():
            for i in range(self.nb_bands):
                if np.any(values[i, :] - self.efermi < -efermi_tol) and \
                        np.any(values[i, :] - self.efermi > efermi_tol):
                    return True
        return False

Response: Check if the band structure indicates a metal