def run(self, input, output=None):
        if input is None:
            raise AquaChemistryError("Missing input.")

        self._parser = InputParser(input)
        self._parser.parse()
        driver_return = self._run_driver_from_parser(self._parser, False)
        if driver_return[0] == AquaChemistry._DRIVER_RUN_TO_HDF5:
            logger.info('No further process.')
            return {'printable': [driver_return[1]]}

        data = run_algorithm(driver_return[1], driver_return[2], True)
        if not isinstance(data, dict):
            raise AquaChemistryError(
                "Algorithm run result should be a dictionary")

        convert_json_to_dict(data)
        if logger.isEnabledFor(logging.DEBUG):
            logger.debug('Algorithm returned: {}'.format(
                pprint.pformat(data, indent=4)))

        lines, result = self._format_result(data)
        logger.info('Processing complete. Final result available')
        result['printable'] = lines

        if output is not None:
            with open(output, 'w') as f:
                for line in lines:
                    print(line, file=f)

        return result
Example #2
0
    def _run_g16(cfg):

        # Run Gaussian 16. We capture stdout and if error log the last 10 lines that
        # should include the error description from Gaussian
        process = None
        try:
            process = Popen(GAUSSIAN_16, stdin=PIPE, stdout=PIPE, universal_newlines=True)
            stdout, stderr = process.communicate(cfg)
            process.wait()
        except:
            if process is not None:
                process.kill()

            raise AquaChemistryError('{} run has failed'.format(GAUSSIAN_16_DESC))

        if process.returncode != 0:
            errmsg = ""
            if stdout is not None:
                lines = stdout.splitlines()
                start = 0
                if len(lines) > 10:
                    start = len(lines) - 10
                for i in range(start, len(lines)):
                    logger.error(lines[i])
                    errmsg += lines[i]+"\n"
            raise AquaChemistryError('{} process return code {}\n{}'.format(GAUSSIAN_16_DESC, process.returncode, errmsg))
        else:
            if logger.isEnabledFor(logging.DEBUG):
                alltext = ""
                if stdout is not None:
                    lines = stdout.splitlines()
                    for line in lines:
                        alltext += line + "\n"
                logger.debug("Gaussian output:\n{}".format(alltext))
Example #3
0
def _check_molecule_format(val):
    """If it seems to be zmatrix rather than xyz format we convert before returning"""
    atoms = [x.strip() for x in val.split(';')]
    if atoms is None or len(atoms) < 1:
        raise AquaChemistryError('Molecule format error: ' + val)

    # Anx xyz format has 4 parts in each atom, if not then do zmatrix convert
    parts = [x.strip() for x in atoms[0].split(' ')]
    if len(parts) != 4:
        try:
            zmat = []
            for atom in atoms:
                parts = [x.strip() for x in atom.split(' ')]
                z = [parts[0]]
                for i in range(1, len(parts), 2):
                    z.append(int(parts[i]))
                    z.append(float(parts[i + 1]))
                zmat.append(z)
            xyz = z2xyz(zmat)
            new_val = ""
            for i in range(len(xyz)):
                atm = xyz[i]
                if i > 0:
                    new_val += "; "
                new_val += "{} {} {} {}".format(atm[0], atm[1], atm[2], atm[3])
            return new_val
        except Exception as exc:
            raise AquaChemistryError('Failed to convert atom string: ' +
                                     val) from exc

    return val
def register_chemistry_operator(cls):
    """
    Registers a chemistry operator class
    Args:
        cls (object): chemistry operator class.
    Returns:
        name: input name
    Raises:
        AquaChemistryError: if the class is already registered or could not be registered
    """
    _discover_on_demand()

    # Verify that the pluggable is not already registered
    if cls in [input.cls for input in _REGISTERED_CHEMISTRY_OPERATORS.values()]:
        raise AquaChemistryError(
            'Could not register class {} is already registered'.format(cls))

    # Verify that it has a minimal valid configuration.
    try:
        chemistry_operator_name = cls.CONFIGURATION['name']
    except (LookupError, TypeError):
        raise AquaChemistryError(
            'Could not register chemistry operator: invalid configuration')

    if chemistry_operator_name in _REGISTERED_CHEMISTRY_OPERATORS:
        raise AquaChemistryError('Could not register class {}. Name {} {} is already registered'.format(cls,
                                                                                                        chemistry_operator_name, _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].cls))

    # Append the pluggable to the `registered_classes` dict.
    _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name] = RegisteredChemOp(
        chemistry_operator_name, cls, copy.deepcopy(cls.CONFIGURATION))
    return chemistry_operator_name
Example #5
0
    def _run_psi4(input_file, output_file):

        # Run psi4.
        process = None
        try:
            process = subprocess.Popen([PSI4, input_file, output_file],
                                       stdout=subprocess.PIPE,
                                       universal_newlines=True)
            stdout, stderr = process.communicate()
            process.wait()
        except:
            if process is not None:
                process.kill()

            raise AquaChemistryError('{} run has failed'.format(PSI4))

        if process.returncode != 0:
            errmsg = ""
            if stdout is not None:
                lines = stdout.splitlines()
                for i in range(len(lines)):
                    logger.error(lines[i])
                    errmsg += lines[i] + "\n"
            raise AquaChemistryError('{} process return code {}\n{}'.format(
                PSI4, process.returncode, errmsg))
Example #6
0
    def _augment_config(self, fname, cfg):
        cfgaug = ""
        with io.StringIO() as outf:
            with io.StringIO(cfg) as inf:
                # Add our Route line at the end of any existing ones
                line = ""
                added = False
                while not added:
                    line = inf.readline()
                    if not line:
                        break
                    if line.startswith('#'):
                        outf.write(line)
                        while not added:
                            line = inf.readline()
                            if not line:
                                raise AquaChemistryError('Unexpected end of Gaussian input')
                            if len(line.strip()) == 0:
                                outf.write('# Window=Full Int=NoRaff Symm=(NoInt,None) output=(matrix,i4labels,mo2el) tran=full\n')
                                added = True
                            outf.write(line)
                    else:
                        outf.write(line)

                # Now add our filename after the title and molecule but before any additional data. We located
                # the end of the # section by looking for a blank line after the first #. Allows comment lines
                # to be inter-mixed with Route lines if that's ever done. From here we need to see two sections
                # more, the title and molecule so we can add the filename.
                added = False
                section_count = 0
                blank = True
                while not added:
                    line = inf.readline()
                    if not line:
                        raise AquaChemistryError('Unexpected end of Gaussian input')
                    if len(line.strip()) == 0:
                        blank = True
                        if section_count == 2:
                            break
                    else:
                        if blank:
                            section_count += 1
                            blank = False
                    outf.write(line)

                outf.write(line)
                outf.write(fname)
                outf.write('\n\n')

                # Whatever is left in the original config we just append without further inspection
                while True:
                    line = inf.readline()
                    if not line:
                        break
                    outf.write(line)

                cfgaug = outf.getvalue()

        return cfgaug
Example #7
0
def compute_integrals(config):
    # Get config from input parameters
    # Molecule is in this format:
    # atoms=H .0 .0 .0; H .0 .0 0.2
    # units=Angstrom
    # charge=0
    # multiplicity=1
    # where we support symbol for atom as well as number

    if 'atoms' not in config:
        raise AquaChemistryError('Atoms is missing')
    val = config['atoms']
    if val is None:
        raise AquaChemistryError('Atoms value is missing')

    charge = int(config.get('charge', '0'))
    multiplicity = int(config.get('multiplicity', '1'))
    units = __checkUnits(config.get('units', 'Angstrom'))
    mol = __parseMolecule(val, units, charge, multiplicity)
    basis = config.get('basis', 'sto3g')
    calc_type = config.get('calc_type', 'rhf').lower()

    try:
        ehf, enuke, norbs, mohij, mohijkl, orbs, orbs_energy = _calculate_integrals(
            mol, basis, calc_type)
    except Exception as exc:
        raise AquaChemistryError(
            'Failed electronic structure computation') from exc

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    # Energies and orbits
    _q_._hf_energy = ehf
    _q_._nuclear_repulsion_energy = enuke
    _q_._num_orbitals = norbs
    _q_._num_alpha = mol.nup()
    _q_._num_beta = mol.ndown()
    _q_._mo_coeff = orbs
    _q_._orbital_energies = orbs_energy
    # Molecule geometry
    _q_._molecular_charge = mol.charge
    _q_._multiplicity = mol.multiplicity
    _q_._num_atoms = len(mol)
    _q_._atom_symbol = []
    _q_._atom_xyz = np.empty([len(mol), 3])
    atoms = mol.atoms
    for _n in range(0, _q_._num_atoms):
        atuple = atoms[_n].atuple()
        _q_._atom_symbol.append(QMolecule.symbols[atuple[0]])
        _q_._atom_xyz[_n][0] = atuple[1]
        _q_._atom_xyz[_n][1] = atuple[2]
        _q_._atom_xyz[_n][2] = atuple[3]
    # 1 and 2 electron integrals
    _q_._mo_onee_ints = mohij
    _q_._mo_eri_ints = mohijkl

    return _q_
    def export_dictionary(self, file_name):
        if file_name is None:
            raise AquaChemistryError('Missing file path')

        file_name = file_name.strip()
        if len(file_name) == 0:
            raise AquaChemistryError('Missing file path')

        value = json.loads(json.dumps(self.to_dictionary()))
        value = pprint.pformat(value, indent=4)
        with open(file_name, 'w') as f:
            print(value, file=f)
Example #9
0
def _check_molecule_format(val):
    """If it seems to be zmatrix rather than xyz format we convert before returning"""
    atoms = [x.strip() for x in val.split(';')]
    if atoms is None or len(atoms) < 1:
        raise AquaChemistryError('Molecule format error: ' + val)

    # Anx xyz format has 4 parts in each atom, if not then do zmatrix convert
    parts = [x.strip() for x in atoms[0].split(' ')]
    if len(parts) != 4:
        try:
            return gto.mole.from_zmatrix(val)
        except Exception as exc:
            raise AquaChemistryError('Failed to convert atom string: ' + val) from exc

    return val
