Repository: qiboteam/qibolab

Issue:
Add native pulse to generate state 2 to platform
In order to efficiently calibrate two qubit gates we will need to be able to generate and classify also the state $\ket{2}$.
See for example qiboteam/qibocal#477 and qiboteam/qibocal#466.
I'm currently working on something in qibocal to calibrate this pulse.
I guess that the simplest solution would be to add also a native pulse for the this state, right?
For a quick summary on how to calibrate this pulse you can have a look here
https://learn.qiskit.org/course/quantum-hardware-pulses/accessing-higher-energy-states-with-qiskit-pulse

Let me know what you think @stavros11 @AleCandido @igres26 @aorgazf @scarrazza 

Discussion:

Patch:
diff --git a/src/qibolab/dummy.py b/src/qibolab/dummy.py
index ac71031b..cf6cab15 100644
--- a/src/qibolab/dummy.py
+++ b/src/qibolab/dummy.py
@@ -27,6 +27,15 @@ RUNCARD = {
                     "start": 0,
                     "phase": 0,
                 },
+                "RX12": {
+                    "duration": 40,
+                    "amplitude": 0.005,
+                    "frequency": 4700000000,
+                    "shape": "Gaussian(5)",
+                    "type": "qd",
+                    "start": 0,
+                    "phase": 0,
+                },
                 "MZ": {
                     "duration": 1000,
                     "amplitude": 0.0025,
@@ -47,6 +56,15 @@ RUNCARD = {
                     "start": 0,
                     "phase": 0,
                 },
+                "RX12": {
+                    "duration": 40,
+                    "amplitude": 0.0484,
+                    "frequency": 4855663000,
+                    "shape": "Drag(5, -0.02)",
+                    "type": "qd",
+                    "start": 0,
+                    "phase": 0,
+                },
                 "MZ": {
                     "duration": 620,
                     "amplitude": 0.003575,
@@ -67,6 +85,15 @@ RUNCARD = {
                     "start": 0,
                     "phase": 0,
                 },
+                "RX12": {
+                    "duration": 40,
+                    "amplitude": 0.005,
+                    "frequency": 2700000000,
+                    "shape": "Gaussian(5)",
+                    "type": "qd",
+                    "start": 0,
+                    "phase": 0,
+                },
                 "MZ": {
                     "duration": 1000,
                     "amplitude": 0.0025,
@@ -87,6 +114,15 @@ RUNCARD = {
                     "start": 0,
                     "phase": 0,
                 },
+                "RX12": {
+                    "duration": 40,
+                    "amplitude": 0.0484,
+                    "frequency": 5855663000,
+                    "shape": "Drag(5, -0.02)",
+                    "type": "qd",
+                    "start": 0,
+                    "phase": 0,
+                },
                 "MZ": {
                     "duration": 620,
                     "amplitude": 0.003575,
diff --git a/src/qibolab/native.py b/src/qibolab/native.py
index 899c3db7..ed04dfd1 100644
--- a/src/qibolab/native.py
+++ b/src/qibolab/native.py
@@ -188,7 +188,11 @@ class SingleQubitNatives:
     """Container with the native single-qubit gates acting on a specific qubit."""
 
     RX: Optional[NativePulse] = None
+    """Pulse to drive the qubit from state 0 to state 1."""
+    RX12: Optional[NativePulse] = None
+    """Pulse to drive to qubit from state 1 to state 2."""
     MZ: Optional[NativePulse] = None
+    """Measurement pulse."""
 
     @property
     def RX90(self) -> NativePulse:
diff --git a/src/qibolab/platform.py b/src/qibolab/platform.py
index eff7838f..404ba08f 100644
--- a/src/qibolab/platform.py
+++ b/src/qibolab/platform.py
@@ -243,6 +243,10 @@ class Platform:
         qubit = self.get_qubit(qubit)
         return self.qubits[qubit].native_gates.RX.pulse(start, relative_phase)
 
+    def create_RX12_pulse(self, qubit, start=0, relative_phase=0):
+        qubit = self.get_qubit(qubit)
+        return self.qubits[qubit].native_gates.RX12.pulse(start, relative_phase)
+
     def create_CZ_pulse_sequence(self, qubits, start=0):
         # Check in the settings if qubits[0]-qubits[1] is a key
         pair = tuple(sorted(self.get_qubit(q) for q in qubits))


Test patch:
diff --git a/tests/dummy_qrc/qblox.yml b/tests/dummy_qrc/qblox.yml
index f482612e..032b220c 100644
--- a/tests/dummy_qrc/qblox.yml
+++ b/tests/dummy_qrc/qblox.yml
@@ -26,6 +26,15 @@ native_gates:
                 type: qd                    # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.5028
+                frequency: 5_050_304_836
+                # if_frequency: -200_000_000    # difference in qubit frequency
+                shape: Gaussian(5)
+                type: qd
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: 0.1
@@ -45,6 +54,15 @@ native_gates:
                 type: qd
                 relative_start: 0
                 phase: 0                    # qubit drive
+            RX12:
+                duration: 40                  # should be multiple of 4
+                amplitude: 0.5078
+                frequency: 4_852_833_073    # qubit frequency
+                # if_frequency: -200_000_000    # difference in qubit frequency
+                shape: Gaussian(5)
+                type: qd
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: 0.2
@@ -64,6 +82,15 @@ native_gates:
                 type: qd                    # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40                   # should be multiple of 4
+                amplitude: 0.5016
+                frequency: 5_795_371_914   # qubit frequency
+                # if_frequency: -200_000_000    # difference in qubit frequency
+                shape: Gaussian(5)
+                type: qd                    # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: 0.25
@@ -83,6 +110,15 @@ native_gates:
                 type: qd                    # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40                   # should be multiple of 4
+                amplitude: 0.5026
+                frequency: 6_761_018_001    # qubit frequency
+                # if_frequency: -200_000_000    # difference in qubit frequency
+                shape: Gaussian(5)
+                type: qd                    # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: 0.2
@@ -102,6 +138,15 @@ native_gates:
                 type: qd                    # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40                # should be multiple of 4
+                amplitude: 0.5172
+                frequency: 6_586_543_060    # qubit frequency
+                # if_frequency: -200_000_000    # difference in qubit frequency
+                shape: Gaussian(5)
+                type: qd                    # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: 0.4
diff --git a/tests/dummy_qrc/qm.yml b/tests/dummy_qrc/qm.yml
index b96e45d7..cb46e54e 100644
--- a/tests/dummy_qrc/qm.yml
+++ b/tests/dummy_qrc/qm.yml
@@ -41,6 +41,14 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.005
+                frequency: 4_700_000_000
+                shape: Gaussian(5)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 1000
                 amplitude: 0.0025
@@ -59,6 +67,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.0484
+                frequency: 4_855_663_000
+                #frequency: 4_718_515_000 # 02 transition (more likely)
+                shape: Drag(5, -0.02)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 620
                 amplitude: 0.003575
@@ -77,6 +94,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.05682
+                frequency: 5_800_563_000
+                #frequency: 5_661_400_000 # 02 transition
+                shape: Drag(5, -0.04) #Gaussian(5)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 960
                 amplitude: 0.00325
@@ -95,6 +121,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.138
+                frequency: 6_760_922_000
+                #frequency: 6_628_822_000 # 02 transition
+                shape: Gaussian(5)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 960
                 amplitude: 0.004225
@@ -112,6 +147,14 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.0617
+                frequency: 6_585_053_000
+                shape: Drag(5, 0.0) #Gaussian(5)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 640
                 amplitude: 0.0039
diff --git a/tests/dummy_qrc/rfsoc.yml b/tests/dummy_qrc/rfsoc.yml
index 2d179f0c..8a4f5f5e 100644
--- a/tests/dummy_qrc/rfsoc.yml
+++ b/tests/dummy_qrc/rfsoc.yml
@@ -17,6 +17,8 @@ native_gates:
         0:
             RX: {duration: 30, amplitude: 0.05284168507293318, frequency: 5542341844,
                 shape: Rectangular(), type: qd, relative_start: 0, phase: 0}
+            RX12: {duration: 30, amplitude: 0.05284168507293318, frequency: 5542341844,
+                shape: Rectangular(), type: qd, relative_start: 0, phase: 0}
             MZ: {duration: 600, amplitude: 0.03, frequency: 7371258599, shape: Rectangular(),
                 type: ro, relative_start: 0, phase: 0}
     two_qubit: {}
diff --git a/tests/dummy_qrc/zurich.yml b/tests/dummy_qrc/zurich.yml
index e6d6b3b1..3602ca93 100644
--- a/tests/dummy_qrc/zurich.yml
+++ b/tests/dummy_qrc/zurich.yml
@@ -35,6 +35,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40
+                amplitude: 0.625 #0.45
+                frequency: 4_095_830_788 #doesnt do anything requiered for qibolab to work
+                # shape: Gaussian(5)
+                shape: Drag(5, 0.04)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000 #2000.e-9
                 amplitude: .5 # .1
@@ -54,6 +63,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 90 #80
+                amplitude: 0.2 #0.2
+                frequency: 4_170_000_000 #doesnt do anything requiered for qibolab to work
+                shape: Gaussian(5)
+                # shape: Drag(5, 0.04)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 1000
                 amplitude: .1 # 1
@@ -73,6 +91,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 40 #200 #60
+                amplitude: 0.59
+                frequency: 4_300_587_281  #4_401_600_000 #4_505_500_000 #4_321_500_000 # 4_541_100_000 #doesnt do anything requiered for qibolab to work
+                shape: Gaussian(5)
+                # shape: Drag(5, 0.04)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: .54
@@ -92,6 +119,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 90 #80
+                amplitude: 0.75 #0.8
+                frequency: 4_100_000_000 #doesnt do anything requiered for qibolab to work
+                shape: Gaussian(5)
+                # shape: Drag(5, 0.04)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 2000
                 amplitude: .01 # 1
@@ -111,6 +147,15 @@ native_gates:
                 type: qd # qubit drive
                 relative_start: 0
                 phase: 0
+            RX12:
+                duration: 53 #110 #80
+                amplitude: 1 #0.398 #0.8
+                frequency: 4_196_800_000 #Small detuning increase freq #4_248_775_000 #doesnt do anything requiered for qibolab to work
+                shape: Gaussian(5)
+                # shape: Drag(5, 0.04)
+                type: qd # qubit drive
+                relative_start: 0
+                phase: 0
             MZ:
                 duration: 1000
                 amplitude: .5 #.50 # 1
diff --git a/tests/test_dummy.py b/tests/test_dummy.py
index 6bca16a5..eae29065 100644
--- a/tests/test_dummy.py
+++ b/tests/test_dummy.py
@@ -22,6 +22,7 @@ def test_dummy_execute_pulse_sequence(acquisition):
     platform = create_platform("dummy")
     sequence = PulseSequence()
     sequence.add(platform.create_qubit_readout_pulse(0, 0))
+    sequence.add(platform.create_RX12_pulse(0, 0))
     options = ExecutionParameters(nshots=None, acquisition_type=acquisition)
     result = platform.execute_pulse_sequence(sequence, options)