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) 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!")
def chunks(self, chunk_size): """Yield successive chunks of tasks of lenght chunk_size.""" for tasks in chunks(self, chunk_size): yield tasks
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!")