sqdtoolz 0.9.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. sqdtoolz/Drivers/ACQ_ETH_FPGA.py +509 -0
  2. sqdtoolz/Drivers/ACQ_M4i_Digitiser.py +397 -0
  3. sqdtoolz/Drivers/ACQ_TektronixDSA70804B.py +775 -0
  4. sqdtoolz/Drivers/ATTEN_Vaunix.py +106 -0
  5. sqdtoolz/Drivers/AWG5014C.py +296 -0
  6. sqdtoolz/Drivers/Agilent_N8241A.py +1797 -0
  7. sqdtoolz/Drivers/DDG_DG645.py +232 -0
  8. sqdtoolz/Drivers/DSO_DS1054Z.py +426 -0
  9. sqdtoolz/Drivers/Dependencies/Agilent_N8241A_constants_python3.py +794 -0
  10. sqdtoolz/Drivers/Dependencies/PrologixGPIBEthernet.py +65 -0
  11. sqdtoolz/Drivers/Dependencies/RPi_gpio_interface.py +91 -0
  12. sqdtoolz/Drivers/Dependencies/RPi_serial_interface.py +82 -0
  13. sqdtoolz/Drivers/Dependencies/Spectrum/M4i.py +1380 -0
  14. sqdtoolz/Drivers/Dependencies/Spectrum/__init__.py +0 -0
  15. sqdtoolz/Drivers/Dependencies/Spectrum/py_header/__init__.py +0 -0
  16. sqdtoolz/Drivers/Dependencies/Spectrum/py_header/regs.py +2863 -0
  17. sqdtoolz/Drivers/Dependencies/Spectrum/py_header/spcerr.py +81 -0
  18. sqdtoolz/Drivers/Dependencies/Spectrum/pyspcm.py +245 -0
  19. sqdtoolz/Drivers/Dependencies/teproteus.py +977 -0
  20. sqdtoolz/Drivers/Dependencies/tevisainst.py +498 -0
  21. sqdtoolz/Drivers/FGEN_FY6900.py +234 -0
  22. sqdtoolz/Drivers/MWS_SGS100A.py +203 -0
  23. sqdtoolz/Drivers/MWS_SMB100A.py +274 -0
  24. sqdtoolz/Drivers/MWS_WFSynthHDProV2.py +222 -0
  25. sqdtoolz/Drivers/MWS_WFSynthHDProV2_RPi.py +56 -0
  26. sqdtoolz/Drivers/SA_RS_FSV.py +246 -0
  27. sqdtoolz/Drivers/SMU_B2901A.py +226 -0
  28. sqdtoolz/Drivers/SMU_Keithley236.py +404 -0
  29. sqdtoolz/Drivers/SMU_TENMA_72_2710.py +192 -0
  30. sqdtoolz/Drivers/SW_BJT_RPi.py +87 -0
  31. sqdtoolz/Drivers/SW_BJT_RPi_Multi.py +107 -0
  32. sqdtoolz/Drivers/SW_FPGA_VNA.py +114 -0
  33. sqdtoolz/Drivers/SW_RFSwitchController_CryoRadiall.py +146 -0
  34. sqdtoolz/Drivers/SW_RPiCryo.py +198 -0
  35. sqdtoolz/Drivers/SW_RPiRadial.py +183 -0
  36. sqdtoolz/Drivers/SW_RpiIQBox.py +41 -0
  37. sqdtoolz/Drivers/THERM_TC0309.py +72 -0
  38. sqdtoolz/Drivers/Tabor_P2584M.py +1874 -0
  39. sqdtoolz/Drivers/VNA_Agilent_N5232A.py +680 -0
  40. sqdtoolz/Drivers/VNA_Keysight_P9373A.py +17 -0
  41. sqdtoolz/Drivers/VOLT_Delft_IVVI.py +1194 -0
  42. sqdtoolz/Drivers/VOLT_IVVI_pyro.py +135 -0
  43. sqdtoolz/Drivers/VOLT_RpiMultiDAC.py +74 -0
  44. sqdtoolz/Drivers/VOLT_SIM928_PLX.py +371 -0
  45. sqdtoolz/Drivers/VOLT_SIM928_VCOM.py +381 -0
  46. sqdtoolz/Drivers/VOLT_SIM928_pyro.py +50 -0
  47. sqdtoolz/Drivers/VOLT_Stahl_16CH.py +304 -0
  48. sqdtoolz/Drivers/ZILabOneQ.py +41 -0
  49. sqdtoolz/Drivers/__init__.py +0 -0
  50. sqdtoolz/Drivers/dummyACQ.py +109 -0
  51. sqdtoolz/Drivers/dummyACQex.py +120 -0
  52. sqdtoolz/Drivers/dummyAWG.py +121 -0
  53. sqdtoolz/Drivers/dummyDDG.py +116 -0
  54. sqdtoolz/Drivers/dummyGENmwSource.py +125 -0
  55. sqdtoolz/Drivers/dummySMU.py +100 -0
  56. sqdtoolz/Experiment.py +406 -0
  57. sqdtoolz/ExperimentConfiguration.py +464 -0
  58. sqdtoolz/ExperimentSpecification.py +150 -0
  59. sqdtoolz/ExperimentSpecifications/__init__.py +0 -0
  60. sqdtoolz/ExperimentSweeps.py +70 -0
  61. sqdtoolz/Experiments/Experimental/ExpACstarkRamseyGE.py +122 -0
  62. sqdtoolz/Experiments/Experimental/ExpBodePlot.py +69 -0
  63. sqdtoolz/Experiments/Experimental/ExpCalibGE.py +67 -0
  64. sqdtoolz/Experiments/Experimental/ExpCalibXrot.py +107 -0
  65. sqdtoolz/Experiments/Experimental/ExpCalibXrotAuto.py +126 -0
  66. sqdtoolz/Experiments/Experimental/ExpGateBenchmarks.py +109 -0
  67. sqdtoolz/Experiments/Experimental/ExpHahnGE.py +121 -0
  68. sqdtoolz/Experiments/Experimental/ExpMixerCalibrationLO.py +130 -0
  69. sqdtoolz/Experiments/Experimental/ExpMixerCalibrationSB.py +102 -0
  70. sqdtoolz/Experiments/Experimental/ExpPeakScouterIQ.py +68 -0
  71. sqdtoolz/Experiments/Experimental/ExpPulsedCavitySpec.py +93 -0
  72. sqdtoolz/Experiments/Experimental/ExpQubitFluxSweep.py +83 -0
  73. sqdtoolz/Experiments/Experimental/ExpRabi.py +170 -0
  74. sqdtoolz/Experiments/Experimental/ExpRamseyGE.py +125 -0
  75. sqdtoolz/Experiments/Experimental/ExpRandomisedBenchmarking.py +142 -0
  76. sqdtoolz/Experiments/Experimental/ExpResistanceIVs.py +54 -0
  77. sqdtoolz/Experiments/Experimental/ExpResistanceIVsFast.py +45 -0
  78. sqdtoolz/Experiments/Experimental/ExpSingleShotGE.py +74 -0
  79. sqdtoolz/Experiments/Experimental/ExpT1GE.py +119 -0
  80. sqdtoolz/Experiments/Experimental/ExpVNAEquations.py +120 -0
  81. sqdtoolz/Experiments/Experimental/ExpVNAoptimalSNR.py +38 -0
  82. sqdtoolz/Experiments/Experimental/ExpZIActiveResetTuneup.py +81 -0
  83. sqdtoolz/Experiments/Experimental/ExpZIBenchmarkETH.py +95 -0
  84. sqdtoolz/Experiments/Experimental/ExpZIBlobs.py +83 -0
  85. sqdtoolz/Experiments/Experimental/ExpZICalibX.py +142 -0
  86. sqdtoolz/Experiments/Experimental/ExpZIChevrons.py +65 -0
  87. sqdtoolz/Experiments/Experimental/ExpZIChevrons2QFixedCoupler.py +182 -0
  88. sqdtoolz/Experiments/Experimental/ExpZICryoscope.py +313 -0
  89. sqdtoolz/Experiments/Experimental/ExpZIDailyTuneup.py +132 -0
  90. sqdtoolz/Experiments/Experimental/ExpZIDispersive.py +110 -0
  91. sqdtoolz/Experiments/Experimental/ExpZIDragScaling.py +90 -0
  92. sqdtoolz/Experiments/Experimental/ExpZIFixedCouplerTuneup.py +152 -0
  93. sqdtoolz/Experiments/Experimental/ExpZIQASM.py +133 -0
  94. sqdtoolz/Experiments/Experimental/ExpZIQASMDataViewer.py +63 -0
  95. sqdtoolz/Experiments/Experimental/ExpZIQubitFluxSweep.py +252 -0
  96. sqdtoolz/Experiments/Experimental/ExpZIQubitPowerSweep.py +114 -0
  97. sqdtoolz/Experiments/Experimental/ExpZIQubitSpec.py +59 -0
  98. sqdtoolz/Experiments/Experimental/ExpZIRabi.py +111 -0
  99. sqdtoolz/Experiments/Experimental/ExpZIRabiRamseyT1.py +164 -0
  100. sqdtoolz/Experiments/Experimental/ExpZIRamsey.py +103 -0
  101. sqdtoolz/Experiments/Experimental/ExpZIRandomisedBenchmarking.py +126 -0
  102. sqdtoolz/Experiments/Experimental/ExpZIRes.py +123 -0
  103. sqdtoolz/Experiments/Experimental/ExpZIResFluxSweep.py +101 -0
  104. sqdtoolz/Experiments/Experimental/ExpZIResOptimal.py +224 -0
  105. sqdtoolz/Experiments/Experimental/ExpZIResPowerSweep.py +66 -0
  106. sqdtoolz/Experiments/Experimental/ExpZISingleQubitTuneup.py +363 -0
  107. sqdtoolz/Experiments/Experimental/ExpZIT1.py +86 -0
  108. sqdtoolz/Experiments/Experimental/ExpZIT1SingleShot.py +53 -0
  109. sqdtoolz/Experiments/Experimental/ExpZITWPATuneup.py +134 -0
  110. sqdtoolz/Experiments/Experimental/ExpZIqubit.py +289 -0
  111. sqdtoolz/Experiments/Experimental/ZI/calibrate_tunable_transmon_fixed_coupler.py +311 -0
  112. sqdtoolz/Experiments/Experimental/ZI/calibrate_tunable_transmon_fixed_coupler_osc.py +291 -0
  113. sqdtoolz/Experiments/Experimental/ZI/cryo_scope.py +329 -0
  114. sqdtoolz/Experiments/Experimental/ZI/flux_scope.py +309 -0
  115. sqdtoolz/Experiments/Experimental/ZI/oqasm_scheduled_qubits.py +320 -0
  116. sqdtoolz/Experiments/Experimental/ZI/qubit_single_chevron.py +290 -0
  117. sqdtoolz/Experiments/Experimental/ZI/qubit_spectroscopy_gef.py +288 -0
  118. sqdtoolz/Experiments/Experimental/ZI/single_qubit_gates.py +259 -0
  119. sqdtoolz/Experiments/Experimental/ZI/single_qubit_gates_sweep.py +280 -0
  120. sqdtoolz/Experiments/Experimental/ZI/sinlge_qubit_gates_sweep_chunking.py +288 -0
  121. sqdtoolz/HAL/ACQ.py +171 -0
  122. sqdtoolz/HAL/ACQdso.py +166 -0
  123. sqdtoolz/HAL/ACQsa.py +108 -0
  124. sqdtoolz/HAL/ACQvna.py +192 -0
  125. sqdtoolz/HAL/AWG.py +1057 -0
  126. sqdtoolz/HAL/DDG.py +93 -0
  127. sqdtoolz/HAL/DataProcessor.py +45 -0
  128. sqdtoolz/HAL/DecisionBlock.py +10 -0
  129. sqdtoolz/HAL/Decisions/DEC_SVM.py +38 -0
  130. sqdtoolz/HAL/GENatten.py +34 -0
  131. sqdtoolz/HAL/GENfuncGen.py +86 -0
  132. sqdtoolz/HAL/GENmwSource.py +132 -0
  133. sqdtoolz/HAL/GENmwSrcAWG.py +157 -0
  134. sqdtoolz/HAL/GENsmu.py +176 -0
  135. sqdtoolz/HAL/GENswitch.py +38 -0
  136. sqdtoolz/HAL/GENswitchTrig.py +44 -0
  137. sqdtoolz/HAL/GENtherm.py +29 -0
  138. sqdtoolz/HAL/GENvoltSource.py +50 -0
  139. sqdtoolz/HAL/HALbase.py +78 -0
  140. sqdtoolz/HAL/LockableProperties.py +22 -0
  141. sqdtoolz/HAL/MultiACQ.py +160 -0
  142. sqdtoolz/HAL/Processors/CPU/CPU_AmpPhs.py +48 -0
  143. sqdtoolz/HAL/Processors/CPU/CPU_ChannelArithmetic.py +72 -0
  144. sqdtoolz/HAL/Processors/CPU/CPU_ConstantArithmetic.py +54 -0
  145. sqdtoolz/HAL/Processors/CPU/CPU_DDC.py +52 -0
  146. sqdtoolz/HAL/Processors/CPU/CPU_Decimation.py +47 -0
  147. sqdtoolz/HAL/Processors/CPU/CPU_Duplicate.py +35 -0
  148. sqdtoolz/HAL/Processors/CPU/CPU_ESD.py +54 -0
  149. sqdtoolz/HAL/Processors/CPU/CPU_FFT.py +55 -0
  150. sqdtoolz/HAL/Processors/CPU/CPU_FIR.py +67 -0
  151. sqdtoolz/HAL/Processors/CPU/CPU_Integrate.py +39 -0
  152. sqdtoolz/HAL/Processors/CPU/CPU_Max.py +39 -0
  153. sqdtoolz/HAL/Processors/CPU/CPU_Mean.py +39 -0
  154. sqdtoolz/HAL/Processors/CPU/CPU_MeanBlock.py +46 -0
  155. sqdtoolz/HAL/Processors/CPU/CPU_MeanVariance.py +43 -0
  156. sqdtoolz/HAL/Processors/CPU/CPU_Rename.py +27 -0
  157. sqdtoolz/HAL/Processors/CPU/CPU_Slice.py +46 -0
  158. sqdtoolz/HAL/Processors/CPU/CPU_Variance.py +39 -0
  159. sqdtoolz/HAL/Processors/CPU/CPU_kMeans.py +49 -0
  160. sqdtoolz/HAL/Processors/FPGA/FPGA_DDC.py +54 -0
  161. sqdtoolz/HAL/Processors/FPGA/FPGA_DDCFIR.py +62 -0
  162. sqdtoolz/HAL/Processors/FPGA/FPGA_Decimation.py +29 -0
  163. sqdtoolz/HAL/Processors/FPGA/FPGA_FFT.py +24 -0
  164. sqdtoolz/HAL/Processors/FPGA/FPGA_FIR.py +56 -0
  165. sqdtoolz/HAL/Processors/FPGA/FPGA_Integrate.py +27 -0
  166. sqdtoolz/HAL/Processors/FPGA/FPGA_Mean.py +27 -0
  167. sqdtoolz/HAL/Processors/FPGA/FPGA_MultiplierConst.py +47 -0
  168. sqdtoolz/HAL/Processors/GPU/GPU_ChannelArithmetic.py +74 -0
  169. sqdtoolz/HAL/Processors/GPU/GPU_ConstantArithmetic.py +54 -0
  170. sqdtoolz/HAL/Processors/GPU/GPU_DDC.py +52 -0
  171. sqdtoolz/HAL/Processors/GPU/GPU_Decimation.py +52 -0
  172. sqdtoolz/HAL/Processors/GPU/GPU_Duplicate.py +35 -0
  173. sqdtoolz/HAL/Processors/GPU/GPU_ESD.py +56 -0
  174. sqdtoolz/HAL/Processors/GPU/GPU_FFT.py +57 -0
  175. sqdtoolz/HAL/Processors/GPU/GPU_FIR.py +87 -0
  176. sqdtoolz/HAL/Processors/GPU/GPU_Integrate.py +37 -0
  177. sqdtoolz/HAL/Processors/GPU/GPU_Max.py +37 -0
  178. sqdtoolz/HAL/Processors/GPU/GPU_Mean.py +37 -0
  179. sqdtoolz/HAL/Processors/GPU/GPU_MeanBlock.py +47 -0
  180. sqdtoolz/HAL/Processors/GPU/GPU_Rename.py +27 -0
  181. sqdtoolz/HAL/Processors/GPU/GPU_Slice.py +37 -0
  182. sqdtoolz/HAL/Processors/ProcessorCPU.py +176 -0
  183. sqdtoolz/HAL/Processors/ProcessorFPGA.py +91 -0
  184. sqdtoolz/HAL/Processors/ProcessorGPU.py +197 -0
  185. sqdtoolz/HAL/SOFTpid.py +169 -0
  186. sqdtoolz/HAL/SOFTqpu.py +254 -0
  187. sqdtoolz/HAL/TriggerPulse.py +223 -0
  188. sqdtoolz/HAL/WaveformGeneric.py +49 -0
  189. sqdtoolz/HAL/WaveformMapper.py +11 -0
  190. sqdtoolz/HAL/WaveformSegments.py +601 -0
  191. sqdtoolz/HAL/WaveformTransformations.py +221 -0
  192. sqdtoolz/HAL/ZI/QuantumElements/TunableTransmonCouplerFixed.py +139 -0
  193. sqdtoolz/HAL/ZI/QuantumElements/__init__.py +18 -0
  194. sqdtoolz/HAL/ZI/ZIACQ.py +209 -0
  195. sqdtoolz/HAL/ZI/ZIPulses.py +253 -0
  196. sqdtoolz/HAL/ZI/ZIQuantumElement.py +126 -0
  197. sqdtoolz/HAL/ZI/ZIQubit.py +294 -0
  198. sqdtoolz/HAL/ZI/ZIbase.py +3 -0
  199. sqdtoolz/HAL/ZI/__init__.py +3 -0
  200. sqdtoolz/Laboratory.py +654 -0
  201. sqdtoolz/Utilities/DataFitting.py +776 -0
  202. sqdtoolz/Utilities/DataIQDiscriminate.py +160 -0
  203. sqdtoolz/Utilities/DataIQNormalise.py +76 -0
  204. sqdtoolz/Utilities/DataQubitFlux.py +309 -0
  205. sqdtoolz/Utilities/DataSingleShotThreshold.py +92 -0
  206. sqdtoolz/Utilities/ExperimentViewer.py +878 -0
  207. sqdtoolz/Utilities/FileConverter.py +49 -0
  208. sqdtoolz/Utilities/FileIO.py +592 -0
  209. sqdtoolz/Utilities/FileJSON.py +48 -0
  210. sqdtoolz/Utilities/Flattenator.py +168 -0
  211. sqdtoolz/Utilities/Miscellaneous.py +111 -0
  212. sqdtoolz/Utilities/OpenQASM/ParserOpenQASM.py +1195 -0
  213. sqdtoolz/Utilities/OpenQASM/ScheduleParametersJSONConfigZI.py +72 -0
  214. sqdtoolz/Utilities/OpenQASM/ScheduleParametersSoftQPUZI.py +44 -0
  215. sqdtoolz/Utilities/OpenQASM/__init__.py +27 -0
  216. sqdtoolz/Utilities/OpenQASM/includes/stdgates.inc +270 -0
  217. sqdtoolz/Utilities/OpenQASM/includes/stdgates_transmon_fixed_coupler.inc +24 -0
  218. sqdtoolz/Utilities/Optimisers.py +64 -0
  219. sqdtoolz/Utilities/QubitGates.py +264 -0
  220. sqdtoolz/Utilities/ResonatorTools.py +2469 -0
  221. sqdtoolz/Utilities/TimingPlots.py +328 -0
  222. sqdtoolz/Variable.py +387 -0
  223. sqdtoolz/__init__.py +42 -0
  224. sqdtoolz-0.9.0.dev1.dist-info/METADATA +125 -0
  225. sqdtoolz-0.9.0.dev1.dist-info/RECORD +228 -0
  226. sqdtoolz-0.9.0.dev1.dist-info/WHEEL +5 -0
  227. sqdtoolz-0.9.0.dev1.dist-info/licenses/LICENSE +203 -0
  228. sqdtoolz-0.9.0.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,126 @@