Example #10
0
    def run(self, section):
        cfg = section['data']
        if cfg is None or not isinstance(cfg,str):
            raise AquaChemistryError("Gaussian user supplied configuration invalid: '{}'".format(cfg))
            
        while not cfg.endswith('\n\n'):
            cfg += '\n'
            
        logger.debug("User supplied configuration raw: '{}'".format(cfg.replace('\r', '\\r').replace('\n', '\\n')))
        logger.debug('User supplied configuration\n{}'.format(cfg))

        # To the Gaussian section of the input file passed here as section['data']
        # add line '# Symm=NoInt output=(matrix,i4labels,mo2el) tran=full'
        # NB: Line above needs to be added in right context, i.e after any lines
        #     beginning with % along with any others that start with #
        # append at end the name of the MatrixElement file to be written

        fd, fname = tempfile.mkstemp(suffix='.mat')
        os.close(fd)

        cfg = self._augment_config(fname, cfg)
        logger.debug('Augmented control information:\n{}'.format(cfg))

        GaussianDriver._run_g16(cfg)

        q_mol = self._parse_matrix_file(fname)
        try:
            os.remove(fname)
        except:
            logger.warning("Failed to remove MatrixElement file " + fname)

        return q_mol
    def run_algorithm_from_json(self, params, output=None, backend=None):
        """
        Runs the Aqua Chemistry experiment from json dictionary

        Args:
            params (dictionary): Input data
            output (filename):  Output data
            backend (BaseBackend): backend object

        Returns:
            result dictionary
        """
        ret = run_algorithm(params, None, True, backend)
        if not isinstance(ret, dict):
            raise AquaChemistryError(
                "Algorithm run result should be a dictionary")

        convert_json_to_dict(ret)
        if logger.isEnabledFor(logging.DEBUG):
            logger.debug('Algorithm returned: {}'.format(
                pprint.pformat(ret, indent=4)))

        print('Output:')
        if isinstance(ret, dict):
            for k, v in ret.items():
                print("'{}': {}".format(k, v))
        else:
            print(ret)

        return ret
    def _update_algorithm_problem(self):
        problem_name = self.get_section_property(JSONSchema.PROBLEM,
                                                 JSONSchema.NAME)
        if problem_name is None:
            problem_name = self.get_property_default_value(
                JSONSchema.PROBLEM, JSONSchema.NAME)

        if problem_name is None:
            raise AquaChemistryError(
                "No algorithm 'problem' section found on input.")

        algo_name = self.get_section_property(JSONSchema.ALGORITHM,
                                              JSONSchema.NAME)
        if algo_name is not None and problem_name in InputParser.get_algorithm_problems(
                algo_name):
            return

        for algo_name in local_algorithms():
            if problem_name in self.get_algorithm_problems(algo_name):
                # set to the first algorithm to solve the problem
                self.set_section_property(JSONSchema.ALGORITHM,
                                          JSONSchema.NAME, algo_name)
                return

        # no algorithm solve this problem, remove section
        self.delete_section(JSONSchema.ALGORITHM)
Example #13
0
    def set_default_properties_for_name(self, section_name):
        if self._parser is None:
            raise AquaChemistryError('Input not initialized.')

        name = self._parser.get_section_property(section_name, JSONSchema.NAME)
        self._parser.delete_section_properties(section_name)
        if name is not None:
            self._parser.set_section_property(section_name, JSONSchema.NAME,
                                              name)

        value = self._parser.get_section_default_properties(section_name)
        if isinstance(value, dict):
            for property_name, property_value in value.items():
                if property_name != JSONSchema.NAME:
                    self._parser.set_section_property(section_name,
                                                      property_name,
                                                      property_value)
        else:
            if value is None:
                types = self._parser.get_section_types(section_name)
                if 'null' not in types:
                    if 'string' in types:
                        value = ''
                    elif 'object' in types:
                        value = {}
                    elif 'array' in types:
                        value = []

            self._parser.set_section_data(section_name, value)
Example #14
0
    def set_section(self, section_name):
        if self._parser is None:
            raise AquaChemistryError('Input not initialized.')

        self._parser.set_section(section_name)
        value = self._parser.get_section_default_properties(section_name)
        if isinstance(value, dict):
            for property_name, property_value in value.items():
                self._parser.set_section_property(section_name, property_name,
                                                  property_value)

            # do one more time in case schema was updated
            value = self._parser.get_section_default_properties(section_name)
            for property_name, property_value in value.items():
                self._parser.set_section_property(section_name, property_name,
                                                  property_value)
        else:
            if value is None:
                types = self._parser.get_section_types(section_name)
                if 'null' not in types:
                    if 'string' in types:
                        value = ''
                    elif 'object' in types:
                        value = {}
                    elif 'array' in types:
                        value = []

            self._parser.set_section_data(section_name, value)
Example #15
0
    def _validate_operator_problem(self):
        operator_name = self.get_section_property(InputParser.OPERATOR, JSONSchema.NAME)
        if operator_name is None:
            return

        problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME)
        if problem_name is None:
            problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME)

        if problem_name is None:
            raise AquaChemistryError("No algorithm 'problem' section found on input.")

        problems = InputParser.get_operator_problems(operator_name)
        if problem_name not in problems:
            raise AquaChemistryError(
                "Problem: {} not in the list of problems: {} for operator: {}.".format(problem_name, problems, operator_name))
