Coverage for cclib/method/population.py : 91%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2018, the cclib development team
4#
5# This file is part of cclib (http://cclib.github.io) and is distributed under
6# the terms of the BSD 3-Clause License.
8"""Population analyses based on cclib data."""
10import logging
12import numpy
14from cclib.method.calculationmethod import Method, MissingAttributeError
17class Population(Method):
18 """An abstract base class for population-type methods."""
20 # All of these are typically required for population analyses.
21 required_attrs = ('homos', 'mocoeffs', 'nbasis')
23 # At least one of these are typically required.
24 overlap_attributes = ('aooverlaps', 'fooverlaps')
26 def __init__(self, data, progress=None, \
27 loglevel=logging.INFO, logname="Log"):
28 super(Population, self).__init__(data, progress, loglevel, logname)
30 self.fragresults = None
32 def __str__(self):
33 """Return a string representation of the object."""
34 return "Population"
36 def __repr__(self):
37 """Return a representation of the object."""
38 return "Population"
40 def _check_required_attributes(self):
41 super(Population, self)._check_required_attributes()
43 if self.overlap_attributes and not any(hasattr(self.data, a) for a in self.overlap_attributes):
44 raise MissingAttributeError(
45 'Need overlap matrix (aooverlaps or fooverlaps attribute) for Population methods')
47 def partition(self, indices=None):
49 if not hasattr(self, "aoresults"):
50 self.calculate()
52 if not indices:
54 # Build list of groups of orbitals in each atom for atomresults.
55 if hasattr(self.data, "aonames"):
56 names = self.data.aonames
57 elif hasattr(self.data, "fonames"):
58 names = self.data.fonames
60 atoms = []
61 indices = []
63 name = names[0].split('_')[0]
64 atoms.append(name)
65 indices.append([0])
67 for i in range(1, len(names)):
68 name = names[i].split('_')[0]
69 try:
70 index = atoms.index(name)
71 except ValueError: #not found in atom list
72 atoms.append(name)
73 indices.append([i])
74 else:
75 indices[index].append(i)
77 natoms = len(indices)
78 nmocoeffs = len(self.aoresults[0])
80 # Build results numpy array[3].
81 alpha = len(self.aoresults[0])
82 results = []
83 results.append(numpy.zeros([alpha, natoms], "d"))
85 if len(self.aoresults) == 2:
86 beta = len(self.aoresults[1])
87 results.append(numpy.zeros([beta, natoms], "d"))
89 # For each spin, splice numpy array at ao index,
90 # and add to correct result row.
91 for spin in range(len(results)):
93 for i in range(natoms): # Number of groups.
95 for j in range(len(indices[i])): # For each group.
97 temp = self.aoresults[spin][:, indices[i][j]]
98 results[spin][:, i] = numpy.add(results[spin][:, i], temp)
100 self.logger.info("Saving partitioned results in fragresults: [array[2]]")
101 self.fragresults = results
103 return True