import warnings
from h5py.h5py_warnings import H5pyDeprecationWarning
warnings.filterwarnings(action="ignore", category=H5pyDeprecationWarning)

from qiskit_nature.drivers import Molecule

molecule = Molecule(
    # coordinates are given in Angstrom
    geometry=[
        ["O", [0.0, 0.0, 0.115]],
        ["H", [0.0, 0.754, -0.459]],
        ["H", [0.0, -0.754, -0.459]],
    ],
    multiplicity=1,  # = 2*spin + 1
    charge=0,
)

from qiskit_nature.drivers.second_quantization import ElectronicStructureMoleculeDriver, ElectronicStructureDriverType

driver = ElectronicStructureMoleculeDriver(
    molecule=molecule,
    basis="sto3g",
    driver_type=ElectronicStructureDriverType.PYSCF,
)

from qiskit_nature.problems.second_quantization.electronic import ElectronicStructureProblem

problem = ElectronicStructureProblem(driver)

# this will call driver.run() internally
second_q_ops = problem.second_q_ops()

from qiskit_nature.operators.second_quantization import FermionicOp

# we increase the truncation value of the FermionicOp applied while printing
FermionicOp.set_truncation(500)

hamiltonian = second_q_ops[0]
print(hamiltonian)

from qiskit_nature.transformers.second_quantization.electronic import ActiveSpaceTransformer

transformer = ActiveSpaceTransformer(
    num_electrons=2,
    num_molecular_orbitals=3,
)

problem_reduced = ElectronicStructureProblem(driver, [transformer])
second_q_ops_reduced = problem_reduced.second_q_ops()
hamiltonian_reduced = second_q_ops_reduced[0]

print(hamiltonian_reduced)

from qiskit_nature.converters.second_quantization import QubitConverter
from qiskit_nature.mappers.second_quantization import JordanWignerMapper

jw_mapper = JordanWignerMapper()
jw_converter = QubitConverter(jw_mapper)

qubit_op_jw = jw_converter.convert(hamiltonian_reduced)
print(qubit_op_jw)

from qiskit_nature.mappers.second_quantization import ParityMapper

parity_mapper = ParityMapper()
parity_converter = QubitConverter(parity_mapper, two_qubit_reduction=True)

qubit_op_parity = parity_converter.convert(hamiltonian_reduced, num_particles=problem_reduced.num_particles)
print(qubit_op_parity)

from qiskit.algorithms.optimizers import SLSQP
from qiskit.providers.aer import StatevectorSimulator, QasmSimulator
from qiskit_nature.algorithms.ground_state_solvers.minimum_eigensolver_factories import VQEUCCFactory

vqe_factory = VQEUCCFactory(
    quantum_instance=StatevectorSimulator(),
    #quantum_instance=QasmSimulator(),
    optimizer=SLSQP(),
)

from qiskit_nature.algorithms.ground_state_solvers import GroundStateEigensolver

solver = GroundStateEigensolver(parity_converter, vqe_factory)

result = solver.solve(problem_reduced)

print(result)

from urllib3.connection import SystemTimeWarning
warnings.filterwarnings(action="ignore", category=SystemTimeWarning)

import numpy as np

np.random.seed(42)

from qiskit.circuit.library import EfficientSU2

ansatz = EfficientSU2(num_qubits=qubit_op_parity.num_qubits, reps=1, entanglement='linear', insert_barriers=True)
ansatz.decompose().draw('mpl', style='iqx')

from qiskit.providers.ibmq import IBMQ, IBMQAccountError

try:
    IBMQ.load_account()
    provider = IBMQ.get_provider(group="open")
except IBMQAccountError:
    print("No IBMQ account credentials available")
    provider = None
else:
    print("Provider supports runtime: ", provider.has_service("runtime"))

    backend = provider.get_backend("ibmq_qasm_simulator")

from qiskit_nature.runtime import VQEClient

optimizer = {
    "name": "SPSA",
    "maxiter": 50,
}
initial_point = np.random.random(ansatz.num_parameters)

if provider is not None:
    runtime_vqe = VQEClient(
        ansatz=ansatz,
        optimizer=optimizer,
        initial_point=initial_point,
        provider=provider,
        backend=backend,
        shots=1024,
        measurement_error_mitigation=True,
    )

if provider is not None:
    runtime_vqe_solver = GroundStateEigensolver(parity_converter, runtime_vqe)

if provider is not None:
    runtime_result = runtime_vqe_solver.solve(problem_reduced)

if provider is not None:
    print(runtime_result)

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright