This file is indexed.

/usr/share/psi/python/qcdb/libmintsbasissetparser.py is in psi4-data 1:0.3-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import os
import re
from exceptions import *
from libmintsgshell import *


class Gaussian94BasisSetParser(object):
    """Class for parsing basis sets from a text file in Gaussian 94
    format. Translated directly from the Psi4 libmints class written
    by Justin M. Turney and Andrew C. Simmonett.

    """

    def __init__(self, forced_puream=None):
        """Constructor"""
        # If the parser needs to force spherical or cartesian (e.g., loading old guess)
        self.force_puream_or_cartesian = False if forced_puream is None else True
        # Is the forced value to use puream?  (Otherwise force Cartesian).
        self.forced_is_puream = False if forced_puream is None else forced_puream
        # string filename
        self.filename = None

    def load_file(self, filename, basisname=None):
        """Load and return the file to be used by parse.  Return only
        portion of *filename* pertaining to *basisname* if specified (for
        multi-basisset files) otherwise entire file as list of strings.

        """
        # string filename
        self.filename = filename

        given_basisname = False if basisname is None else True
        found_basisname = False
        basis_separator = re.compile(r'^\s*\[\s*(.*?)\s*\]\s*$')

        # Loads an entire file.
        try:
            infile = open(filename, 'r')
        except IOError:
            raise BasisSetFileNotFound("""BasisSetParser::parse: Unable to open basis set file: %s""" % (filename))
        if os.stat(filename).st_size == 0:
            raise ValidationError("""BasisSetParser::parse: given filename '%s' is blank.""" % (filename))
        contents = infile.readlines()

        lines = []
        for text in contents:
            text = text.strip()
            # If no basisname was given always save the line.
            if given_basisname is False:
                lines.append(text)

            if found_basisname:
                # If we find another [*] we're done.
                if basis_separator.match(text):
                    what = basis_separator.match(text).group(1)
                    break
                lines.append(text)
                continue

            # If the user gave a basisname AND text matches the basisname we want to trigger to retain
            if given_basisname and basis_separator.match(text):
                if basisname == basis_separator.match(text).group(1):
                    found_basisname = True

        return lines

    def parse(self, symbol, dataset):
        """Given a string, parse for the basis set needed for atom.
        * @param symbol atom symbol to look for in dataset
        * @param dataset data set to look through
        dataset can be list of lines or a single string which will be converted to list of lines

        """
        if isinstance(dataset, basestring):
            lines = dataset.split('\n')
        else:
            lines = dataset

        # Regular expressions that we'll be checking for.
        cartesian = re.compile(r'^\s*cartesian\s*', re.IGNORECASE)
        spherical = re.compile(r'^\s*spherical\s*', re.IGNORECASE)
        comment = re.compile(r'^\s*\!.*')  # line starts with !
        separator = re.compile(r'^\s*\*\*\*\*')  # line starts with ****
        ATOM = '(([A-Z]{1,3}\d*)|([A-Z]{1,3}_\w+))'  # match 'C 0', 'Al c 0', 'P p88 p_pass 0' not 'Ofail 0', 'h99_text 0'
        atom_array = re.compile(r'^\s*((' + ATOM + '\s+)+)0\s*$', re.IGNORECASE)  # array of atomic symbols terminated by 0
        shell = re.compile(r'^\s*(\w+)\s*(\d+)\s*(-?\d+\.\d+)')  # Match beginning of contraction
        blank = re.compile(r'^\s*$')
        NUMBER = "((?:[-+]?\\d*\\.\\d+(?:[DdEe][-+]?\\d+)?)|(?:[-+]?\\d+\\.\\d*(?:[DdEe][-+]?\\d+)?))"
        primitives1 = re.compile(r'^\s*' + NUMBER + '\s+' + NUMBER + '.*')  # Match s, p, d, f, g, ... functions
        primitives2 = re.compile(r'^\s*' + NUMBER + '\s+' + NUMBER + '\s+' + NUMBER + '.*')  # match sp functions

        # s, p and s, p, d can be grouped together in Pople-style basis sets
        sp = 'SP'
        spd = 'SPD'

        #                a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
        #shell_to_am = [-1,-1,-1, 2,-1, 3, 4, 5, 6,-1, 7, 8, 9,10,11, 1,12,13, 0,14,15,16,17,18,19,20]
        alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
        angmo = [-1, -1, -1, 2, -1, 3, 4, 5, 6, -1, 7, 8,
            9, 10, 11, 1, 12, 13, 0, 14, 15, 16, 17, 18, 19, 20]
        shell_to_am = dict(zip(alpha, angmo))

        # Basis type.
        gaussian_type = 'Pure'

        if self.force_puream_or_cartesian:
            if self.forced_is_puream == False:
                gaussian_type = 'Cartesian'

        # Need a dummy center for the shell.
        center = [0.0, 0.0, 0.0]

        shell_list = []
        lineno = 0
        found = False

        while lineno < len(lines):
            line = lines[lineno]
            lineno += 1

            # Ignore blank lines
            if blank.match(line):
                continue

            # Look for Cartesian or Spherical
            if not self.force_puream_or_cartesian:
                if cartesian.match(line):
                    gaussian_type = 'Cartesian'
