We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
BackendV2Converter fails to wrap Aer simulator
### Environment

- **Qiskit Terra version**: 8ec6749
- **Qiskit Aer version**: 0.11.2
- **Python version**: 3.10.9
- **Operating system**: Arch Linux


### What is happening?

See title.

### How can we reproduce the issue?

```python
from qiskit import Aer
from qiskit.providers import BackendV2Converter
backend = BackendV2Converter(Aer.get_backend('aer_simulator'))
```

```
KeyError                                  Traceback (most recent call last)
~/projects/qiskit-terra/qiskit/providers/models/backendconfiguration.py in __getattr__(self, name)
    383         try:
--> 384             return self._data[name]
    385         except KeyError as ex:

KeyError: 'online_date'

The above exception was the direct cause of the following exception:

AttributeError                            Traceback (most recent call last)
<ipython-input-1-38c84b7d22f9> in <module>
      1 from qiskit import Aer
      2 from qiskit.providers import BackendV2Converter
----> 3 backend = BackendV2Converter(Aer.get_backend('aer_simulator'))

~/projects/qiskit-terra/qiskit/providers/backend_compat.py in __init__(self, backend, name_mapping, add_delay)
    221             name=backend.name(),
    222             description=self._config.description,
--> 223             online_date=self._config.online_date,
    224             backend_version=self._config.backend_version,
    225         )

~/projects/qiskit-terra/qiskit/providers/models/backendconfiguration.py in __getattr__(self, name)
    384             return self._data[name]
    385         except KeyError as ex:
--> 386             raise AttributeError(f"Attribute {name} is not defined") from ex
    387 
    388     @classmethod

AttributeError: Attribute online_date is not defined
```

### What should happen?

It should work.

### Any suggestions?