Example #16
0
    def _validate_algorithm_problem(self):
        algo_name = self.get_section_property(PluggableType.ALGORITHM.value, JSONSchema.NAME)
        if algo_name is None:
            return

        problem_name = self.get_section_property(JSONSchema.PROBLEM, JSONSchema.NAME)
        if problem_name is None:
            problem_name = self.get_property_default_value(JSONSchema.PROBLEM, JSONSchema.NAME)

        if problem_name is None:
            raise AquaChemistryError("No algorithm 'problem' section found on input.")

        problems = InputParser.get_algorithm_problems(algo_name)
        if problem_name not in problems:
            raise AquaChemistryError("Problem: {} not in the list of problems: {} for algorithm: {}.".format(
                problem_name, problems, algo_name))
    def _update_operator_problem(self):
        problem_name = self.get_section_property(JSONSchema.PROBLEM,
                                                 JSONSchema.NAME)
        if problem_name is None:
            problem_name = self.get_property_default_value(
                JSONSchema.PROBLEM, JSONSchema.NAME)

        if problem_name is None:
            raise AquaChemistryError(
                "No algorithm 'problem' section found on input.")

        operator_name = self.get_section_property(InputParser.OPERATOR,
                                                  JSONSchema.NAME)
        if operator_name is not None and problem_name in InputParser.get_operator_problems(
                operator_name):
            return

        for operator_name in local_chemistry_operators():
            if problem_name in self.get_operator_problems(operator_name):
                # set to the first input to solve the problem
                self.set_section_property(InputParser.OPERATOR,
                                          JSONSchema.NAME, operator_name)
                return

        # no input solve this problem, remove section
        self.delete_section(InputParser.OPERATOR)
    def parse(self):
        """Parse the data."""
        if self._inputdict is None:
            if self._filename is None:
                raise AquaChemistryError("Missing input file")

            section = None
            self._sections = OrderedDict()
            with open(self._filename, 'rt', encoding="utf8",
                      errors='ignore') as f:
                for line in f:
                    section = self._process_line(section, line)
        else:
            self._load_parser_from_dict()

        # check for old enable_substitutions name
        old_enable_substitutions = self.get_section_property(
            JSONSchema.PROBLEM, InputParser._OLD_ENABLE_SUBSTITUTIONS)
        if old_enable_substitutions is not None:
            self.delete_section_property(JSONSchema.PROBLEM,
                                         InputParser._OLD_ENABLE_SUBSTITUTIONS)
            self.set_section_property(JSONSchema.PROBLEM,
                                      InputParser.AUTO_SUBSTITUTIONS,
                                      old_enable_substitutions)

        self._json_schema.update_pluggable_input_schemas(self)
        self._update_driver_input_schemas()
        self._update_operator_input_schema()
        self._sections = self._order_sections(self._sections)
        self._original_sections = copy.deepcopy(self._sections)
    def _process_line(self, section, line):
        stripLine = line.strip()
        if len(stripLine) == 0:
            if section is not None:
                section['data'].append(line)

            return section

        if stripLine.lower().startswith(InputParser._END_SECTION):
            if section is not None:
                self._sections[section[
                    JSONSchema.NAME]] = self._process_section(section)
            return None

        if stripLine.startswith(InputParser._START_SECTION):
            if section is not None:
                raise AquaChemistryError(
                    'New section "{0}" starting before the end of previuos section "{1}"'
                    .format(line, section[JSONSchema.NAME]))

            return OrderedDict([(JSONSchema.NAME, stripLine[1:].lower()),
                                ('data', [])])

        if section is None:
            return section

        section['data'].append(line)

        return section
    def process_substitutions(self, substitutions=None):
        if substitutions is not None and not isinstance(substitutions, dict):
            raise AquaChemistryError(
                'Invalid substitution parameter: {}'.format(substitutions))

        if not self.is_substitution_allowed():
            return {}

        result = {}
        for key, value in self._substitutions.items():
            key_items = key.split('.')
            if len(key_items) != 3:
                raise AquaChemistryError(
                    'Invalid substitution key: {}'.format(key))

            name = self.get_property_default_value(key_items[0],
                                                   JSONSchema.NAME)
            name = self.get_section_property(key_items[0], JSONSchema.NAME,
                                             name)
            if name != key_items[1]:
                continue

            value_set = False
            value_items = value.split('.')
            if len(value_items) == 3:
                name = self.get_section_property(value_items[0],
                                                 JSONSchema.NAME)
                if name == value_items[1]:
                    v = self.get_property_default_value(
                        value_items[0], value_items[2])
                    v = self.get_section_property(value_items[0],
                                                  value_items[2], v)
                    if v is not None:
                        self.set_section_property(key_items[0], key_items[2],
                                                  v)
                        result[key] = v
                        value_set = True

            if value_set or substitutions is None:
                continue

            if value in substitutions:
                self.set_section_property(key_items[0], key_items[2],
                                          substitutions[value])
                result[key] = substitutions[value]

        return result
