Repository: Qiskit/qiskit

Issue:
Cannot apply dynamical decoupling on a circuit with parameterized global phase
### Environment

- **Qiskit Terra version**: 0.25 
- **Python version**: 3.11
- **Operating system**: Windows


### What is happening?

Dynamical decoupling cannot be applied on a circuit with a parameterized global phase, due to a failing `_mod_2pi` wrapping 

### How can we reproduce the issue?

```python
from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDynamicalDecoupling
from qiskit.transpiler import PassManager, InstructionDurations
from qiskit.circuit.library import XGate
from qiskit.circuit import Parameter
durations = InstructionDurations.from_backend(backend)

qc = QuantumCircuit(1,1)
qc.sx(0)
qc.delay(1600, 0)
qc.sx(0)
qc.global_phase=Parameter('a')

pm = PassManager([ALAPScheduleAnalysis(durations), PadDynamicalDecoupling(durations, [XGate(), XGate()])])
pm.run(qc)
```

errors in
https://github.com/Qiskit/qiskit-terra/blob/c29e938c2ba1c359a0a3268679c68f3237b2c1b7/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py#L260
with:
`TypeError: unsupported operand type(s) for %: 'ParameterExpression' and 'float'`

### What should happen?

Run the DD transpiler pass successfully

### Any suggestions?

Don't wrap global phase if parameterized, see same issue in https://github.com/Qiskit/qiskit-ibm-provider/pull/689


Discussion:
Thanks for reporting this. I'm labelling this as good first issue as it can be solved analogously to the referenced PR, https://github.com/Qiskit/qiskit-ibm-provider/pull/689. 
@Cryoris Please assign this issue to me.

Resolving patch:
diff --git a/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py
--- a/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py
+++ b/qiskit/transpiler/passes/scheduling/dynamical_decoupling.py
@@ -274,7 +274,7 @@ def run(self, dag):
                 if gate is not None:
                     new_dag.apply_operation_back(gate, [dag_qubit], check=False)
 
-            new_dag.global_phase = _mod_2pi(new_dag.global_phase + sequence_gphase)
+            new_dag.global_phase = new_dag.global_phase + sequence_gphase
 
         return new_dag
 
@@ -283,11 +283,3 @@ def __gate_supported(self, gate: Gate, qarg: int) -> bool:
         if self._target is None or self._target.instruction_supported(gate.name, qargs=(qarg,)):
             return True
         return False
-
-
-def _mod_2pi(angle: float, atol: float = 0):
-    """Wrap angle into interval [-π,π). If within atol of the endpoint, clamp to -π"""
-    wrapped = (angle + np.pi) % (2 * np.pi) - np.pi
-    if abs(wrapped - np.pi) < atol:
-        wrapped = -np.pi
-    return wrapped
diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py
--- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py
+++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py
@@ -394,8 +394,7 @@ def _constrained_length(values):
                 gate_length = self._dd_sequence_lengths[qubit][dd_ind]
                 self._apply_scheduled_op(dag, idle_after, gate, qubit)
                 idle_after += gate_length
-
-        dag.global_phase = self._mod_2pi(dag.global_phase + sequence_gphase)
+        dag.global_phase = dag.global_phase + sequence_gphase
 
     @staticmethod
     def _resolve_params(gate: Gate) -> tuple:
@@ -407,11 +406,3 @@ def _resolve_params(gate: Gate) -> tuple:
             else:
                 params.append(p)
         return tuple(params)
-
-    @staticmethod
-    def _mod_2pi(angle: float, atol: float = 0):
-        """Wrap angle into interval [-π,π). If within atol of the endpoint, clamp to -π"""
-        wrapped = (angle + np.pi) % (2 * np.pi) - np.pi
-        if abs(wrapped - np.pi) < atol:
-            wrapped = -np.pi
-        return wrapped


Test patch:
diff --git a/test/python/transpiler/test_dynamical_decoupling.py b/test/python/transpiler/test_dynamical_decoupling.py
--- a/test/python/transpiler/test_dynamical_decoupling.py
+++ b/test/python/transpiler/test_dynamical_decoupling.py
@@ -1031,6 +1031,25 @@ def test_respect_target_instruction_constraints(self):
         expected.delay(200, [0])
         self.assertEqual(expected, scheduled)
 
+    def test_paramaterized_global_phase(self):
+        """Test paramaterized global phase in DD circuit.
+        See:https://github.com/Qiskit/qiskit-terra/issues/10569
+        """
+        dd_sequence = [XGate(), YGate()] * 2
+        qc = QuantumCircuit(1, 1)
+        qc.h(0)
+        qc.delay(1700, 0)
+        qc.y(0)
+        qc.global_phase = Parameter("a")
+        pm = PassManager(
+            [
+                ALAPScheduleAnalysis(self.durations),
+                PadDynamicalDecoupling(self.durations, dd_sequence),
+            ]
+        )
+
+        self.assertEqual(qc.global_phase + np.pi, pm.run(qc).global_phase)
+
 
 if __name__ == "__main__":
     unittest.main()