Hide keyboard shortcuts

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. 

7 

8"""Population analyses based on cclib data.""" 

9 

10import logging 

11 

12import numpy 

13 

14from cclib.method.calculationmethod import Method, MissingAttributeError 

15 

16 

17class Population(Method): 

18 """An abstract base class for population-type methods.""" 

19 

20 # All of these are typically required for population analyses. 

21 required_attrs = ('homos', 'mocoeffs', 'nbasis') 

22 

23 # At least one of these are typically required. 

24 overlap_attributes = ('aooverlaps', 'fooverlaps') 

25 

26 def __init__(self, data, progress=None, \ 

27 loglevel=logging.INFO, logname="Log"): 

28 super(Population, self).__init__(data, progress, loglevel, logname) 

29 

30 self.fragresults = None 

31 

32 def __str__(self): 

33 """Return a string representation of the object.""" 

34 return "Population" 

35 

36 def __repr__(self): 

37 """Return a representation of the object.""" 

38 return "Population" 

39 

40 def _check_required_attributes(self): 

41 super(Population, self)._check_required_attributes() 

42 

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') 

46 

47 def partition(self, indices=None): 

48 

49 if not hasattr(self, "aoresults"): 

50 self.calculate() 

51 

52 if not indices: 

53 

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 

59 

60 atoms = [] 

61 indices = [] 

62 

63 name = names[0].split('_')[0] 

64 atoms.append(name) 

65 indices.append([0]) 

66 

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) 

76 

77 natoms = len(indices) 

78 nmocoeffs = len(self.aoresults[0]) 

79 

80 # Build results numpy array[3]. 

81 alpha = len(self.aoresults[0]) 

82 results = [] 

83 results.append(numpy.zeros([alpha, natoms], "d")) 

84 

85 if len(self.aoresults) == 2: 

86 beta = len(self.aoresults[1]) 

87 results.append(numpy.zeros([beta, natoms], "d")) 

88 

89 # For each spin, splice numpy array at ao index, 

90 # and add to correct result row. 

91 for spin in range(len(results)): 

92 

93 for i in range(natoms): # Number of groups. 

94 

95 for j in range(len(indices[i])): # For each group. 

96 

97 temp = self.aoresults[spin][:, indices[i][j]] 

98 results[spin][:, i] = numpy.add(results[spin][:, i], temp) 

99 

100 self.logger.info("Saving partitioned results in fragresults: [array[2]]") 

101 self.fragresults = results 

102 

103 return True