diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2fc86c596..26c112176 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -29,6 +29,8 @@ Added - The connector ``get_job()`` methods accepts two new parameters for including and excluding specific fields from the response. (#6) +- Added ``backend.defauls()`` for retrieving the pulse defaults for a + backend through a new endpoint (#33). Changed """"""" diff --git a/qiskit/providers/ibmq/api/ibmqconnector.py b/qiskit/providers/ibmq/api/ibmqconnector.py index 51ac38bda..274d1947e 100644 --- a/qiskit/providers/ibmq/api/ibmqconnector.py +++ b/qiskit/providers/ibmq/api/ibmqconnector.py @@ -37,6 +37,19 @@ def get_backend_properties_url(config, backend_type, hub=None): return '/Backends/{}/properties'.format(backend_type) +def get_backend_defaults_url(config, backend_type): + """Return the URL for a backend's pulse defaults.""" + hub = config.get('hub', None) + group = config.get('group', None) + project = config.get('project', None) + + if hub and group and project: + return '/Network/{}/Groups/{}/Projects/{}/devices/{}/defaults'.format( + hub, group, project, backend_type) + + return '/Backends/{}/defaults'.format(backend_type) + + def get_backends_url(config, hub, group, project): """Return the URL for a backend.""" hub = config.get('hub', hub) @@ -81,13 +94,11 @@ def __init__(self, token=None, config=None, verify=True): def _check_backend(self, backend_name): """Check if the name of a backend is valid to run in QX Platform.""" - backend_name = backend_name.lower() - - # Check for new-style backends backends = self.available_backends() for backend_ in backends: if backend_.get('backend_name', '') == backend_name: return backend_name + # backend unrecognized return None @@ -312,7 +323,7 @@ def cancel_job(self, id_job, hub=None, group=None, project=None, return res def backend_status(self, backend, access_token=None, user_id=None): - """Get the status of a chip.""" + """Get the status of a backend.""" if access_token: self.req.credential.set_token(access_token) if user_id: @@ -346,7 +357,7 @@ def backend_status(self, backend, access_token=None, user_id=None): def backend_properties(self, backend, hub=None, access_token=None, user_id=None): - """Get the parameters of calibration of a real chip.""" + """Get the properties of a backend.""" if access_token: self.req.credential.set_token(access_token) if user_id: @@ -368,9 +379,26 @@ def backend_properties(self, backend, hub=None, access_token=None, ret["backend_name"] = backend_type return ret + def backend_defaults(self, backend): + """Get the pulse defaults of a backend.""" + if not self.check_credentials(): + raise CredentialsError('credentials invalid') + + backend_name = self._check_backend(backend) + + if not backend_name: + raise BadBackendError(backend) + + url = get_backend_defaults_url(self.config, backend_name) + + ret = self.req.get(url) + if not bool(ret): + ret = {} + return ret + def available_backends(self, hub=None, group=None, project=None, access_token=None, user_id=None): - """Get the backends available to use in the QX Platform.""" + """Get the backends available to use in the IBMQ Platform.""" if access_token: self.req.credential.set_token(access_token) if user_id: diff --git a/qiskit/providers/ibmq/ibmqbackend.py b/qiskit/providers/ibmq/ibmqbackend.py index 956f21b41..06ca8c92b 100644 --- a/qiskit/providers/ibmq/ibmqbackend.py +++ b/qiskit/providers/ibmq/ibmqbackend.py @@ -13,7 +13,8 @@ from marshmallow import ValidationError from qiskit.providers import BaseBackend, JobStatus -from qiskit.providers.models import BackendStatus, BackendProperties +from qiskit.providers.models import (BackendStatus, BackendProperties, + PulseDefaults) from .api import ApiError from .exceptions import IBMQBackendError, IBMQBackendValueError @@ -90,6 +91,20 @@ def status(self): raise LookupError( "Couldn't get backend status: {0}".format(ex)) + def defaults(self): + """Return the pulse defaults for the backend. + + Returns: + PulseDefaults: the pulse defaults for the backend. IF the backend + does not support defaults, it returns ``None``. + """ + backend_defaults = self._api.backend_defaults(self.name()) + + if backend_defaults: + return PulseDefaults.from_dict(backend_defaults) + + return None + def jobs(self, limit=50, skip=0, status=None, db_filter=None): """Attempt to get the jobs submitted to the backend. diff --git a/test/ibmq/test_ibmq_backends.py b/test/ibmq/test_ibmq_backends.py index 840fbf1b1..49244166a 100644 --- a/test/ibmq/test_ibmq_backends.py +++ b/test/ibmq/test_ibmq_backends.py @@ -73,6 +73,14 @@ def test_remote_backend_properties(self, qe_token, qe_url): if backend.configuration().simulator: self.assertEqual(properties, None) + @requires_qe_access + def test_remote_backend_defaults(self, qe_token, qe_url): + """Test backend pulse defaults.""" + IBMQ.enable_account(qe_token, qe_url) + remotes = IBMQ.backends(simulator=False) + for backend in remotes: + _ = backend.defaults() + @requires_qe_access def test_qobj_headers_in_result_sims(self, qe_token, qe_url): """Test that the qobj headers are passed onto the results for sims."""