From @mtreinish :
>The converter is meant to be general but we never tested it with aer and I guess it misses that the online date field is optional

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qiskit/providers/backend_compat.py`
Content:
```
1 # This code is part of Qiskit.
2 #
3 # (C) Copyright IBM 2020.
4 #
5 # This code is licensed under the Apache License, Version 2.0. You may
6 # obtain a copy of this license in the LICENSE.txt file in the root directory
7 # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8 #
9 # Any modifications or derivative works of this code must retain this
10 # copyright notice, and modified files need to carry a notice indicating
11 # that they have been altered from the originals.
12 
13 """Backend abstract interface for providers."""
14 
15 from __future__ import annotations
16 
17 from typing import List, Iterable, Any, Dict, Optional
18 
19 from qiskit.exceptions import QiskitError
20 
21 from qiskit.providers.backend import BackendV1, BackendV2
22 from qiskit.providers.backend import QubitProperties
23 from qiskit.utils.units import apply_prefix
24 from qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping
25 from qiskit.circuit.measure import Measure
26 from qiskit.providers.models.backendconfiguration import BackendConfiguration
27 from qiskit.providers.models.backendproperties import BackendProperties
28 from qiskit.providers.models.pulsedefaults import PulseDefaults
29 from qiskit.providers.options import Options
30 from qiskit.providers.exceptions import BackendPropertyError
31 
32 
33 def convert_to_target(
34     configuration: BackendConfiguration,
35     properties: BackendProperties = None,
36     defaults: PulseDefaults = None,
37     custom_name_mapping: Optional[Dict[str, Any]] = None,
38     add_delay: bool = False,
39 ):
40     """Uses configuration, properties and pulse defaults
41     to construct and return Target class.
42     """
43     # pylint: disable=cyclic-import
44     from qiskit.transpiler.target import (
45         Target,
46         InstructionProperties,
47     )
48 
49     # Standard gates library mapping, multicontrolled gates not included since they're
50     # variable width
51     name_mapping = get_standard_gate_name_mapping()
52     target = None
53     if custom_name_mapping is not None:
54         name_mapping.update(custom_name_mapping)
55     # Parse from properties if it exsits
56     if properties is not None:
57         qubit_properties = qubit_props_list_from_props(properties=properties)
58         target = Target(num_qubits=configuration.n_qubits, qubit_properties=qubit_properties)
59         # Parse instructions
60         gates: Dict[str, Any] = {}
61         for gate in properties.gates:
62             name = gate.gate
63             if name in name_mapping:
64                 if name not in gates:
65                     gates[name] = {}
66             else:
67                 raise QiskitError(
68                     f"Operation name {name} does not have a known mapping. Use "
69                     "custom_name_mapping to map this name to an Operation object"
70                 )
71 
72             qubits = tuple(gate.qubits)
73             gate_props = {}
74             for param in gate.parameters:
75                 if param.name == "gate_error":
76                     gate_props["error"] = param.value
77                 if param.name == "gate_length":
78                     gate_props["duration"] = apply_prefix(param.value, param.unit)
79             gates[name][qubits] = InstructionProperties(**gate_props)
80         for gate, props in gates.items():
81             inst = name_mapping[gate]
82             target.add_instruction(inst, props)
83         # Create measurement instructions:
84         measure_props = {}
85         for qubit, _ in enumerate(properties.qubits):
86             measure_props[(qubit,)] = InstructionProperties(
87                 duration=properties.readout_length(qubit),
88                 error=properties.readout_error(qubit),
89             )
90         target.add_instruction(Measure(), measure_props)
91     # Parse from configuration because properties doesn't exist
92     else:
93         target = Target(num_qubits=configuration.n_qubits)
94         for gate in configuration.gates:
95             name = gate.name
96             gate_props = (
97                 {tuple(x): None for x in gate.coupling_map}  # type: ignore[misc]
98                 if hasattr(gate, "coupling_map")
99                 else {None: None}
100             )
101             if name in name_mapping:
102                 target.add_instruction(name_mapping[name], gate_props)
103             else:
104                 raise QiskitError(
105                     f"Operation name {name} does not have a known mapping. "
106                     "Use custom_name_mapping to map this name to an Operation object"
107                 )
108         target.add_instruction(Measure())
109     # parse global configuration properties
110     if hasattr(configuration, "dt"):
111         target.dt = configuration.dt
112     if hasattr(configuration, "timing_constraints"):
113         target.granularity = configuration.timing_constraints.get("granularity")
114         target.min_length = configuration.timing_constraints.get("min_length")
115         target.pulse_alignment = configuration.timing_constraints.get("pulse_alignment")
116         target.aquire_alignment = configuration.timing_constraints.get("acquire_alignment")
117     # If a pulse defaults exists use that as the source of truth
118     if defaults is not None:
119         inst_map = defaults.instruction_schedule_map
120         for inst in inst_map.instructions:
121             for qarg in inst_map.qubits_with_instruction(inst):
122                 try:
123                     qargs = tuple(qarg)
124                 except TypeError:
125                     qargs = (qarg,)
126                 # Do NOT call .get method. This parses Qpbj immediately.
127                 # This operation is computationally expensive and should be bypassed.
128                 calibration_entry = inst_map._get_calibration_entry(inst, qargs)
129                 if inst in target:
130                     if inst == "measure":
131                         for qubit in qargs:
132                             target[inst][(qubit,)].calibration = calibration_entry
133                     elif qargs in target[inst]:
134                         target[inst][qargs].calibration = calibration_entry
135     combined_global_ops = set()
136     if configuration.basis_gates:
137         combined_global_ops.update(configuration.basis_gates)
138     for op in combined_global_ops:
139         if op not in target:
140             if op in name_mapping:
141                 target.add_instruction(
142                     name_mapping[op], {(bit,): None for bit in range(target.num_qubits)}
143                 )
144             else:
145                 raise QiskitError(
146                     f"Operation name '{op}' does not have a known mapping. Use "
147                     "custom_name_mapping to map this name to an Operation object"
148                 )
149     if add_delay and "delay" not in target:
150         target.add_instruction(
151             name_mapping["delay"], {(bit,): None for bit in range(target.num_qubits)}
152         )
153     return target
154 
155 
156 def qubit_props_list_from_props(
157     properties: BackendProperties,
158 ) -> List[QubitProperties]:
159     """Uses BackendProperties to construct
160     and return a list of QubitProperties.
161     """
162     qubit_props: List[QubitProperties] = []
163     for qubit, _ in enumerate(properties.qubits):
164         try:
165             t_1 = properties.t1(qubit)
166         except BackendPropertyError:
167             t_1 = None
168         try:
169             t_2 = properties.t2(qubit)
170         except BackendPropertyError:
171             t_2 = None
172         try:
173             frequency = properties.frequency(qubit)
174         except BackendPropertyError:
175             frequency = None
176         qubit_props.append(
177             QubitProperties(  # type: ignore[no-untyped-call]
178                 t1=t_1,
179                 t2=t_2,
180                 frequency=frequency,
181             )
182         )
183     return qubit_props
184 
185 
186 class BackendV2Converter(BackendV2):
187     """A converter class that takes a :class:`~.BackendV1` instance and wraps it in a
188     :class:`~.BackendV2` interface.
189 
190     This class implements the :class:`~.BackendV2` interface and is used to enable
191     common access patterns between :class:`~.BackendV1` and :class:`~.BackendV2`. This
192     class should only be used if you need a :class:`~.BackendV2` and still need
193     compatibility with :class:`~.BackendV1`.
194     """
195 
196     def __init__(
197         self,
198         backend: BackendV1,
199         name_mapping: Optional[Dict[str, Any]] = None,
200         add_delay: bool = False,
201     ):
202         """Initialize a BackendV2 converter instance based on a BackendV1 instance.
203 
204         Args:
205             backend: The input :class:`~.BackendV1` based backend to wrap in a
206                 :class:`~.BackendV2` interface
207             name_mapping: An optional dictionary that maps custom gate/operation names in
208                 ``backend`` to an :class:`~.Operation` object representing that
209                 gate/operation. By default most standard gates names are mapped to the
210                 standard gate object from :mod:`qiskit.circuit.library` this only needs
211                 to be specified if the input ``backend`` defines gates in names outside
212                 that set.
213             add_delay: If set to true a :class:`~qiskit.circuit.Delay` operation
214                 will be added to the target as a supported operation for all
215                 qubits
216         """
217         self._backend = backend
218         self._config = self._backend.configuration()
219         super().__init__(
220             provider=backend.provider,
221             name=backend.name(),
222             description=self._config.description,
223             online_date=self._config.online_date,
224             backend_version=self._config.backend_version,
225         )
226         self._options = self._backend._options
227         self._properties = None
228         if hasattr(self._backend, "properties"):
229             self._properties = self._backend.properties()
230         self._defaults = None
231         self._target = None
232         self._name_mapping = name_mapping
233         self._add_delay = add_delay
234 
235     @property
236     def target(self):
237         """A :class:`qiskit.transpiler.Target` object for the backend.
238 
239         :rtype: Target
240         """
241         if self._target is None:
242             if self._defaults is None and hasattr(self._backend, "defaults"):
243                 self._defaults = self._backend.defaults()
244             if self._properties is None and hasattr(self._backend, "properties"):
245                 self._properties = self._backend.properties()
246             self._target = convert_to_target(
247                 self._config,
248                 self._properties,
249                 self._defaults,
250                 custom_name_mapping=self._name_mapping,
251                 add_delay=self._add_delay,
252             )
253         return self._target
254 
255     @property
256     def max_circuits(self):
257         return self._config.max_experiments
258 
259     @classmethod
260     def _default_options(cls):
261         return Options()
262 
263     @property
264     def dtm(self) -> float:
265         return self._config.dtm
266 
267     @property
268     def meas_map(self) -> List[List[int]]:
269         return self._config.meas_map
270 
271     def drive_channel(self, qubit: int):
272         return self._config.drive(qubit)
273 
274     def measure_channel(self, qubit: int):
275         return self._config.measure(qubit)
276 
277     def acquire_channel(self, qubit: int):
278         return self._config.acquire(qubit)
279 
280     def control_channel(self, qubits: Iterable[int]):
281         return self._config.control(qubits)
282 
283     def run(self, run_input, **options):
284         return self._backend.run(run_input, **options)
285
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qiskit/providers/backend_compat.py b/qiskit/providers/backend_compat.py
--- a/qiskit/providers/backend_compat.py
+++ b/qiskit/providers/backend_compat.py
@@ -138,9 +138,7 @@
     for op in combined_global_ops:
         if op not in target:
             if op in name_mapping:
-                target.add_instruction(
-                    name_mapping[op], {(bit,): None for bit in range(target.num_qubits)}
-                )
+                target.add_instruction(name_mapping[op], name=op)
             else:
                 raise QiskitError(
                     f"Operation name '{op}' does not have a known mapping. Use "
@@ -220,7 +218,7 @@
             provider=backend.provider,
             name=backend.name(),
             description=self._config.description,
-            online_date=self._config.online_date,
+            online_date=getattr(self._config, "online_date", None),
             backend_version=self._config.backend_version,
         )
         self._options = self._backend._options

{"golden_diff": "diff --git a/qiskit/providers/backend_compat.py b/qiskit/providers/backend_compat.py\n--- a/qiskit/providers/backend_compat.py\n+++ b/qiskit/providers/backend_compat.py\n@@ -138,9 +138,7 @@\n     for op in combined_global_ops:\n         if op not in target:\n             if op in name_mapping:\n-                target.add_instruction(\n-                    name_mapping[op], {(bit,): None for bit in range(target.num_qubits)}\n-                )\n+                target.add_instruction(name_mapping[op], name=op)\n             else:\n                 raise QiskitError(\n                     f\"Operation name '{op}' does not have a known mapping. Use \"\n@@ -220,7 +218,7 @@\n             provider=backend.provider,\n             name=backend.name(),\n             description=self._config.description,\n-            online_date=self._config.online_date,\n+            online_date=getattr(self._config, \"online_date\", None),\n             backend_version=self._config.backend_version,\n         )\n         self._options = self._backend._options\n", "issue": "BackendV2Converter fails to wrap Aer simulator\n### Environment\n\n- **Qiskit Terra version**: 8ec6749\r\n- **Qiskit Aer version**: 0.11.2\r\n- **Python version**: 3.10.9\r\n- **Operating system**: Arch Linux\r\n\n\n### What is happening?\n\nSee title.\n\n### How can we reproduce the issue?\n\n```python\r\nfrom qiskit import Aer\r\nfrom qiskit.providers import BackendV2Converter\r\nbackend = BackendV2Converter(Aer.get_backend('aer_simulator'))\r\n```\r\n\r\n```\r\nKeyError                                  Traceback (most recent call last)\r\n~/projects/qiskit-terra/qiskit/providers/models/backendconfiguration.py in __getattr__(self, name)\r\n    383         try:\r\n--> 384             return self._data[name]\r\n    385         except KeyError as ex:\r\n\r\nKeyError: 'online_date'\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nAttributeError                            Traceback (most recent call last)\r\n<ipython-input-1-38c84b7d22f9> in <module>\r\n      1 from qiskit import Aer\r\n      2 from qiskit.providers import BackendV2Converter\r\n----> 3 backend = BackendV2Converter(Aer.get_backend('aer_simulator'))\r\n\r\n~/projects/qiskit-terra/qiskit/providers/backend_compat.py in __init__(self, backend, name_mapping, add_delay)\r\n    221             name=backend.name(),\r\n    222             description=self._config.description,\r\n--> 223             online_date=self._config.online_date,\r\n    224             backend_version=self._config.backend_version,\r\n    225         )\r\n\r\n~/projects/qiskit-terra/qiskit/providers/models/backendconfiguration.py in __getattr__(self, name)\r\n    384             return self._data[name]\r\n    385         except KeyError as ex:\r\n--> 386             raise AttributeError(f\"Attribute {name} is not defined\") from ex\r\n    387 \r\n    388     @classmethod\r\n\r\nAttributeError: Attribute online_date is not defined\r\n```\n\n### What should happen?\n\nIt should work.\n\n### Any suggestions?\n\nFrom @mtreinish :\r\n>The converter is meant to be general but we never tested it with aer and I guess it misses that the online date field is optional\n", "before_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Backend abstract interface for providers.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import List, Iterable, Any, Dict, Optional\n\nfrom qiskit.exceptions import QiskitError\n\nfrom qiskit.providers.backend import BackendV1, BackendV2\nfrom qiskit.providers.backend import QubitProperties\nfrom qiskit.utils.units import apply_prefix\nfrom qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping\nfrom qiskit.circuit.measure import Measure\nfrom qiskit.providers.models.backendconfiguration import BackendConfiguration\nfrom qiskit.providers.models.backendproperties import BackendProperties\nfrom qiskit.providers.models.pulsedefaults import PulseDefaults\nfrom qiskit.providers.options import Options\nfrom qiskit.providers.exceptions import BackendPropertyError\n\n\ndef convert_to_target(\n    configuration: BackendConfiguration,\n    properties: BackendProperties = None,\n    defaults: PulseDefaults = None,\n    custom_name_mapping: Optional[Dict[str, Any]] = None,\n    add_delay: bool = False,\n):\n    \"\"\"Uses configuration, properties and pulse defaults\n    to construct and return Target class.\n    \"\"\"\n    # pylint: disable=cyclic-import\n    from qiskit.transpiler.target import (\n        Target,\n        InstructionProperties,\n    )\n\n    # Standard gates library mapping, multicontrolled gates not included since they're\n    # variable width\n    name_mapping = get_standard_gate_name_mapping()\n    target = None\n    if custom_name_mapping is not None:\n        name_mapping.update(custom_name_mapping)\n    # Parse from properties if it exsits\n    if properties is not None:\n        qubit_properties = qubit_props_list_from_props(properties=properties)\n        target = Target(num_qubits=configuration.n_qubits, qubit_properties=qubit_properties)\n        # Parse instructions\n        gates: Dict[str, Any] = {}\n        for gate in properties.gates:\n            name = gate.gate\n            if name in name_mapping:\n                if name not in gates:\n                    gates[name] = {}\n            else:\n                raise QiskitError(\n                    f\"Operation name {name} does not have a known mapping. Use \"\n                    \"custom_name_mapping to map this name to an Operation object\"\n                )\n\n            qubits = tuple(gate.qubits)\n            gate_props = {}\n            for param in gate.parameters:\n                if param.name == \"gate_error\":\n                    gate_props[\"error\"] = param.value\n                if param.name == \"gate_length\":\n                    gate_props[\"duration\"] = apply_prefix(param.value, param.unit)\n            gates[name][qubits] = InstructionProperties(**gate_props)\n        for gate, props in gates.items():\n            inst = name_mapping[gate]\n            target.add_instruction(inst, props)\n        # Create measurement instructions:\n        measure_props = {}\n        for qubit, _ in enumerate(properties.qubits):\n            measure_props[(qubit,)] = InstructionProperties(\n                duration=properties.readout_length(qubit),\n                error=properties.readout_error(qubit),\n            )\n        target.add_instruction(Measure(), measure_props)\n    # Parse from configuration because properties doesn't exist\n    else:\n        target = Target(num_qubits=configuration.n_qubits)\n        for gate in configuration.gates:\n            name = gate.name\n            gate_props = (\n                {tuple(x): None for x in gate.coupling_map}  # type: ignore[misc]\n                if hasattr(gate, \"coupling_map\")\n                else {None: None}\n            )\n            if name in name_mapping:\n                target.add_instruction(name_mapping[name], gate_props)\n            else:\n                raise QiskitError(\n                    f\"Operation name {name} does not have a known mapping. \"\n                    \"Use custom_name_mapping to map this name to an Operation object\"\n                )\n        target.add_instruction(Measure())\n    # parse global configuration properties\n    if hasattr(configuration, \"dt\"):\n        target.dt = configuration.dt\n    if hasattr(configuration, \"timing_constraints\"):\n        target.granularity = configuration.timing_constraints.get(\"granularity\")\n        target.min_length = configuration.timing_constraints.get(\"min_length\")\n        target.pulse_alignment = configuration.timing_constraints.get(\"pulse_alignment\")\n        target.aquire_alignment = configuration.timing_constraints.get(\"acquire_alignment\")\n    # If a pulse defaults exists use that as the source of truth\n    if defaults is not None:\n        inst_map = defaults.instruction_schedule_map\n        for inst in inst_map.instructions:\n            for qarg in inst_map.qubits_with_instruction(inst):\n                try:\n                    qargs = tuple(qarg)\n                except TypeError:\n                    qargs = (qarg,)\n                # Do NOT call .get method. This parses Qpbj immediately.\n                # This operation is computationally expensive and should be bypassed.\n                calibration_entry = inst_map._get_calibration_entry(inst, qargs)\n                if inst in target:\n                    if inst == \"measure\":\n                        for qubit in qargs:\n                            target[inst][(qubit,)].calibration = calibration_entry\n                    elif qargs in target[inst]:\n                        target[inst][qargs].calibration = calibration_entry\n    combined_global_ops = set()\n    if configuration.basis_gates:\n        combined_global_ops.update(configuration.basis_gates)\n    for op in combined_global_ops:\n        if op not in target:\n            if op in name_mapping:\n                target.add_instruction(\n                    name_mapping[op], {(bit,): None for bit in range(target.num_qubits)}\n                )\n            else:\n                raise QiskitError(\n                    f\"Operation name '{op}' does not have a known mapping. Use \"\n                    \"custom_name_mapping to map this name to an Operation object\"\n                )\n    if add_delay and \"delay\" not in target:\n        target.add_instruction(\n            name_mapping[\"delay\"], {(bit,): None for bit in range(target.num_qubits)}\n        )\n    return target\n\n\ndef qubit_props_list_from_props(\n    properties: BackendProperties,\n) -> List[QubitProperties]:\n    \"\"\"Uses BackendProperties to construct\n    and return a list of QubitProperties.\n    \"\"\"\n    qubit_props: List[QubitProperties] = []\n    for qubit, _ in enumerate(properties.qubits):\n        try:\n            t_1 = properties.t1(qubit)\n        except BackendPropertyError:\n            t_1 = None\n        try:\n            t_2 = properties.t2(qubit)\n        except BackendPropertyError:\n            t_2 = None\n        try:\n            frequency = properties.frequency(qubit)\n        except BackendPropertyError:\n            frequency = None\n        qubit_props.append(\n            QubitProperties(  # type: ignore[no-untyped-call]\n                t1=t_1,\n                t2=t_2,\n                frequency=frequency,\n            )\n        )\n    return qubit_props\n\n\nclass BackendV2Converter(BackendV2):\n    \"\"\"A converter class that takes a :class:`~.BackendV1` instance and wraps it in a\n    :class:`~.BackendV2` interface.\n\n    This class implements the :class:`~.BackendV2` interface and is used to enable\n    common access patterns between :class:`~.BackendV1` and :class:`~.BackendV2`. This\n    class should only be used if you need a :class:`~.BackendV2` and still need\n    compatibility with :class:`~.BackendV1`.\n    \"\"\"\n\n    def __init__(\n        self,\n        backend: BackendV1,\n        name_mapping: Optional[Dict[str, Any]] = None,\n        add_delay: bool = False,\n    ):\n        \"\"\"Initialize a BackendV2 converter instance based on a BackendV1 instance.\n\n        Args:\n            backend: The input :class:`~.BackendV1` based backend to wrap in a\n                :class:`~.BackendV2` interface\n            name_mapping: An optional dictionary that maps custom gate/operation names in\n                ``backend`` to an :class:`~.Operation` object representing that\n                gate/operation. By default most standard gates names are mapped to the\n                standard gate object from :mod:`qiskit.circuit.library` this only needs\n                to be specified if the input ``backend`` defines gates in names outside\n                that set.\n            add_delay: If set to true a :class:`~qiskit.circuit.Delay` operation\n                will be added to the target as a supported operation for all\n                qubits\n        \"\"\"\n        self._backend = backend\n        self._config = self._backend.configuration()\n        super().__init__(\n            provider=backend.provider,\n            name=backend.name(),\n            description=self._config.description,\n            online_date=self._config.online_date,\n            backend_version=self._config.backend_version,\n        )\n        self._options = self._backend._options\n        self._properties = None\n        if hasattr(self._backend, \"properties\"):\n            self._properties = self._backend.properties()\n        self._defaults = None\n        self._target = None\n        self._name_mapping = name_mapping\n        self._add_delay = add_delay\n\n    @property\n    def target(self):\n        \"\"\"A :class:`qiskit.transpiler.Target` object for the backend.\n\n        :rtype: Target\n        \"\"\"\n        if self._target is None:\n            if self._defaults is None and hasattr(self._backend, \"defaults\"):\n                self._defaults = self._backend.defaults()\n            if self._properties is None and hasattr(self._backend, \"properties\"):\n                self._properties = self._backend.properties()\n            self._target = convert_to_target(\n                self._config,\n                self._properties,\n                self._defaults,\n                custom_name_mapping=self._name_mapping,\n                add_delay=self._add_delay,\n            )\n        return self._target\n\n    @property\n    def max_circuits(self):\n        return self._config.max_experiments\n\n    @classmethod\n    def _default_options(cls):\n        return Options()\n\n    @property\n    def dtm(self) -> float:\n        return self._config.dtm\n\n    @property\n    def meas_map(self) -> List[List[int]]:\n        return self._config.meas_map\n\n    def drive_channel(self, qubit: int):\n        return self._config.drive(qubit)\n\n    def measure_channel(self, qubit: int):\n        return self._config.measure(qubit)\n\n    def acquire_channel(self, qubit: int):\n        return self._config.acquire(qubit)\n\n    def control_channel(self, qubits: Iterable[int]):\n        return self._config.control(qubits)\n\n    def run(self, run_input, **options):\n        return self._backend.run(run_input, **options)\n", "path": "qiskit/providers/backend_compat.py"}], "after_files": [{"content": "# This code is part of Qiskit.\n#\n# (C) Copyright IBM 2020.\n#\n# This code is licensed under the Apache License, Version 2.0. You may\n# obtain a copy of this license in the LICENSE.txt file in the root directory\n# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.\n#\n# Any modifications or derivative works of this code must retain this\n# copyright notice, and modified files need to carry a notice indicating\n# that they have been altered from the originals.\n\n\"\"\"Backend abstract interface for providers.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import List, Iterable, Any, Dict, Optional\n\nfrom qiskit.exceptions import QiskitError\n\nfrom qiskit.providers.backend import BackendV1, BackendV2\nfrom qiskit.providers.backend import QubitProperties\nfrom qiskit.utils.units import apply_prefix\nfrom qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping\nfrom qiskit.circuit.measure import Measure\nfrom qiskit.providers.models.backendconfiguration import BackendConfiguration\nfrom qiskit.providers.models.backendproperties import BackendProperties\nfrom qiskit.providers.models.pulsedefaults import PulseDefaults\nfrom qiskit.providers.options import Options\nfrom qiskit.providers.exceptions import BackendPropertyError\n\n\ndef convert_to_target(\n    configuration: BackendConfiguration,\n    properties: BackendProperties = None,\n    defaults: PulseDefaults = None,\n    custom_name_mapping: Optional[Dict[str, Any]] = None,\n    add_delay: bool = False,\n):\n    \"\"\"Uses configuration, properties and pulse defaults\n    to construct and return Target class.\n    \"\"\"\n    # pylint: disable=cyclic-import\n    from qiskit.transpiler.target import (\n        Target,\n        InstructionProperties,\n    )\n\n    # Standard gates library mapping, multicontrolled gates not included since they're\n    # variable width\n    name_mapping = get_standard_gate_name_mapping()\n    target = None\n    if custom_name_mapping is not None:\n        name_mapping.update(custom_name_mapping)\n    # Parse from properties if it exsits\n    if properties is not None:\n        qubit_properties = qubit_props_list_from_props(properties=properties)\n        target = Target(num_qubits=configuration.n_qubits, qubit_properties=qubit_properties)\n        # Parse instructions\n        gates: Dict[str, Any] = {}\n        for gate in properties.gates:\n            name = gate.gate\n            if name in name_mapping:\n                if name not in gates:\n                    gates[name] = {}\n            else:\n                raise QiskitError(\n                    f\"Operation name {name} does not have a known mapping. Use \"\n                    \"custom_name_mapping to map this name to an Operation object\"\n                )\n\n            qubits = tuple(gate.qubits)\n            gate_props = {}\n            for param in gate.parameters:\n                if param.name == \"gate_error\":\n                    gate_props[\"error\"] = param.value\n                if param.name == \"gate_length\":\n                    gate_props[\"duration\"] = apply_prefix(param.value, param.unit)\n            gates[name][qubits] = InstructionProperties(**gate_props)\n        for gate, props in gates.items():\n            inst = name_mapping[gate]\n            target.add_instruction(inst, props)\n        # Create measurement instructions:\n        measure_props = {}\n        for qubit, _ in enumerate(properties.qubits):\n            measure_props[(qubit,)] = InstructionProperties(\n                duration=properties.readout_length(qubit),\n                error=properties.readout_error(qubit),\n            )\n        target.add_instruction(Measure(), measure_props)\n    # Parse from configuration because properties doesn't exist\n    else:\n        target = Target(num_qubits=configuration.n_qubits)\n        for gate in configuration.gates:\n            name = gate.name\n            gate_props = (\n                {tuple(x): None for x in gate.coupling_map}  # type: ignore[misc]\n                if hasattr(gate, \"coupling_map\")\n                else {None: None}\n            )\n            if name in name_mapping:\n                target.add_instruction(name_mapping[name], gate_props)\n            else:\n                raise QiskitError(\n                    f\"Operation name {name} does not have a known mapping. \"\n                    \"Use custom_name_mapping to map this name to an Operation object\"\n                )\n        target.add_instruction(Measure())\n    # parse global configuration properties\n    if hasattr(configuration, \"dt\"):\n        target.dt = configuration.dt\n    if hasattr(configuration, \"timing_constraints\"):\n        target.granularity = configuration.timing_constraints.get(\"granularity\")\n        target.min_length = configuration.timing_constraints.get(\"min_length\")\n        target.pulse_alignment = configuration.timing_constraints.get(\"pulse_alignment\")\n        target.aquire_alignment = configuration.timing_constraints.get(\"acquire_alignment\")\n    # If a pulse defaults exists use that as the source of truth\n    if defaults is not None:\n        inst_map = defaults.instruction_schedule_map\n        for inst in inst_map.instructions:\n            for qarg in inst_map.qubits_with_instruction(inst):\n                try:\n                    qargs = tuple(qarg)\n                except TypeError:\n                    qargs = (qarg,)\n                # Do NOT call .get method. This parses Qpbj immediately.\n                # This operation is computationally expensive and should be bypassed.\n                calibration_entry = inst_map._get_calibration_entry(inst, qargs)\n                if inst in target:\n                    if inst == \"measure\":\n                        for qubit in qargs:\n                            target[inst][(qubit,)].calibration = calibration_entry\n                    elif qargs in target[inst]:\n                        target[inst][qargs].calibration = calibration_entry\n    combined_global_ops = set()\n    if configuration.basis_gates:\n        combined_global_ops.update(configuration.basis_gates)\n    for op in combined_global_ops:\n        if op not in target:\n            if op in name_mapping:\n                target.add_instruction(name_mapping[op], name=op)\n            else:\n                raise QiskitError(\n                    f\"Operation name '{op}' does not have a known mapping. Use \"\n                    \"custom_name_mapping to map this name to an Operation object\"\n                )\n    if add_delay and \"delay\" not in target:\n        target.add_instruction(\n            name_mapping[\"delay\"], {(bit,): None for bit in range(target.num_qubits)}\n        )\n    return target\n\n\ndef qubit_props_list_from_props(\n    properties: BackendProperties,\n) -> List[QubitProperties]:\n    \"\"\"Uses BackendProperties to construct\n    and return a list of QubitProperties.\n    \"\"\"\n    qubit_props: List[QubitProperties] = []\n    for qubit, _ in enumerate(properties.qubits):\n        try:\n            t_1 = properties.t1(qubit)\n        except BackendPropertyError:\n            t_1 = None\n        try:\n            t_2 = properties.t2(qubit)\n        except BackendPropertyError:\n            t_2 = None\n        try:\n            frequency = properties.frequency(qubit)\n        except BackendPropertyError:\n            frequency = None\n        qubit_props.append(\n            QubitProperties(  # type: ignore[no-untyped-call]\n                t1=t_1,\n                t2=t_2,\n                frequency=frequency,\n            )\n        )\n    return qubit_props\n\n\nclass BackendV2Converter(BackendV2):\n    \"\"\"A converter class that takes a :class:`~.BackendV1` instance and wraps it in a\n    :class:`~.BackendV2` interface.\n\n    This class implements the :class:`~.BackendV2` interface and is used to enable\n    common access patterns between :class:`~.BackendV1` and :class:`~.BackendV2`. This\n    class should only be used if you need a :class:`~.BackendV2` and still need\n    compatibility with :class:`~.BackendV1`.\n    \"\"\"\n\n    def __init__(\n        self,\n        backend: BackendV1,\n        name_mapping: Optional[Dict[str, Any]] = None,\n        add_delay: bool = False,\n    ):\n        \"\"\"Initialize a BackendV2 converter instance based on a BackendV1 instance.\n\n        Args:\n            backend: The input :class:`~.BackendV1` based backend to wrap in a\n                :class:`~.BackendV2` interface\n            name_mapping: An optional dictionary that maps custom gate/operation names in\n                ``backend`` to an :class:`~.Operation` object representing that\n                gate/operation. By default most standard gates names are mapped to the\n                standard gate object from :mod:`qiskit.circuit.library` this only needs\n                to be specified if the input ``backend`` defines gates in names outside\n                that set.\n            add_delay: If set to true a :class:`~qiskit.circuit.Delay` operation\n                will be added to the target as a supported operation for all\n                qubits\n        \"\"\"\n        self._backend = backend\n        self._config = self._backend.configuration()\n        super().__init__(\n            provider=backend.provider,\n            name=backend.name(),\n            description=self._config.description,\n            online_date=getattr(self._config, \"online_date\", None),\n            backend_version=self._config.backend_version,\n        )\n        self._options = self._backend._options\n        self._properties = None\n        if hasattr(self._backend, \"properties\"):\n            self._properties = self._backend.properties()\n        self._defaults = None\n        self._target = None\n        self._name_mapping = name_mapping\n        self._add_delay = add_delay\n\n    @property\n    def target(self):\n        \"\"\"A :class:`qiskit.transpiler.Target` object for the backend.\n\n        :rtype: Target\n        \"\"\"\n        if self._target is None:\n            if self._defaults is None and hasattr(self._backend, \"defaults\"):\n                self._defaults = self._backend.defaults()\n            if self._properties is None and hasattr(self._backend, \"properties\"):\n                self._properties = self._backend.properties()\n            self._target = convert_to_target(\n                self._config,\n                self._properties,\n                self._defaults,\n                custom_name_mapping=self._name_mapping,\n                add_delay=self._add_delay,\n            )\n        return self._target\n\n    @property\n    def max_circuits(self):\n        return self._config.max_experiments\n\n    @classmethod\n    def _default_options(cls):\n        return Options()\n\n    @property\n    def dtm(self) -> float:\n        return self._config.dtm\n\n    @property\n    def meas_map(self) -> List[List[int]]:\n        return self._config.meas_map\n\n    def drive_channel(self, qubit: int):\n        return self._config.drive(qubit)\n\n    def measure_channel(self, qubit: int):\n        return self._config.measure(qubit)\n\n    def acquire_channel(self, qubit: int):\n        return self._config.acquire(qubit)\n\n    def control_channel(self, qubits: Iterable[int]):\n        return self._config.control(qubits)\n\n    def run(self, run_input, **options):\n        return self._backend.run(run_input, **options)\n", "path": "qiskit/providers/backend_compat.py"}]}