Example #21
0
    def _update_operator_input_schema(self):
        # find operator
        default_name = self.get_property_default_value(
            InputParser.OPERATOR, JSONSchema.NAME)
        operator_name = self.get_section_property(
            InputParser.OPERATOR, JSONSchema.NAME, default_name)
        if operator_name is None:
            # find the first valid input for the problem
            problem_name = self.get_section_property(
                JSONSchema.PROBLEM, JSONSchema.NAME)
            if problem_name is None:
                problem_name = self.get_property_default_value(
                    JSONSchema.PROBLEM, JSONSchema.NAME)

            if problem_name is None:
                raise AquaChemistryError(
                    "No algorithm 'problem' section found on input.")

            for name in local_chemistry_operators():
                if problem_name in self.get_operator_problems(name):
                    # set to the first input to solve the problem
                    operator_name = name
                    break

        if operator_name is None:
            # just remove fromm schema if none solves the problem
            if InputParser.OPERATOR in self._json_schema.schema['properties']:
                del self._json_schema.schema['properties'][InputParser.OPERATOR]

            return

        if default_name is None:
            default_name = operator_name

        config = {}
        try:
            config = get_chemistry_operator_configuration(operator_name)
        except:
            pass

        input_schema = config['input_schema'] if 'input_schema' in config else {
        }
        properties = input_schema['properties'] if 'properties' in input_schema else {
        }
        properties[JSONSchema.NAME] = {'type': 'string'}
        required = input_schema['required'] if 'required' in input_schema else [
        ]
        additionalProperties = input_schema['additionalProperties'] if 'additionalProperties' in input_schema else True
        if default_name is not None:
            properties[JSONSchema.NAME]['default'] = default_name
            required.append(JSONSchema.NAME)

        if InputParser.OPERATOR not in self._json_schema.schema['properties']:
            self._json_schema.schema['properties'][InputParser.OPERATOR] = {
                'type': 'object'}

        self._json_schema.schema['properties'][InputParser.OPERATOR]['properties'] = properties
        self._json_schema.schema['properties'][InputParser.OPERATOR]['required'] = required
        self._json_schema.schema['properties'][InputParser.OPERATOR]['additionalProperties'] = additionalProperties
Example #22
0
    def delete_section_property(self, section_name, property_name):
        if self._parser is None:
            raise AquaChemistryError('Input not initialized.')

        self._parser.delete_section_property(section_name, property_name)
        if InputParser.is_pluggable_section(
                section_name) and property_name == JSONSchema.NAME:
            self._parser.delete_section_properties(section_name)
Example #23
0
def __checkUnits(units):
    if units.lower() in ["angstrom", "ang", "a"]:
        units = 'Angstrom'
    elif units.lower() in ["bohr", "b"]:
        units = 'Bohr'
    else:
        raise AquaChemistryError('Molecule units format error: ' + units)
    return units
