Task: Allow dynamical decoupling pass to work on circuits with pulse gates  (Qiskit/qiskit#10834)

org: Qiskit
repo: qiskit
pr_number: 10834
issue_title: Allow dynamical decoupling pass to work on circuits with pulse gates 
issue_body: ### Summary\r\n\r\nAllow dynamical decoupling pass to work on circuits with pulse gates \r\n\r\n### Details and comments\r\n\r\nThe pass was accessing the circuit calibrations incorrectly, resulting in\r\nan error when one of the gates in the dynamical decoupling sequence had\r\na pulse gate calibration.\r\n\r\nCloses #10833
resolved_issues: number: 10833
title: Dynamical decoupling fails when a gate in the decoupling sequence has a calibration attached to the circuit
body: ### Environment\n\n- **Qiskit Terra version**: 0.25.1\r\n- **Python version**: 3.10\r\n- **Operating system**: Fedora Linux\r\n\n\n### What is happening?\n\n`PadDynamicalDecoupling` raises `TypeError: unhashable type: 'list'` when run on a circuit with a calibration for one of the gates in the decoupling sequence.\n\n### How can we reproduce the issue?\n\n```python\r\nfrom qiskit_ibm_provider import IBMProvider\r\n\r\n\r\nprovider = IBMProvider()\r\nbackend = provider.get_backend("ibm_nazca")\r\n\r\n\r\nimport numpy as np\r\n\r\nfrom qiskit import pulse, QuantumCircuit\r\nfrom qiskit.transpiler import PassManager\r\nfrom qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDynamicalDecoupling\r\nfrom qiskit.circuit.library import XGate, YGate\r\nfrom qiskit.pulse import DriveChannel\r\n\r\n\r\ninst_sched_map = backend.instruction_schedule_map\r\n\r\n\r\ncirc = QuantumCircuit(1, 1)\r\ncirc.x(0)\r\ncirc.delay(1600, 0)\r\ncirc.x(0)\r\n\r\nfor qubit in range(backend.configuration().n_qubits):\r\n    with pulse.build(f"y gate for qubit {qubit}") as sched:\r\n        with pulse.phase_offset(np.pi / 2, DriveChannel(qubit)):\r\n            x_sched = inst_sched_map.get("x", qubits=[qubit])\r\n            pulse.call(x_sched)\r\n        circ.add_calibration("y", [qubit], sched)\r\n\r\ndd_sequence = [XGate(), YGate()]*4\r\ndurations = backend.target.durations()\r\n\r\npm = PassManager(\r\n        [\r\n            ALAPScheduleAnalysis(durations),\r\n            PadDynamicalDecoupling(\r\n                durations,\r\n                dd_sequence,\r\n                pulse_alignment=backend.configuration().timing_constraints[\r\n                    "pulse_alignment"\r\n                ],\r\n            ),\r\n        ]\r\n    )\r\n\r\npm.run(circ)\r\n```\n\n### What should happen?\n\nThe duration of the gate calibration should be used to schedule the decoupling sequence.\n\n### Any suggestions?\n\nA PR with a fix will be opened shortly.

Reference solution:
fix_patch: diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py\nindex bbb1b39bbd72..fb33361a4959 100644\n--- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py\n+++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py\n@@ -16,7 +16,7 @@\n import logging\n import numpy as np\n \n-from qiskit.circuit import Qubit, Gate\n+from qiskit.circuit import Gate, ParameterExpression, Qubit\n from qiskit.circuit.delay import Delay\n from qiskit.circuit.library.standard_gates import IGate, UGate, U3Gate\n from qiskit.circuit.reset import Reset\n@@ -227,7 +227,8 @@ def _pre_runhook(self, dag: DAGCircuit):\n             for gate in self._dd_sequence:\n                 try:\n                     # Check calibration.\n-                    gate_length = dag.calibrations[gate.name][(physical_index, gate.params)]\n+                    params = self._resolve_params(gate)\n+                    gate_length = dag.calibrations[gate.name][((physical_index,), params)].duration\n                     if gate_length % self._alignment != 0:\n                         # This is necessary to implement lightweight scheduling logic for this pass.\n                         # Usually the pulse alignment constraint and pulse data chunk size take\n@@ -394,6 +395,17 @@ def _constrained_length(values):\n \n         dag.global_phase = self._mod_2pi(dag.global_phase + sequence_gphase)\n \n+    @staticmethod\n+    def _resolve_params(gate: Gate) -> tuple:\n+        """Return gate params with any bound parameters replaced with floats"""\n+        params = []\n+        for p in gate.params:\n+            if isinstance(p, ParameterExpression) and not p.parameters:\n+                params.append(float(p))\n+            else:\n+                params.append(p)\n+        return tuple(params)\n+\n     @staticmethod\n     def _mod_2pi(angle: float, atol: float = 0):\n         """Wrap angle into interval [-π,π). If within atol of the endpoint, clamp to -π"""\ndiff --git a/releasenotes/notes/dd-pg-10833-ddddee68ffd913c4.yaml b/releasenotes/notes/dd-pg-10833-ddddee68ffd913c4.yaml\nnew file mode 100644\nindex 000000000000..cdf23b9ef9a3\n--- /dev/null\n+++ b/releasenotes/notes/dd-pg-10833-ddddee68ffd913c4.yaml\n@@ -0,0 +1,7 @@\n+---\n+fixes:\n+  - |\n+    Fixed a bug in the :class:`.PadDynamicalDecoupling` transpiler pass which\n+    would cause the pass to fail if a circuit contained a pulse gate\n+    calibration for one of the gates in the decoupling sequence. Fixed `#10833\n+    <https://github.com/Qiskit/qiskit/issues/10833>`_.\n