Repository: Qiskit/qiskit

Issue:
DAGCircuit.compose is not updating the "calibrations" attribute

### Information

- **Qiskit Terra version**: `master` branch (commit 0cb8f58444781986f052c14260ba4263cede40fe)
- **Python version**: any
- **Operating system**: any

### What is the current behavior?

The `DAGCircuit.compose` method is not updating the `DAGCircuit.calibrations` attribute.

### Steps to reproduce the problem

The following code snippet replicates the issue:

```py
from qiskit.converters import circuit_to_dag, dag_to_circuit
from qiskit.pulse import Schedule
from qiskit import QuantumCircuit
from qiskit.circuit.gate import Gate

empty_circuit = QuantumCircuit(1)

dummy_gate = Gate("my_dummy_gate", 1, [])
circuit_with_calibrated_pulse_definition = QuantumCircuit(1)
circuit_with_calibrated_pulse_definition.append(dummy_gate, qargs=[0])
circuit_with_calibrated_pulse_definition.add_calibration(dummy_gate, [0], Schedule())

empty_dag = circuit_to_dag(empty_circuit)
calibrated_dag = circuit_to_dag(circuit_with_calibrated_pulse_definition)
composed_dag = empty_dag.compose(calibrated_dag, inplace=False)

print("Empty DAG:     ", empty_dag.calibrations)
print("Calibrated DAG:", calibrated_dag.calibrations)
print("Composed DAG:  ", composed_dag.calibrations) # Should be the same as calibrated_dag
```

with output:

```
Empty DAG:      {}
Calibrated DAG: {'my_dummy_gate': {((0,), ()): Schedule(, name="sched383")}}
Composed DAG:   {}
```
### What is the expected behavior?

The `calibrations` attribute should be updated in `DAGCircuit.compose`, just like it is updated in `QuantumCircuit.compose`: [code here](https://github.com/Qiskit/qiskit-terra/blob/0cb8f58444781986f052c14260ba4263cede40fe/qiskit/circuit/quantumcircuit.py#L752)

### Suggested solutions

Copy-paste the code used for `QuantumCircuit.compose` ([here](https://github.com/Qiskit/qiskit-terra/blob/0cb8f58444781986f052c14260ba4263cede40fe/qiskit/circuit/quantumcircuit.py#L752)) to `DAGCircuit.compose`.



Discussion:

Resolving patch:
diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py
--- a/qiskit/dagcircuit/dagcircuit.py
+++ b/qiskit/dagcircuit/dagcircuit.py
@@ -695,6 +695,9 @@ def compose(self, other, edge_map=None, qubits=None, clbits=None, front=False, i
             dag = copy.deepcopy(self)
         dag.global_phase += other.global_phase
 
+        for gate, cals in other.calibrations.items():
+            dag._calibrations[gate].update(cals)
+
         for nd in other.topological_nodes():
             if nd.type == "in":
                 # if in edge_map, get new name, else use existing name


Test patch:
diff --git a/test/python/dagcircuit/test_compose.py b/test/python/dagcircuit/test_compose.py
--- a/test/python/dagcircuit/test_compose.py
+++ b/test/python/dagcircuit/test_compose.py
@@ -18,6 +18,8 @@
 from qiskit.converters import circuit_to_dag, dag_to_circuit
 from qiskit.dagcircuit.exceptions import DAGCircuitError
 from qiskit.test import QiskitTestCase
+from qiskit.pulse import Schedule
+from qiskit.circuit.gate import Gate
 
 
 class TestDagCompose(QiskitTestCase):
@@ -439,6 +441,20 @@ def test_compose_raises_if_splitting_condition_creg(self):
         with self.assertRaisesRegex(DAGCircuitError, 'more than one creg'):
             circuit_left.compose(circuit_right)
 
+    def test_compose_calibrations(self):
+        """Test that compose carries over the calibrations."""
+        dag_cal = QuantumCircuit(1)
+        dag_cal.append(Gate('', 1, []), qargs=[0])
+        dag_cal.add_calibration(Gate('', 1, []), [0], Schedule())
+
+        empty_dag = circuit_to_dag(QuantumCircuit(1))
+        calibrated_dag = circuit_to_dag(dag_cal)
+        composed_dag = empty_dag.compose(calibrated_dag, inplace=False)
+
+        cal = {'': {((0,), ()): Schedule(name="sched0")}}
+        self.assertEqual(composed_dag.calibrations, cal)
+        self.assertEqual(calibrated_dag.calibrations, cal)
+
 
 if __name__ == '__main__':
     unittest.main()