Example #24
0
def __parseAtom(val):
    if val is None or len(val) < 1:
        raise AquaChemistryError('Molecule atom format error: ' + val)

    parts = re.split('\s+', val)
    if len(parts) != 4:
        raise AquaChemistryError('Molecule atom format error: ' + val)

    parts[0] = parts[0].lower().capitalize()
    if not parts[0].isdigit():
        if parts[0] in QMolecule.symbols:
            parts[0] = QMolecule.symbols.index(parts[0])
        else:
            raise AquaChemistryError('Molecule atom symbol error: ' + parts[0])

    return int(float(parts[0])), float(parts[1]), float(parts[2]), float(
        parts[3])
def register_chemistry_operator(cls, configuration=None):
    """
    Registers a chemistry operator class
    Args:
        cls (object): chemistry operator class.
        configuration (object, optional): Pluggable configuration
    Returns:
        name: input name
    Raises:
        AquaChemistryError: if the class is already registered or could not be registered
    """
    _discover_on_demand()

    # Verify that the pluggable is not already registered
    if cls in [
            input.cls for input in _REGISTERED_CHEMISTRY_OPERATORS.values()
    ]:
        raise AquaChemistryError(
            'Could not register class {} is already registered'.format(cls))

    try:
        chem_instance = cls(configuration=configuration)
    except Exception as err:
        raise AquaChemistryError(
            'Could not register chemistry operator:{} could not be instantiated: {}'
            .format(cls, str(err)))

    # Verify that it has a minimal valid configuration.
    try:
        chemistry_operator_name = chem_instance.configuration['name']
    except (LookupError, TypeError):
        raise AquaChemistryError(
            'Could not register chemistry operator: invalid configuration')

    if chemistry_operator_name in _REGISTERED_CHEMISTRY_OPERATORS:
        raise AquaChemistryError(
            'Could not register class {}. Name {} {} is already registered'.
            format(
                cls, chemistry_operator_name,
                _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].cls))

    # Append the pluggable to the `registered_classes` dict.
    _REGISTERED_CHEMISTRY_OPERATORS[
        chemistry_operator_name] = RegisteredChemOp(
            chemistry_operator_name, cls, chem_instance.configuration)
    return chemistry_operator_name
Example #26
0
    def save_input(self, input_file):
        """Save the input of a run to a file.
        Params:
            input_file (string): file path
        """
        if self._parser is None:
            raise AquaChemistryError("Missing input information.")

        self._parser.save_to_file(input_file)
