Пример #1
0
    def _parse_matrix_file(self, fname, useAO2E=False):
        # get_driver_class is used here because the discovery routine will load all the gaussian
        # binary dependencies, if not loaded already. It won't work without it.
        try:
            get_driver_class('GAUSSIAN')
            from .gauopen.QCMatEl import MatEl
        except ImportError as mnfe:
            msg = 'qcmatrixio extension not found. See Gaussian driver readme to build qcmatrixio.F using f2py' \
                if mnfe.name == 'qcmatrixio' else str(mnfe)

            logger.info(msg)
            raise QiskitChemistryError(msg)

        mel = MatEl(file=fname)
        logger.debug('MatrixElement file:\n{}'.format(mel))

        # Create driver level molecule object and populate
        _q_ = QMolecule()
        # Energies and orbits
        _q_.hf_energy = mel.scalar('ETOTAL')
        _q_.nuclear_repulsion_energy = mel.scalar('ENUCREP')
        _q_.num_orbitals = 0  # updated below from orbital coeffs size
        _q_.num_alpha = (mel.ne + mel.multip - 1) // 2
        _q_.num_beta = (mel.ne - mel.multip + 1) // 2
        _q_.molecular_charge = mel.icharg
        # Molecule geometry
        _q_.multiplicity = mel.multip
        _q_.num_atoms = mel.natoms
        _q_.atom_symbol = []
        _q_.atom_xyz = np.empty([mel.natoms, 3])
        syms = mel.ian
        xyz = np.reshape(mel.c, (_q_.num_atoms, 3))
        for _n in range(0, _q_.num_atoms):
            _q_.atom_symbol.append(QMolecule.symbols[syms[_n]])
            for _i in range(xyz.shape[1]):
                coord = xyz[_n][_i]
                if abs(coord) < 1e-10:
                    coord = 0
                _q_.atom_xyz[_n][_i] = coord

        moc = self._getMatrix(mel, 'ALPHA MO COEFFICIENTS')
        _q_.num_orbitals = moc.shape[0]
        _q_.mo_coeff = moc
        orbs_energy = self._getMatrix(mel, 'ALPHA ORBITAL ENERGIES')
        _q_.orbital_energies = orbs_energy

        # 1 and 2 electron integrals
        hcore = self._getMatrix(mel, 'CORE HAMILTONIAN ALPHA')
        logger.debug('CORE HAMILTONIAN ALPHA {}'.format(hcore.shape))
        mohij = QMolecule.oneeints2mo(hcore, moc)
        if useAO2E:
            # These are 2-body in AO. We can convert to MO via the QMolecule
            # method but using ints in MO already, as in the else here, is better
            eri = self._getMatrix(mel, 'REGULAR 2E INTEGRALS')
            logger.debug('REGULAR 2E INTEGRALS {}'.format(eri.shape))
            mohijkl = QMolecule.twoeints2mo(eri, moc)
        else:
            # These are in MO basis but by default will be reduced in size by
            # frozen core default so to use them we need to add Window=Full
            # above when we augment the config
            mohijkl = self._getMatrix(mel, 'AA MO 2E INTEGRALS')
            logger.debug('AA MO 2E INTEGRALS {}'.format(mohijkl.shape))

        _q_.mo_onee_ints = mohij
        _q_.mo_eri_ints = mohijkl

        # dipole moment
        dipints = self._getMatrix(mel, 'DIPOLE INTEGRALS')
        dipints = np.einsum('ijk->kji', dipints)
        _q_.x_dip_mo_ints = QMolecule.oneeints2mo(dipints[0], moc)
        _q_.y_dip_mo_ints = QMolecule.oneeints2mo(dipints[1], moc)
        _q_.z_dip_mo_ints = QMolecule.oneeints2mo(dipints[2], moc)

        nucl_dip = np.einsum('i,ix->x', syms, xyz)
        nucl_dip = np.round(nucl_dip, decimals=8)
        _q_.nuclear_dipole_moment = nucl_dip
        _q_.reverse_dipole_sign = True

        return _q_