#TODO                    if psi4.get_global_option('PUREAM').has_changed():
#TODO                        gaussian_type = 'Pure' if int(psi4.get_global('PUREAM')) else 'Cartesian'
                    continue
                elif spherical.match(line):
                    gaussian_type = 'Pure'
#TODO                    if psi4.get_global_option('PUREAM').has_changed():
#TODO                        gaussian_type = 'Pure' if int(psi4.get_global('PUREAM')) else 'Cartesian'
                    continue
                #end case where puream setting wasn't forced by caller

            # Do some matches
            if comment.match(line):
                continue
            if separator.match(line):
                continue

            # Match: H    0
            # or:    H    O...     0
            if atom_array.match(line):
                what = atom_array.match(line).group(1).split()
                # Check the captures and see if this basis set is for the atom we need.
                found = False
                if symbol in [x.upper() for x in what]:
                    found = True
                    msg = """line %5d""" % (lineno)

                    # Read in the next line
                    line = lines[lineno]
                    lineno += 1

                    # Need to do the following until we match a "****" which is the end of the basis set
                    while not separator.match(line):
                        # Match shell information
                        if shell.match(line):
                            what = shell.match(line)
                            shell_type = str(what.group(1)).upper()
                            nprimitive = int(what.group(2))
                            scale = float(what.group(3))

                            if len(shell_type) == 1:
                                am = shell_to_am[shell_type[0]]

                                exponents = [0.0] * nprimitive
                                contractions = [0.0] * nprimitive

                                for p in range(nprimitive):
                                    line = lines[lineno]
                                    lineno += 1
                                    line = line.replace('D', 'e', 2)
                                    line = line.replace('d', 'e', 2)

                                    what = primitives1.match(line)
                                    # Must match primitives1; will work on the others later
                                    if not what:
                                        raise ValidationError("""Gaussian94BasisSetParser::parse: Unable to match an exponent with one contraction: line %d: %s""" % (lineno, line))
                                    exponent = float(what.group(1))
                                    contraction = float(what.group(2))

                                    # Scale the contraction and save the information
                                    contraction *= scale
                                    exponents[p] = exponent
                                    contractions[p] = contraction

                                # We have a full shell, push it to the basis set
                                shell_list.append(ShellInfo(am, contractions, exponents,
                                    gaussian_type, 0, center, 0, 'Unnormalized'))

                            elif len(shell_type) == 2:
                                # This is to handle instances of SP, PD, DF, FG, ...
                                am1 = shell_to_am[shell_type[0]]
                                am2 = shell_to_am[shell_type[1]]

                                exponents = [0.0] * nprimitive
                                contractions1 = [0.0] * nprimitive
                                contractions2 = [0.0] * nprimitive

                                for p in range(nprimitive):
                                    line = lines[lineno]
                                    lineno += 1
                                    line = line.replace('D', 'e', 2)
                                    line = line.replace('d', 'e', 2)

                                    what = primitives2.match(line)
                                    # Must match primitivies2
                                    if not what:
                                        raise ValidationError("Gaussian94BasisSetParser::parse: Unable to match an exponent with two contractions: line %d: %s" % (lineno, line))
                                    exponent = float(what.group(1))
                                    contraction = float(what.group(2))

                                    # Scale the contraction and save the information
                                    contraction *= scale
                                    exponents[p] = exponent
                                    contractions1[p] = contraction

                                    # Do the other contraction
                                    contraction = float(what.group(3))

                                    # Scale the contraction and save the information
                                    contraction *= scale
                                    contractions2[p] = contraction

                                shell_list.append(ShellInfo(am1, contractions1, exponents,
                                    gaussian_type, 0, center, 0, 'Unnormalized'))
                                shell_list.append(ShellInfo(am2, contractions2, exponents,
                                    gaussian_type, 0, center, 0, 'Unnormalized'))
                            else:
                                raise ValidationError("""Gaussian94BasisSetParser::parse: Unable to parse basis sets with spd, or higher grouping""")
                        else:
                            raise ValidationError("""Gaussian94BasisSetParser::parse: Expected shell information, but got: line %d: %s""" % (lineno, line))
                        line = lines[lineno]
                        lineno += 1

                    break

        if not found:
            #raise BasisSetNotFound("Gaussian94BasisSetParser::parser: Unable to find the basis set for %s in %s" % \
            #   (symbol, self.filename), silent=True)
            return None, None

        return shell_list, msg