Example #27
0
def _calculate_integrals(molecule, basis='sto3g', calc_type='rhf'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        molecule : A pyquante2 molecular object.
        basis : The basis set for the electronic structure computation
        calc_type: rhf, uhf, rohf
    Returns:
        ehf : Hartree-Fock energy
        enuke: Nuclear repulsion energy
        norbs : Number of orbitals
        mohij : One electron terms of the Hamiltonian.
        mohijkl : Two electron terms of the Hamiltonian.
        orbs: Molecular orbital coefficients
        orbs_energy: Orbital energies
    """
    bfs = basisset(molecule, basis)
    integrals = onee_integrals(bfs, molecule)
    hij = integrals.T + integrals.V
    hijkl_compressed = twoe_integrals(bfs)

    # convert overlap integrals to molecular basis
    # calculate the Hartree-Fock solution of the molecule

    if calc_type == 'rhf':
        solver = rhf(molecule, bfs)
    elif calc_type == 'rohf':
        solver = rohf(molecule, bfs)
    elif calc_type == 'uhf':
        solver = uhf(molecule, bfs)
    else:
        raise AquaChemistryError('Invalid calc_type: {}'.format(calc_type))
    logger.debug('Solver name {}'.format(solver.name))
    ehf = solver.converge()
    if hasattr(solver, 'orbs'):
        orbs = solver.orbs
    else:
        orbs = solver.orbsa
    norbs = len(orbs)
    if hasattr(solver, 'orbe'):
        orbs_energy = solver.orbe
    else:
        orbs_energy = solver.orbea
    enuke = molecule.nuclear_repulsion()
    # Get ints in molecular orbital basis
    mohij = simx(hij, orbs)
    mohijkl_compressed = transformintegrals(hijkl_compressed, orbs)
    mohijkl = np.zeros((norbs, norbs, norbs, norbs))
    for i in range(norbs):
        for j in range(norbs):
            for k in range(norbs):
                for l in range(norbs):
                    mohijkl[i, j, k,
                            l] = mohijkl_compressed[ijkl2intindex(i, j, k, l)]

    return ehf[0], enuke, norbs, mohij, mohijkl, orbs, orbs_energy
Example #28
0
def __parseMolecule(val, units, charge, multiplicity):
    parts = [x.strip() for x in val.split(';')]
    if parts is None or len(parts) < 1:
        raise AquaChemistryError('Molecule format error: ' + val)
    geom = []
    for n in range(len(parts)):
        part = parts[n]
        geom.append(__parseAtom(part))

    if len(geom) < 1:
        raise AquaChemistryError('Molecule format error: ' + val)

    try:
        return molecule(geom,
                        units=units,
                        charge=charge,
                        multiplicity=multiplicity)
    except Exception as exc:
        raise AquaChemistryError('Failed to create molecule') from exc
    def set_section_property(self, section_name, property_name, value):
        section_name = JSONSchema.format_section_name(section_name).lower()
        property_name = JSONSchema.format_property_name(property_name)
        value = self._json_schema.check_property_value(section_name,
                                                       property_name, value)
        types = self.get_property_types(section_name, property_name)

        parser_temp = copy.deepcopy(self)
        InputParser._set_section_property(parser_temp._sections, section_name,
                                          property_name, value, types)
        msg = self._json_schema.validate_property(parser_temp.to_JSON(),
                                                  section_name, property_name)
        if msg is not None:
            raise AquaChemistryError("{}.{}: Value '{}': '{}'".format(
                section_name, property_name, value, msg))

        InputParser._set_section_property(self._sections, section_name,
                                          property_name, value, types)
        if property_name == JSONSchema.NAME:
            if InputParser.OPERATOR == section_name:
                self._update_operator_input_schema()
                # remove properties that are not valid for this section
                default_properties = self.get_section_default_properties(
                    section_name)
                if isinstance(default_properties, dict):
                    properties = self.get_section_properties(section_name)
                    for property_name in list(properties.keys()):
                        if property_name != JSONSchema.NAME and property_name not in default_properties:
                            self.delete_section_property(
                                section_name, property_name)
            elif JSONSchema.PROBLEM == section_name:
                self._update_algorithm_problem()
                self._update_operator_problem()
            elif InputParser.is_pluggable_section(section_name):
                self._json_schema.update_pluggable_input_schemas(self)
                # remove properties that are not valid for this section
                default_properties = self.get_section_default_properties(
                    section_name)
                if isinstance(default_properties, dict):
                    properties = self.get_section_properties(section_name)
                    for property_name in list(properties.keys()):
                        if property_name != JSONSchema.NAME and property_name not in default_properties:
                            self.delete_section_property(
                                section_name, property_name)

                if section_name == JSONSchema.ALGORITHM:
                    self._update_dependency_sections()
            elif value is not None:
                value = str(value).lower().strip()
                if len(value) > 0 and self.section_is_driver(value):
                    self._update_driver_input_schemas()
                    self._update_driver_sections()

        self._sections = self._order_sections(self._sections)
    def _run_drive(self, input, save_json_algo_file):
        if input is None:
            raise AquaChemistryError("Missing input.")

        self._parser = InputParser(input)
        self._parser.parse()
        driver_return = self._run_driver_from_parser(self._parser,
                                                     save_json_algo_file)
        driver_return[1]['input'] = driver_return[2].to_params()
        driver_return[1]['input']['name'] = driver_return[2].configuration[
            'name']
        return driver_return[1]