Пример #2
0
    def run_driver(self, params, backend=None):
        """
        Runs the Qiskit Chemistry driver

        Args:
            params (Union(dictionary, filename)): Chemistry input data
            backend (QuantumInstance or BaseBackend): the experimental settings
                to be used in place of backend name
         Raises:
            QiskitChemistryError: Missing Input
        """
        if params is None:
            raise QiskitChemistryError("Missing input.")

        self._operator = None
        self._chemistry_result = None
        self._qiskit_aqua = None
        self._hdf5_file = None
        self._parser = InputParser(params)
        self._parser.parse()

        # before merging defaults attempts to find a provider for the backend in case no
        # provider was passed
        if backend is None and \
                self._parser.get_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER) is None:
            backend_name = self._parser.get_section_property(
                JSONSchema.BACKEND, JSONSchema.NAME)
            if backend_name is not None:
                self._parser.set_section_property(
                    JSONSchema.BACKEND, JSONSchema.PROVIDER,
                    get_provider_from_backend(backend_name))

        # set provider and name in input file for proper backend schema dictionary build
        if isinstance(backend, BaseBackend):
            self._parser.backend = backend
            self._parser.add_section_properties(
                JSONSchema.BACKEND, {
                    JSONSchema.PROVIDER: get_provider_from_backend(backend),
                    JSONSchema.NAME: backend.name(),
                })

        self._parser.validate_merge_defaults()

        experiment_name = "-- no &NAME section found --"
        if JSONSchema.NAME in self._parser.get_section_names():
            name_sect = self._parser.get_section(JSONSchema.NAME)
            if name_sect is not None:
                experiment_name = str(name_sect)
        logger.info('Running chemistry problem from input file: %s',
                    self._parser.get_filename())
        logger.info('Experiment description: %s', experiment_name.rstrip())

        driver_name = self._parser.get_section_property(
            InputParser.DRIVER, JSONSchema.NAME)
        if driver_name is None:
            raise QiskitChemistryError(
                'Property "{0}" missing in section "{1}"'.format(
                    JSONSchema.NAME, InputParser.DRIVER))

        self._hdf5_file = \
            self._parser.get_section_property(InputParser.DRIVER, InputParser.HDF5_OUTPUT)

        if driver_name not in local_drivers():
            raise QiskitChemistryError(
                'Driver "{0}" missing in local drivers'.format(driver_name))

        work_path = None
        input_file = self._parser.get_filename()
        if input_file is not None:
            work_path = os.path.dirname(os.path.realpath(input_file))

        section = self._parser.get_section(driver_name)
        driver = get_driver_class(driver_name).init_from_input(section)
        driver.work_path = work_path
        molecule = driver.run()

        if work_path is not None and \
                self._hdf5_file is not None and not os.path.isabs(self._hdf5_file):
            self._hdf5_file = os.path.abspath(
                os.path.join(work_path, self._hdf5_file))

        molecule.log()

        if self._hdf5_file is not None:
            molecule.save(self._hdf5_file)
            logger.info("HDF5 file saved '%s'", self._hdf5_file)

        # Run the Hamiltonian to process the QMolecule and get an input for algorithms
        clazz = get_chemistry_operator_class(
            self._parser.get_section_property(InputParser.OPERATOR,
                                              JSONSchema.NAME))
        self._operator = clazz.init_params(
            self._parser.get_section_properties(InputParser.OPERATOR))
        qubit_op, aux_ops = self.operator.run(molecule)
        input_object = EnergyInput(qubit_op, aux_ops)

        logger.debug('Core computed substitution variables %s',
                     self.operator.molecule_info)
        result = self._parser.process_substitutions(
            self.operator.molecule_info)
        logger.debug('Substitutions %s', result)

        aqua_params = {}
        for section_name, section in self._parser.get_sections().items():
            if section_name == JSONSchema.NAME or \
               section_name == InputParser.DRIVER or \
               section_name == driver_name.lower() or \
               section_name == InputParser.OPERATOR or \
               not isinstance(section, dict):
                continue

            aqua_params[section_name] = copy.deepcopy(section)
            if JSONSchema.PROBLEM == section_name and \
                    InputParser.AUTO_SUBSTITUTIONS in aqua_params[section_name]:
                del aqua_params[section_name][InputParser.AUTO_SUBSTITUTIONS]

        self._qiskit_aqua = QiskitAqua(aqua_params, input_object, backend)