1
+ import numpy as np
2
+ from sqdtoolz.Experiments.Experimental.ExpZIqubit import ExpZIqubit
3
+ from sqdtoolz.Variable import VariablePropertyTransient
4
+ from sqdtoolz.HAL.WaveformGeneric import *
5
+ from sqdtoolz.HAL.WaveformSegments import *
6
+ from sqdtoolz.Utilities.DataFitting import *
7
+ from sqdtoolz.Experiments.Experimental.ExpCalibGE import *
8
+ from sqdtoolz.Utilities.QubitGates import QubitGatesBase
9
+ import json
10
+ from sqdtoolz.Experiments.Experimental.ZI import single_qubit_gates_sweep
11
+ from sqdtoolz.Experiments.Experimental.ZI import sinlge_qubit_gates_sweep_chunking
12
+ from sqdtoolz.Utilities.QubitGates import QubitGatesBase
13
+ from sqdtoolz.Variable import VariableInternalTransient
14
+
15
+ class ExpZIBenchmarkRandomised(ExpZIqubit):
16
+ def __init__(self, name, expt_config, hal_QPU, qubit_ids, **kwargs):
17
+ self._qubit_datasets = qubit_ids
18
+
19
+ self._hal_QPU = hal_QPU
20
+
21
+ self._dont_show_plot = kwargs.pop('dont_show_plot', False)
22
+ assert (not 'update' in kwargs) or ('update' in kwargs and not kwargs['update']), "Don't set 'update=True'. The updates shall be done by calling update_qubit after running the experiment."
23
+ kwargs['update'] = False
24
+
25
+ kwargs['coordinate_system'] = kwargs.get('coordinate_system', 'RH')
26
+ assert kwargs['coordinate_system'] in ['LH', 'RH'], "The 'coordinate_system' must be either LH or RH for left/right handed."
27
+
28
+ self._fit_vals = []
29
+
30
+ #extra_gate_seqs = kwargs.get('extra_gate_seqs', [])
31
+ self._rb_seed = kwargs.get('rb_seed', 88)
32
+ self._rng = np.random.default_rng(seed = self._rb_seed)
33
+
34
+ self._sequence_lengths = kwargs.pop('sequence_lengths', [3,4,5,6,7,8,9,10,11,12])
35
+ self._num_trials = kwargs.pop('num_trials',5)
36
+
37
+
38
+ self._gate_set = ['X', 'X/2', '-X/2', 'Y', 'Y/2', '-Y/2']
39
+
40
+
41
+ self._all_seqs = {}
42
+ kwargs['gate_lists'] = []
43
+ print("Generating gate sequences...")
44
+ for seq_len in self._sequence_lengths:
45
+ self._all_seqs[int(seq_len)] = {}
46
+ for trial in range(self._num_trials):
47
+ cur_seq = self._generate_sequence(seq_len)
48
+ kwargs['gate_lists'].append([cur_seq]*len(qubit_ids))
49
+ self._all_seqs[int(seq_len)][int(trial)] = [cur_seq]*len(qubit_ids)
50
+ self._all_seqs_list = kwargs['gate_lists']
51
+ print("Done.")
52
+ super().__init__(name, expt_config, sinlge_qubit_gates_sweep_chunking, hal_QPU, qubit_ids, **kwargs)
53
+
54
+ def _generate_sequence(self, seq_len):
55
+ #Keep trying to find random sequences that enable the final gate to be within the gate-set - e.g. X/2, Y will give a 45° rotation...
56
+ while(True):
57
+ rand_int_array = self._rng.integers(low=0, high=len(self._gate_set)-1, size=seq_len-1)
58
+ gate_seq = [self._gate_set[i] for i in rand_int_array]
59
+ gate_mats = [QubitGatesBase.get_rotation_from_Pauli_Matrix(g) for g in gate_seq]
60
+ gate_mats.reverse()
61
+ effective_gate = np.linalg.multi_dot(gate_mats)
62
+ #Final state should be excited-state...
63
+ XReInv = QubitGatesBase.get_rotation_from_Pauli_Matrix('X') @ np.linalg.inv(effective_gate)
64
+
65
+ try:
66
+ final_gate = QubitGatesBase.convert_Pauli_rotation_to_natural( *QubitGatesBase.compute_rotation_Pauli_Matrices(XReInv))
67
+ except:
68
+ continue
69
+ if final_gate == 'Z' or final_gate == 'Z/2' or final_gate == '-Z/2':
70
+ final_gate = 'I'
71
+ gate_seq.append(final_gate)
72
+
73
+ return gate_seq
74
+
75
+ def _post_process(self, data):
76
+ for ind_qubit, qubit_dataset in enumerate(self._qubit_datasets):
77
+ leData = self.retrieve_last_dataset(qubit_dataset)
78
+ arr = leData.get_numpy_array()
79
+ seqs = leData.param_vals[0]
80
+ seq_lens = np.array(self._sequence_lengths)
81
+ norm = ExpZIqubit.normalise_qubit_data(self.retrieve_last_dataset(qubit_dataset+'_calib'), self._transition)
82
+ probs = norm.normalise_data(arr)
83
+ mean_vals = []
84
+ std_vals = []
85
+
86
+ fig, axs = plt.subplots(ncols=2); fig.set_figwidth(12); axs[0].grid(); axs[1].grid()
87
+
88
+ for m in range(len(self._sequence_lengths)):
89
+ trial_probs = []
90
+ xvals = []
91
+ for k in range(self._num_trials):
92
+ cur_seq_index = m*self._num_trials + k
93
+ if probs[cur_seq_index] < 0.8:
94
+ continue
95
+ trial_probs.append(probs[cur_seq_index])
96
+ xvals.append(self._sequence_lengths[m])
97
+ cur_x = xvals
98
+ cur_y = trial_probs
99
+ axs[0].plot(cur_x, cur_y, 'kx', alpha = 0.3)
100
+ mean_vals.append(np.mean(cur_y))
101
+ std_vals.append(np.std(cur_y))
102
+ mean_vals = np.array(mean_vals)
103
+ std_vals = np.array(std_vals)
104
+
105
+
106
+
107
+ axs[0].plot(seq_lens, mean_vals)
108
+ axs[0].fill_between(seq_lens, mean_vals-std_vals, mean_vals+std_vals, alpha=0.5)
109
+ axs[0].set_xlabel('Sequence Length')
110
+ axs[0].set_ylabel('Excited State Probability')
111
+ axs[0].set_title(f'Number of Trials per Sequence Length: {self._num_trials}')
112
+
113
+ zProj = mean_vals - 0.5
114
+ slope, intercept = np.polyfit(seq_lens, np.log(zProj), deg=1)
115
+ error_per_gate = np.exp(slope)
116
+ axs[1].plot(seq_lens, np.log(zProj), 'kx')
117
+ axs[1].plot(seq_lens, seq_lens*slope+intercept, 'r-')
118
+ axs[1].set_xlabel('Sequence Length')
119
+ axs[1].set_ylabel(r'$\ell n(Z_{proj})$')
120
+ axs[1].set_title(f"Error per Gate: {(error_per_gate*100):.6g}%")
121
+ axs[1].legend(['Raw Data', 'Fitted Error line'])
122
+
123
+ fig.show()
124
+ fig.savefig(self._file_path + 'Summary.png')
125
+
126
+ return data
@@ -0,0 +1,123 @@
1
+ from sqdtoolz.Experiments.Experimental.ExpZIqubit import ExpZIqubit
2
+ from sqdtoolz.Utilities.DataFitting import*
3
+ from sqdtoolz.Utilities.ResonatorTools import ResonatorPowerSweep
4
+ from laboneq_applications.experiments import (
5
+ resonator_spectroscopy,
6
+ resonator_spectroscopy_amplitude,
7
+ )
8
+
9
+ class ExpZIRes(ExpZIqubit):
10
+ def __init__(self, name, expt_config, hal_QPU, qubit_id, **kwargs):
11
+ assert isinstance(qubit_id, str), "Supply qubit_id as the solitary string ID here (i.e. not a list)."
12
+ self._qubit_dataset = qubit_id
13
+
14
+ self._update_qubit = kwargs.pop('update_qubit_params', True)
15
+
16
+ self._dont_show_plot = kwargs.pop('dont_show_plot', False)
17
+
18
+ self._iq_indices = kwargs.pop('iq_indices', [0,1])
19
+ self._is_trough = kwargs.pop('is_trough', False)
20
+ self._fit_type = kwargs.pop('fit_type', 'Default') #Default, Fano, Full
21
+ assert self._fit_type in ["Default", "Fano", "Full"], "Choose fit_type as either 'Default', 'Fano' or 'Full'."
22
+ assert self._is_trough or (not self._is_trough and not self._fit_type=='Fano'), "Fano resonance fitting only supports troughs at the moment."
23
+ self._param_centre = kwargs.pop('param_freq', None)
24
+ self._param_width = kwargs.pop('param_width', None)
25
+ self._param_amplitude = kwargs.pop('param_amplitude', None)
26
+ self._param_offset = kwargs.pop('param_offset', None)
27
+ self._param_fano = kwargs.pop('param_fano', None)
28
+ self._dont_plot = kwargs.pop('dont_plot', False)
29
+ self._xUnits = kwargs.pop('plot_x_units', 'Hz')
30
+ self._hal_QPU = hal_QPU
31
+
32
+ self._frequencies = kwargs.pop('frequencies', None)
33
+ self._span = kwargs.pop('span', 5e6)
34
+ self._num_freq_pts = kwargs.pop('num_frequency_points', 401)
35
+
36
+ if self._frequencies is None:
37
+ self._frequencies = np.linspace(-self._span, self._span, self._num_freq_pts) + self._hal_QPU.get_qubit_obj(self._qubit_dataset).ReadoutFrequency
38
+
39
+ kwargs['frequencies'] = self._frequencies
40
+
41
+ super().__init__(name, expt_config, resonator_spectroscopy, hal_QPU, [qubit_id], **kwargs)
42
+
43
+ def _post_process(self, data):
44
+ data = self.retrieve_last_dataset(self._qubit_dataset)
45
+ assert len(data.param_names), "The sweep should only be 1D."
46
+
47
+ arr = data.get_numpy_array()
48
+ data_x = data.param_vals[0]
49
+ data_i = arr[:,self._iq_indices[0]]
50
+ data_q = arr[:,self._iq_indices[1]]
51
+ data_y = np.sqrt(arr[:,self._iq_indices[0]]**2 + arr[:,self._iq_indices[1]]**2)
52
+
53
+ if self._fit_type == "Default":
54
+ dfit = DFitPeakLorentzian()
55
+ dpkt = dfit.get_fitted_plot(data_x, data_y**2, xLabel="Frequency (Hz)", dip=self._is_trough, dontplot=self._dont_plot, xUnits=self._xUnits)
56
+ #Commit to parameters...
57
+ if self._update_qubit:
58
+ cur_qubit = self._hal_QPU.get_qubit_obj(self._qubit_dataset)
59
+ cur_qubit.ReadoutFrequency = dpkt['centre']
60
+ if self._param_centre:
61
+ self._param_centre.Value = dpkt['centre']
62
+ if self._param_width:
63
+ self._param_width.Value = dpkt['width']
64
+ if self._param_amplitude:
65
+ self._param_amplitude.Value = dpkt['amplitude']
66
+ if self._param_offset:
67
+ self._param_offset.Value = dpkt['offset']
68
+ dpkt['fit_data'] = {'squared_amplitude': dpkt['fit_data']}
69
+ elif self._fit_type == "Fano":
70
+ dfit = DFitFanoResonance()
71
+ dpkt = dfit.get_fitted_plot(data_x, data_y**2, xLabel="Frequency (Hz)", yLabel="Squared IQ Amplitude", dontplot=self._dont_plot, xUnits=self._xUnits) #, dip=self._is_trough)
72
+ #Commit to parameters...
73
+ if self._update_qubit:
74
+ cur_qubit = self._hal_QPU.get_qubit_obj(self._qubit_dataset)
75
+ cur_qubit.ReadoutFrequency = dpkt['xMinimum']
76
+ if self._param_centre:
77
+ self._param_centre.Value = dpkt['xMinimum']
78
+ if self._param_width:
79
+ self._param_width.Value = dpkt['width']
80
+ if self._param_amplitude:
81
+ self._param_amplitude.Value = dpkt['amplitude']
82
+ if self._param_offset:
83
+ self._param_offset.Value = dpkt['offset']
84
+ if self._param_fano:
85
+ self._param_fano.Value = dpkt['FanoFac']
86
+ dpkt['fit_data'] = {'squared_amplitude': dpkt['fit_data']}
87
+ elif self._fit_type == "Full":
88
+ if self._hal_QPU.get_qubit_obj(self._qubit_dataset).ReadoutLineAttenuation_dB:
89
+ atten = self._hal_QPU.get_qubit_obj(self._qubit_dataset).ReadoutLineAttenuation_dB
90
+ readout_pwr = self._hal_QPU.get_qubit_obj(self._qubit_dataset).ReadoutPower + 20*np.log10(self._hal_QPU.get_qubit_obj(self._qubit_dataset).ReadoutAmplitude)
91
+ dpkt = ResonatorPowerSweep.single_circlefit(data_x, data_i, data_q, power_dBm=atten + readout_pwr, dont_plot=self._dont_plot)
92
+ else:
93
+ dpkt = ResonatorPowerSweep.single_circlefit(data_x, data_i, data_q, power_dBm=-100, dont_plot=self._dont_plot)
94
+ #Commit to parameters...
95
+ if self._update_qubit:
96
+ cur_qubit = self._hal_QPU.get_qubit_obj(self._qubit_dataset)
97
+ if dpkt and dpkt['fr']:
98
+ cur_qubit.ReadoutFrequency = dpkt['fr']
99
+ cur_qubit.ReadoutQi = dpkt['Qi_dia_corr']
100
+ cur_qubit.ReadoutQc = dpkt['Qc_dia_corr']
101
+ cur_qubit.ReadoutQl = dpkt['Ql']
102
+ dpkt['fit_data'] = {'real': np.real(dpkt['fit_data']), 'imag': np.imag(dpkt['fit_data'])}
103
+ cur_qubit.ReadoutKappa = dpkt['fr'] / dpkt['Qc_dia_corr']
104
+ else:
105
+ print('Qubit parameters were not updated: bad fit.')
106
+ if self._param_centre:
107
+ self._param_centre.Value = dpkt['fr']
108
+
109
+ if dpkt:
110
+ if not self._dont_plot:
111
+ dpkt['fig'].savefig(self._file_path + 'fitted_plot.png')
112
+ if not self._dont_show_plot:
113
+ dpkt['fig'].show()
114
+ else:
115
+ plt.close(dpkt['fig'])
116
+ if 'fit_data' in dpkt:
117
+ np.save(self._file_path + 'fitted_data.npy', dpkt['fit_data'])
118
+ else:
119
+ if not self._dont_plot:
120
+ plt.plot(data_x, data_y)
121
+ plt.xlabel("Frequency (Hz)")
122
+ plt.ylabel("|S21|")
123
+ plt.show()
@@ -0,0 +1,101 @@
1
+ from sqdtoolz.Experiments.Experimental.ExpZIqubit import ExpZIqubit
2
+ from laboneq_applications.experiments import resonator_spectroscopy
3
+ from sqdtoolz.Variable import VariablePropertyTransient
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ import scipy.interpolate
7
+ import scipy.optimize
8
+ from sqdtoolz.Utilities.DataFitting import DFitPeakLorentzian
9
+
10
+ class ExpZIResFluxSweep(ExpZIqubit):
11
+ def __init__(self, name, expt_config, hal_QPU, qubit_id, **kwargs):
12
+ assert isinstance(qubit_id, str), "Supply qubit_id as the solitary string ID here (i.e. not a list)."
13
+ self._qubit_id = qubit_id
14
+
15
+ self._update_qubit = kwargs.pop('update_qubit_params', True)
16
+
17
+ self._dont_show_plot = kwargs.pop('dont_show_plot', False)
18
+
19
+ self._is_trough = kwargs.pop('is_trough', True)
20
+ self._dont_plot = kwargs.pop('dont_plot', False)
21
+ self._xUnits = kwargs.pop('plot_x_units', 'Hz')
22
+ self._flux_range = kwargs.pop('flux_range', np.linspace(-1, 1, 10))
23
+ self._frequencies = kwargs.pop('frequencies', None)
24
+ self._span = kwargs.pop('span', 10e6)
25
+ self._num_freq_pts = kwargs.pop('num_frequency_points', 401)
26
+ self._hal_QPU = hal_QPU
27
+
28
+ self._opt_flux_val = None
29
+
30
+ if self._frequencies is None:
31
+ self._frequencies = np.linspace(-self._span, self._span, self._num_freq_pts) + self._hal_QPU.get_qubit_obj(self._qubit_id).ReadoutFrequency
32
+
33
+ kwargs['frequencies'] = self._frequencies
34
+ super().__init__(name, expt_config, resonator_spectroscopy, hal_QPU, [qubit_id], **kwargs)
35
+
36
+ def _run(self, file_path, sweep_vars=[], **kwargs):
37
+ assert len(sweep_vars) == 0, "Supply the frequency/flux when defining the Experiment object."
38
+
39
+ var_flux = VariablePropertyTransient('Flux', self._hal_QPU.get_qubit_obj(self._qubit_id),'FluxDC')
40
+ super()._run(file_path, sweep_vars=[(var_flux, self._flux_range)], **kwargs)
41
+
42
+ def _post_process(self, data):
43
+ leData = self.retrieve_last_dataset(self._qubit_id)
44
+ flux_vals,freq_vals = leData.param_vals
45
+ arr = leData.get_numpy_array()
46
+
47
+ ampl = np.sqrt(arr[:,:,0]**2 + arr[:,:,1]**2)
48
+
49
+ is_trough = self._is_trough
50
+
51
+ dfit = DFitPeakLorentzian()
52
+ res_freqs = []
53
+ for cur_slice in ampl:
54
+ dpkt = dfit.get_fitted_plot(freq_vals, cur_slice, dip=is_trough, dontplot=True)
55
+ res_freqs.append(dpkt['centre'])
56
+ res_freqs = np.array(res_freqs)
57
+
58
+ norm_fac = 10**np.round(np.log10(res_freqs).mean())
59
+ if flux_vals[1]-flux_vals[0] < 0:
60
+ spl = scipy.interpolate.UnivariateSpline(flux_vals[::-1], res_freqs[::-1]/norm_fac)
61
+ else:
62
+ spl = scipy.interpolate.UnivariateSpline(flux_vals, res_freqs/norm_fac)
63
+ spl.set_smoothing_factor(0.5)
64
+ soln = scipy.optimize.minimize_scalar(lambda x:-spl(x), bounds=(np.min(flux_vals), np.max(flux_vals)))
65
+
66
+ opt_flux = soln.x
67
+ sweet_freq = spl(opt_flux)*norm_fac
68
+
69
+ fitted_data = {
70
+ 'raw_fit_freqs': res_freqs,
71
+ 'smoothed_fit_freqs': spl(flux_vals)*norm_fac,
72
+ 'sweet_freq_flux': np.array([sweet_freq, opt_flux])
73
+ }
74
+ np.save(self._file_path + 'fitted_data.npy', fitted_data)
75
+
76
+ if not self._dont_plot:
77
+ fig, ax = plt.subplots(1); fig.set_figwidth(15)
78
+ ExpZIResFluxSweep.plot_fitted_results(ax, self._qubit_id, freq_vals, flux_vals, ampl, fitted_data)
79
+ if not self._dont_show_plot:
80
+ fig.show()
81
+ else:
82
+ plt.close(fig)
83
+ fig.savefig(self._file_path + 'fitted_plot.png')
84
+
85
+ self._opt_flux_val = opt_flux
86
+
87
+ @staticmethod
88
+ def plot_fitted_results(ax, qubit_id, freq_vals, flux_vals, ampl, fitted_data):
89
+ ax.pcolor(freq_vals, flux_vals, ampl)
90
+ ax.plot(fitted_data['smoothed_fit_freqs'], flux_vals, 'w-')
91
+ ax.plot(fitted_data['raw_fit_freqs'], flux_vals, 'wo')
92
+ ax.plot([fitted_data['sweet_freq_flux'][0]], [fitted_data['sweet_freq_flux'][1]], 'ro')
93
+ ax.set_title(f"{qubit_id} resonator flux sweep: $f_r$={fitted_data['sweet_freq_flux'][0]*1e-9:.4f} GHz, $V_\Phi$={fitted_data['sweet_freq_flux'][1]:.4f} V")
94
+ ax.set_xlabel('Frequency (Hz)')
95
+ ax.set_ylabel('Flux (V)')
96
+
97
+ def update_qubit(self):
98
+ assert self._opt_flux_val != None, "Must run an experiment before updating qubit parameters."
99
+ self._hal_QPU.get_qubit_obj(self._qubit_id).FluxDC = self._opt_flux_val
100
+ # TODO: update flux range to minimum
101
+ self._opt_flux_val = None
@@ -0,0 +1,224 @@
1
+ from sqdtoolz.Experiments.Experimental.ExpZIqubit import ExpZIqubit
2
+ import matplotlib.pyplot as plt
3
+ from sqdtoolz.Utilities.Miscellaneous import Miscellaneous
4
+ from laboneq_applications.experiments import dispersive_shift
5
+ import numpy as np
6
+ from sqdtoolz.Utilities.DataIQDiscriminate import DataIQDiscriminate
7
+ from sqdtoolz.Experiments.Experimental.ExpZIBlobs import ExpZIBlobs
8
+
9
+ class ExpZIResOptimal(ExpZIqubit):
10
+ def __init__(self, name, expt_config, hal_QPU, qubit_ids, **kwargs):
11
+ self._dont_show_plot = kwargs.pop('dont_show_plot', False)
12
+ assert (not 'update' in kwargs) or ('update' in kwargs and not kwargs['update']), "Don't set 'update=True'. This is just a diagnostic experiment."
13
+ kwargs['update'] = False
14
+ # self._fit_vals = []
15
+ assert 'states' in kwargs, "Must provide the states to measure traces over; e.g. 'ge' or 'gef'"
16
+ self._states = kwargs['states']
17
+ self._calc_single_shot_fidelities = kwargs.pop('calc_single_shot_fidelities', False)
18
+ if self._calc_single_shot_fidelities:
19
+ kwargs['do_analysis'] = False #The default ZI analysis will fail in this mode...
20
+ self._fit_data = {}
21
+ self._readout_fidelity = 0.0
22
+ super().__init__(name, expt_config, dispersive_shift, hal_QPU, qubit_ids, **kwargs)
23
+
24
+ def _run(self, file_path, sweep_vars=[], **kwargs):
25
+ if self._calc_single_shot_fidelities:
26
+ kwargs['override_ACQ_params'] = {'AveragingOrder': "SingleShot"}
27
+ return super()._run(file_path, sweep_vars, **kwargs)
28
+
29
+ def _post_process(self, data):
30
+ #This experiment only supports one qubit at a time...
31
+ leDatasets = [self.retrieve_last_dataset(self._qubit_ids[0] + '_' + x) for x in self._states]
32
+ arrs = [leDatasets[m].get_numpy_array() for m in range((len(self._states)))]
33
+
34
+ leCols = plt.rcParams['axes.prop_cycle'].by_key()['color']
35
+ if self._calc_single_shot_fidelities:
36
+ freqs = leDatasets[0].param_vals[1]
37
+ norm_fac, norm_prefix = Miscellaneous.get_metric_multiplier(freqs) #Should all be the same anyway...
38
+
39
+ fig = plt.figure(figsize=(8, 10))
40
+ gs = fig.add_gridspec(5, 4)
41
+
42
+ # First three rows each span all four columns
43
+ ax_mag = fig.add_subplot(gs[0, :])
44
+ axSeps = fig.add_subplot(gs[1, :], sharex=ax_mag)
45
+ axFids = fig.add_subplot(gs[2, :], sharex=ax_mag)
46
+
47
+ ax_mag.grid(); axSeps.grid(); axFids.grid()
48
+
49
+ axFids.set_ylabel('State Fidelities')
50
+
51
+ axFids.set_xlabel(f'Readout Frequency ({norm_prefix}Hz)')
52
+ else:
53
+ freqs = leDatasets[0].param_vals[0]
54
+ norm_fac, norm_prefix = Miscellaneous.get_metric_multiplier(freqs) #Should all be the same anyway...
55
+ fig, axs = plt.subplots(nrows=2)
56
+ ax_mag = axs[0]
57
+ axSeps = axs[1]
58
+ ax_mag.grid(); axSeps.grid()
59
+ ax_mag.set_xlabel(f'Readout Frequency ({norm_prefix}Hz)')
60
+ axSeps.set_xlabel(f'Readout Frequency ({norm_prefix}Hz)')
61
+ axSeps.set_ylabel('IQ separation')
62
+
63
+ ax_phase = ax_mag.twinx()
64
+
65
+ handles = []
66
+ for m in range(len(self._states)):
67
+ if self._calc_single_shot_fidelities:
68
+ arr = np.mean(arrs[m],axis=0)
69
+ else:
70
+ arr = arrs[m]
71
+ mag = np.sqrt(arr[:, 0]**2 + arr[:, 1]**2)
72
+ phase = np.unwrap(np.arctan2(arr[:, 1], arr[:, 0]))
73
+ # Plot magnitude and capture the line object
74
+ line, = ax_mag.plot(freqs/norm_fac, mag, label=self._states[m])
75
+ handles.append(line)
76
+ # Use the same colour for phase, but dashed
77
+ ax_phase.plot(freqs/norm_fac, phase,':',color=line.get_color())
78
+
79
+ ax_mag.set_ylabel('Magnitude')
80
+ ax_phase.set_ylabel('Phase (rad) (dotted)')
81
+ ax_mag.legend(handles=handles)
82
+
83
+
84
+ if len(self._states) == 2:
85
+ combs = [[0,1]]
86
+ else:
87
+ combs = [(0,1), (1,2), (0,2)]
88
+
89
+ all_diffs = []
90
+ maxSepInds = []
91
+ for m in range(len(combs)):
92
+ if self._calc_single_shot_fidelities:
93
+ arr1 = np.mean(arrs[combs[m][0]],axis=0)
94
+ arr2 = np.mean(arrs[combs[m][1]],axis=0)
95
+ else:
96
+ arr1 = arrs[combs[m][0]]
97
+ arr2 = arrs[combs[m][1]]
98
+ cur_diff = np.linalg.norm(arr1 - arr2, axis=1)
99
+ axSeps.plot(freqs/norm_fac, cur_diff, color=leCols[m])
100
+ maxSepInds.append(np.argmax(cur_diff))
101
+ axSeps.plot([freqs[maxSepInds[-1]]/norm_fac], [cur_diff[maxSepInds[-1]]], 'o', color=leCols[m], label='_nolegend_')
102
+ all_diffs.append(cur_diff)
103
+ if len(self._states) == 3:
104
+ cur_diff = np.sum(all_diffs, axis=0)
105
+ axSeps.plot(freqs/norm_fac, cur_diff, color=leCols[m+1])
106
+ maxSepInds.append(np.argmax(cur_diff))
107
+ axSeps.plot([freqs[maxSepInds[-1]]/norm_fac], [cur_diff[maxSepInds[-1]]], 'o', color=leCols[m+1], label='_nolegend_')
108
+ if len(self._states) == 2:
109
+ axSeps.legend(['GE'])
110
+ leTitlesSS = ['G','E','Mean']
111
+ else:
112
+ axSeps.legend(['GE', 'EF', 'GF', 'Total'])
113
+ leTitlesSS = ['G','E','F','Mean']
114
+
115
+ if self._calc_single_shot_fidelities:
116
+ leIQDiscs = [DataIQDiscriminate([arrs[x][:,m,:] for x in range(len(self._states))]) for m in range(freqs.size)]
117
+ leFids = [leIQDiscs[m].get_fidelities() for m in range(freqs.size)]
118
+ leFids = np.array(leFids)
119
+ #Gather fidelity data for each state the total
120
+ fidData = []
121
+ for m in range(len(self._states)):
122
+ fidData.append(leFids[:,m])
123
+ fidData.append(np.mean(leFids, axis=1))
124
+
125
+ maxFidInds = []
126
+ axFirst = None
127
+ for m in range(len(fidData)):
128
+ axFids.plot(freqs/norm_fac, fidData[m], color = leCols[m])
129
+ maxFidInds.append(np.argmax(fidData[m]))
130
+ axFids.plot(freqs[maxFidInds[-1]]/norm_fac, [fidData[m][maxFidInds[-1]]], 'o', color=leCols[m], label='_nolegend_')
131
+
132
+ if axFirst == None:
133
+ ax = fig.add_subplot(gs[3, m])
134
+ axFirst = ax
135
+ else:
136
+ ax = fig.add_subplot(gs[3, m], sharey=axFirst)
137
+ leIQDiscs[maxFidInds[-1]].plot_points(ax)
138
+ ax.set_title(leTitlesSS[m])
139
+ ax.set_xticklabels([])
140
+ ax.set_yticklabels([])
141
+ #
142
+ axA = fig.add_subplot(gs[4, m])
143
+ leIQDiscs[maxFidInds[-1]].plot_assignment_matrix(axA, sigFigs=2)
144
+ self._readout_fidelity = (leIQDiscs[maxFidInds[-1]].get_average_fidelity()*100)
145
+ axA.set_title(f"Mean: {self._readout_fidelity:.4g}%")
146
+ if m > 0:
147
+ ax.set_ylabel('')
148
+ axA.set_ylabel('')
149
+ axA.set_yticklabels([])
150
+
151
+ if len(self._states) == 2:
152
+ axFids.legend(['G','E','Mean'])
153
+ else:
154
+ axFids.legend(['G','E','F','Mean'])
155
+
156
+ self._fit_data = {'freqs':freqs, 'maxSepIndices':maxSepInds, 'maxFidIndices':maxFidInds, 'discriminators':leIQDiscs}
157
+
158
+ fig.subplots_adjust(hspace=0.1)
159
+ fig.tight_layout()
160
+
161
+ fig.savefig(self._file_path + f'fitted_plot_{self._qubit_ids[0]}.png')
162
+ if not self._dont_show_plot:
163
+ fig.show()
164
+ else:
165
+ plt.close(fig)
166
+
167
+ def update_qubits_by_separation(self, transition:str='Total'):
168
+ """
169
+ transition is given as 'ge', 'ef', 'gf' or 'Total' (can capitalise etc.)
170
+ """
171
+ assert len(self._fit_data) > 0, "Must run experiment first."
172
+ qubit_obj = self._hal_QPU.get_qubit_obj(self._qubit_ids[0])
173
+ transition = transition.lower()
174
+ if len(self._states) == 2:
175
+ assert transition in ['ge', 'total'], "Invalid transition (must be either 'ge' or 'total')"
176
+ ind = 0
177
+ else:
178
+ assert transition in ['ge', 'ef', 'gf', 'total'], "Invalid transition (must be either 'ge', 'ef', 'gf' or 'total')"
179
+ ind = ['ge', 'ef', 'gf', 'total'].index(transition)
180
+ qubit_obj.ReadoutFrequency = float( self._fit_data['freqs'][ self._fit_data['maxSepIndices'][ind] ] )
181
+ qubit_obj.FidelityReadout = self._readout_fidelity
182
+
183
+ def update_qubits_by_fidelity(self, state_fidelity:str='Mean'):
184
+ """
185
+ state_fidelity is given as 'g', 'e', 'f' or 'Mean' (can capitalise etc.) to take the highest of the respective fidelities as the point.
186
+ """
187
+ assert len(self._fit_data) > 0, "Must run experiment first."
188
+ assert self._calc_single_shot_fidelities, "Must run the experiment in single-shot by setting calc_single_shot_fidelities to True."
189
+ qubit_obj = self._hal_QPU.get_qubit_obj(self._qubit_ids[0])
190
+ state_fidelity = state_fidelity.lower()
191
+ if len(self._states) == 2:
192
+ assert state_fidelity in ['g', 'e', 'mean'], "Invalid state (must be either 'g', 'e' or 'mean')"
193
+ ind = ['g', 'e', 'mean'].index(state_fidelity)
194
+ else:
195
+ assert state_fidelity in ['g', 'e', 'f', 'mean'], "Invalid state (must be either 'g', 'e', 'f' or 'mean')"
196
+ ind = ['g', 'e', 'f', 'mean'].index(state_fidelity)
197
+ qubit_obj.ReadoutFrequency = float( self._fit_data['freqs'][ self._fit_data['maxFidIndices'][ind] ] )
198
+ qubit_obj.FidelityReadout = self._readout_fidelity
199
+
200
+ def print_best_frequencies_by_separation(self):
201
+ assert len(self._fit_data) > 0, "Must run experiment first."
202
+ if len(self._states) == 2:
203
+ print(f"Max GE: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxSepIndices'][0] ])}Hz")
204
+ else:
205
+ print(f"Max GE: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxSepIndices'][0] ])}Hz")
206
+ print(f"Max EF: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxSepIndices'][1] ])}Hz")
207
+ print(f"Max GF: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxSepIndices'][2] ])}Hz")
208
+
209
+ def print_best_frequencies_by_fidelity(self):
210
+ assert len(self._fit_data) > 0, "Must run experiment first."
211
+ assert self._calc_single_shot_fidelities, "Must run the experiment in single-shot by setting calc_single_shot_fidelities to True."
212
+ print(f"Max G: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxFidIndices'][0] ])}Hz")
213
+ print(f"Max E: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxFidIndices'][1] ])}Hz")
214
+ if len(self._states) == 2:
215
+ print(f"Max Mean: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxFidIndices'][2] ])}Hz")
216
+ else:
217
+ print(f"Max F: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxFidIndices'][2] ])}Hz")
218
+ print(f"Max Mean: {Miscellaneous.get_units(self._fit_data['freqs'][ self._fit_data['maxFidIndices'][3] ])}Hz")
219
+
220
+ def plot_blobs(self, frequency):
221
+ assert len(self._fit_data) > 0, "Must run experiment first."
222
+ assert self._calc_single_shot_fidelities, "Must run the experiment in single-shot by setting calc_single_shot_fidelities to True."
223
+ ind = np.argmin(np.abs(frequency-self._fit_data['freqs']))
224
+ ExpZIBlobs.plot_fitted_results(self._fit_data['discriminators'][ind], f"(Frequency: {Miscellaneous.get_units(self._fit_data['freqs'][ind])}Hz)")
@@ -0,0 +1,66 @@
1
+ from sqdtoolz.Experiments.Experimental.ExpZIqubit import ExpZIqubit
2
+ from laboneq_applications.experiments import resonator_spectroscopy
3
+ from sqdtoolz.Variable import VariablePropertyTransient
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ import scipy.interpolate
7
+ import scipy.optimize
8
+ from sqdtoolz.Utilities.DataFitting import DFitPeakLorentzian
9
+
10
+ class ExpZIResPowerSweep(ExpZIqubit):
11
+ def __init__(self, name, expt_config, hal_QPU, qubit_id, frequencies, **kwargs):
12
+ assert isinstance(qubit_id, str), "Supply qubit_id as the solitary string ID here (i.e. not a list)."
13
+ self._qubit_id = qubit_id
14
+
15
+ self._amplitude_range = kwargs.pop('amplitude_range', np.linspace(0.001, 0.9, 20))
16
+
17
+ self._dont_show_plot = kwargs.pop('dont_show_plot', False)
18
+
19
+ self._is_trough = kwargs.pop('is_trough', True)
20
+ self._dont_plot = kwargs.pop('dont_plot', False)
21
+ self._frequencies = frequencies
22
+ self._hal_QPU = hal_QPU
23
+
24
+ kwargs['frequencies'] = frequencies
25
+ super().__init__(name, expt_config, resonator_spectroscopy, hal_QPU, [qubit_id], **kwargs)
26
+
27
+ def _run(self, file_path, sweep_vars=[], **kwargs):
28
+ var_ampl = VariablePropertyTransient('Amplitude', self._hal_QPU.get_qubit_obj(self._qubit_id),'ReadoutAmplitude')
29
+ super()._run(file_path, sweep_vars=[(var_ampl, self._amplitude_range)], **kwargs)
30
+
31
+ def _post_process(self, data):
32
+ leData = self.retrieve_last_dataset(self._qubit_id)
33
+ ampl_vals,freq_vals = leData.param_vals
34
+ arr = leData.get_numpy_array()
35
+
36
+ ampl = np.sqrt(arr[:,:,0]**2 + arr[:,:,1]**2)
37
+
38
+ is_trough = self._is_trough
39
+
40
+ dfit = DFitPeakLorentzian()
41
+ res_freqs = []
42
+ for cur_slice in ampl:
43
+ dpkt = dfit.get_fitted_plot(freq_vals, cur_slice, dip=is_trough, dontplot=True)
44
+ res_freqs.append(dpkt['centre'])
45
+ res_freqs = np.array(res_freqs)
46
+
47
+ fitted_data = {'raw_fit_freqs': res_freqs,}
48
+
49
+ if not self._dont_plot:
50
+ fig, ax = plt.subplots(1); fig.set_figwidth(15)
51
+ ExpZIResPowerSweep.plot_fitted_results(ax, self._hal_QPU, self._qubit_id, freq_vals, ampl_vals, ampl, fitted_data)
52
+ if not self._dont_show_plot:
53
+ fig.show()
54
+ else:
55
+ plt.close(fig)
56
+ fig.savefig(self._file_path + 'fitted_plot.png')
57
+
58
+ @staticmethod
59
+ def plot_fitted_results(ax, hal_QPU, qubit_id, freq_vals, ampl_vals, ampl, fitted_data):
60
+ row_means = np.nanmean(ampl, axis=1)
61
+ ampl_corrected = (ampl.T - row_means).T
62
+ ax.pcolor(freq_vals, ampl_vals, ampl_corrected)
63
+ ax.plot(fitted_data['raw_fit_freqs'], ampl_vals, 'wo')
64
+ ax.set_title(f"{qubit_id} resonator power sweep at {hal_QPU.get_qubit_obj(qubit_id).ReadoutPower} dBm")
65
+ ax.set_xlabel('Frequency (Hz)')
66
+ ax.set_ylabel('Readout amplitude')