Пример #3
0
    def _run_driver_from_parser(self, p, save_json_algo_file):
        if p is None:
            raise QiskitChemistryError("Missing parser")

        # before merging defaults attempts to find a provider for the backend in case no
        # provider was passed
        if p.get_section_property(JSONSchema.BACKEND,
                                  JSONSchema.PROVIDER) is None:
            backend_name = p.get_section_property(JSONSchema.BACKEND,
                                                  JSONSchema.NAME)
            if backend_name is not None:
                p.set_section_property(JSONSchema.BACKEND, JSONSchema.PROVIDER,
                                       get_provider_from_backend(backend_name))

        p.validate_merge_defaults()
        # logger.debug('ALgorithm Input Schema: {}'.format(json.dumps(p..get_sections(), sort_keys=True, indent=4)))

        experiment_name = "-- no &NAME section found --"
        if JSONSchema.NAME in p.get_section_names():
            name_sect = p.get_section(JSONSchema.NAME)
            if name_sect is not None:
                experiment_name = str(name_sect)
        logger.info('Running chemistry problem from input file: {}'.format(
            p.get_filename()))
        logger.info('Experiment description: {}'.format(
            experiment_name.rstrip()))

        driver_name = p.get_section_property(InputParser.DRIVER,
                                             JSONSchema.NAME)
        if driver_name is None:
            raise QiskitChemistryError(
                'Property "{0}" missing in section "{1}"'.format(
                    JSONSchema.NAME, InputParser.DRIVER))

        hdf5_file = p.get_section_property(InputParser.DRIVER,
                                           QiskitChemistry.KEY_HDF5_OUTPUT)

        if driver_name not in local_drivers():
            raise QiskitChemistryError(
                'Driver "{0}" missing in local drivers'.format(driver_name))

        work_path = None
        input_file = p.get_filename()
        if input_file is not None:
            work_path = os.path.dirname(os.path.realpath(input_file))

        section = p.get_section(driver_name)
        driver = get_driver_class(driver_name).init_from_input(section)
        driver.work_path = work_path
        molecule = driver.run()

        if work_path is not None and hdf5_file is not None and not os.path.isabs(
                hdf5_file):
            hdf5_file = os.path.abspath(os.path.join(work_path, hdf5_file))

        molecule.log()

        if hdf5_file is not None:
            molecule._origin_driver_name = driver_name
            molecule._origin_driver_config = section if isinstance(
                section, str) else json.dumps(
                    section, sort_keys=True, indent=4)
            molecule.save(hdf5_file)
            text = "HDF5 file saved '{}'".format(hdf5_file)
            logger.info(text)
            if not save_json_algo_file:
                logger.info('Run ended with hdf5 file saved.')
                return QiskitChemistry._DRIVER_RUN_TO_HDF5, text

        # Run the Hamiltonian to process the QMolecule and get an input for algorithms
        cls = get_chemistry_operator_class(
            p.get_section_property(InputParser.OPERATOR, JSONSchema.NAME))
        self._core = cls.init_params(
            p.get_section_properties(InputParser.OPERATOR))
        input_object = self._core.run(molecule)

        logger.debug('Core computed substitution variables {}'.format(
            self._core.molecule_info))
        result = p.process_substitutions(self._core.molecule_info)
        logger.debug('Substitutions {}'.format(result))

        params = {}
        for section_name, section in p.get_sections().items():
            if section_name == JSONSchema.NAME or \
               section_name == InputParser.DRIVER or \
               section_name == driver_name.lower() or \
               section_name == InputParser.OPERATOR or \
               not isinstance(section, dict):
                continue

            params[section_name] = copy.deepcopy(section)
            if JSONSchema.PROBLEM == section_name and InputParser.AUTO_SUBSTITUTIONS in params[
                    section_name]:
                del params[section_name][InputParser.AUTO_SUBSTITUTIONS]

        return QiskitChemistry._DRIVER_RUN_TO_ALGO_INPUT, params, input_object