qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__cp39-abi3-macosx_11_0_arm64.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 (462) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +3 -9
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +35 -10
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +236 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +469 -154
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/graph_state.py +1 -0
  60. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  61. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  62. qiskit/circuit/library/n_local/n_local.py +1 -1
  63. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  64. qiskit/circuit/library/overlap.py +2 -2
  65. qiskit/circuit/library/pauli_evolution.py +39 -24
  66. qiskit/circuit/library/phase_oracle.py +130 -51
  67. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  69. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  70. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  71. qiskit/circuit/library/standard_gates/h.py +4 -9
  72. qiskit/circuit/library/standard_gates/i.py +2 -2
  73. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  74. qiskit/circuit/library/standard_gates/p.py +15 -34
  75. qiskit/circuit/library/standard_gates/r.py +7 -10
  76. qiskit/circuit/library/standard_gates/rx.py +5 -15
  77. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  78. qiskit/circuit/library/standard_gates/ry.py +5 -17
  79. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  80. qiskit/circuit/library/standard_gates/rz.py +5 -17
  81. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  82. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  83. qiskit/circuit/library/standard_gates/s.py +6 -15
  84. qiskit/circuit/library/standard_gates/swap.py +4 -11
  85. qiskit/circuit/library/standard_gates/sx.py +7 -12
  86. qiskit/circuit/library/standard_gates/t.py +6 -7
  87. qiskit/circuit/library/standard_gates/u.py +2 -10
  88. qiskit/circuit/library/standard_gates/u1.py +5 -16
  89. qiskit/circuit/library/standard_gates/u2.py +2 -6
  90. qiskit/circuit/library/standard_gates/u3.py +3 -11
  91. qiskit/circuit/library/standard_gates/x.py +14 -62
  92. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  94. qiskit/circuit/library/standard_gates/y.py +4 -9
  95. qiskit/circuit/library/standard_gates/z.py +5 -15
  96. qiskit/circuit/measure.py +11 -2
  97. qiskit/circuit/parameterexpression.py +11 -0
  98. qiskit/circuit/quantumcircuit.py +890 -564
  99. qiskit/circuit/random/utils.py +12 -6
  100. qiskit/circuit/reset.py +5 -2
  101. qiskit/circuit/singleton.py +5 -11
  102. qiskit/circuit/store.py +0 -8
  103. qiskit/circuit/tools/pi_check.py +3 -0
  104. qiskit/compiler/__init__.py +1 -7
  105. qiskit/compiler/transpiler.py +38 -196
  106. qiskit/converters/circuit_to_dag.py +6 -4
  107. qiskit/converters/circuit_to_dagdependency.py +0 -2
  108. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  109. qiskit/converters/circuit_to_gate.py +1 -1
  110. qiskit/converters/circuit_to_instruction.py +16 -29
  111. qiskit/converters/dag_to_circuit.py +7 -8
  112. qiskit/converters/dag_to_dagdependency.py +0 -1
  113. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  114. qiskit/converters/dagdependency_to_circuit.py +0 -6
  115. qiskit/converters/dagdependency_to_dag.py +0 -6
  116. qiskit/dagcircuit/collect_blocks.py +32 -20
  117. qiskit/dagcircuit/dagdependency.py +3 -37
  118. qiskit/dagcircuit/dagdependency_v2.py +5 -82
  119. qiskit/dagcircuit/dagnode.py +14 -2
  120. qiskit/passmanager/__init__.py +24 -6
  121. qiskit/passmanager/passmanager.py +26 -24
  122. qiskit/primitives/__init__.py +44 -35
  123. qiskit/primitives/backend_estimator_v2.py +102 -23
  124. qiskit/primitives/backend_sampler_v2.py +5 -20
  125. qiskit/primitives/base/__init__.py +4 -4
  126. qiskit/primitives/base/base_estimator.py +77 -82
  127. qiskit/primitives/base/base_primitive_job.py +2 -2
  128. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  129. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  130. qiskit/primitives/base/base_sampler.py +52 -60
  131. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  132. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  133. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  134. qiskit/primitives/containers/bindings_array.py +3 -1
  135. qiskit/primitives/containers/bit_array.py +23 -0
  136. qiskit/primitives/containers/data_bin.py +3 -1
  137. qiskit/primitives/containers/observables_array.py +19 -2
  138. qiskit/primitives/statevector_sampler.py +6 -8
  139. qiskit/primitives/utils.py +14 -189
  140. qiskit/providers/__init__.py +4 -130
  141. qiskit/providers/backend.py +11 -314
  142. qiskit/providers/basic_provider/__init__.py +3 -1
  143. qiskit/providers/basic_provider/basic_provider.py +29 -9
  144. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  145. qiskit/providers/exceptions.py +0 -33
  146. qiskit/providers/fake_provider/__init__.py +0 -37
  147. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  148. qiskit/qasm2/__init__.py +21 -6
  149. qiskit/qasm2/export.py +2 -10
  150. qiskit/qasm2/parse.py +11 -25
  151. qiskit/qasm3/__init__.py +5 -1
  152. qiskit/qasm3/ast.py +44 -0
  153. qiskit/qasm3/exporter.py +65 -27
  154. qiskit/qasm3/printer.py +35 -4
  155. qiskit/qpy/__init__.py +162 -19
  156. qiskit/qpy/binary_io/__init__.py +0 -1
  157. qiskit/qpy/binary_io/circuits.py +96 -116
  158. qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
  159. qiskit/qpy/binary_io/schedules.py +61 -388
  160. qiskit/qpy/binary_io/value.py +159 -33
  161. qiskit/qpy/common.py +10 -7
  162. qiskit/qpy/formats.py +41 -0
  163. qiskit/qpy/interface.py +29 -62
  164. qiskit/qpy/type_keys.py +58 -221
  165. qiskit/quantum_info/analysis/distance.py +3 -1
  166. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  167. qiskit/quantum_info/operators/operator.py +6 -2
  168. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  169. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  170. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  171. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  172. qiskit/quantum_info/states/densitymatrix.py +16 -6
  173. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  174. qiskit/quantum_info/states/statevector.py +16 -6
  175. qiskit/result/__init__.py +5 -17
  176. qiskit/result/models.py +18 -11
  177. qiskit/result/result.py +38 -134
  178. qiskit/result/sampled_expval.py +1 -2
  179. qiskit/result/utils.py +3 -4
  180. qiskit/synthesis/__init__.py +21 -1
  181. qiskit/synthesis/arithmetic/__init__.py +3 -1
  182. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  183. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  184. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  185. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  186. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  187. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  188. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  189. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  190. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  191. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  192. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  193. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  194. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  195. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  196. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  197. qiskit/synthesis/evolution/product_formula.py +44 -35
  198. qiskit/synthesis/evolution/qdrift.py +17 -24
  199. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  200. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  201. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  202. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  203. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  204. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  205. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  206. qiskit/synthesis/two_qubit/__init__.py +1 -0
  207. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  208. qiskit/transpiler/__init__.py +32 -232
  209. qiskit/transpiler/basepasses.py +20 -51
  210. qiskit/transpiler/layout.py +1 -1
  211. qiskit/transpiler/passes/__init__.py +4 -40
  212. qiskit/transpiler/passes/basis/basis_translator.py +5 -4
  213. qiskit/transpiler/passes/basis/decompose.py +1 -15
  214. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  215. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  216. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  217. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  218. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
  219. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  220. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  221. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  222. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  223. qiskit/transpiler/passes/optimization/__init__.py +2 -3
  224. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  225. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  226. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  227. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  228. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  229. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  230. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  231. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  232. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  233. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  234. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  235. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  236. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  237. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  238. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -2
  239. qiskit/transpiler/passes/routing/__init__.py +0 -1
  240. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  241. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  242. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  243. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  244. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  245. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  246. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  247. qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
  248. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
  249. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
  250. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  251. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  252. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  253. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
  254. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  255. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  256. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  257. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  258. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  259. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  260. qiskit/transpiler/passes/utils/__init__.py +0 -1
  261. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  262. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  263. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  264. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  265. qiskit/transpiler/passmanager.py +13 -0
  266. qiskit/transpiler/passmanager_config.py +5 -81
  267. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  268. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  269. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
  270. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  272. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  273. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  274. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  275. qiskit/transpiler/target.py +78 -524
  276. qiskit/user_config.py +8 -4
  277. qiskit/utils/__init__.py +13 -12
  278. qiskit/utils/deprecation.py +4 -112
  279. qiskit/utils/optionals.py +11 -4
  280. qiskit/utils/parallel.py +214 -87
  281. qiskit/utils/units.py +4 -1
  282. qiskit/visualization/__init__.py +3 -7
  283. qiskit/visualization/array.py +4 -1
  284. qiskit/visualization/bloch.py +1 -1
  285. qiskit/visualization/circuit/_utils.py +19 -19
  286. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  287. qiskit/visualization/circuit/matplotlib.py +13 -23
  288. qiskit/visualization/circuit/text.py +7 -3
  289. qiskit/visualization/counts_visualization.py +4 -0
  290. qiskit/visualization/dag_visualization.py +2 -1
  291. qiskit/visualization/gate_map.py +39 -154
  292. qiskit/visualization/library.py +4 -1
  293. qiskit/visualization/pass_manager_visualization.py +6 -2
  294. qiskit/visualization/state_visualization.py +19 -2
  295. qiskit/visualization/timeline/core.py +19 -13
  296. qiskit/visualization/timeline/interface.py +19 -18
  297. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  298. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
  299. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
  300. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
  301. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
  302. qiskit/assembler/__init__.py +0 -42
  303. qiskit/assembler/assemble_circuits.py +0 -451
  304. qiskit/assembler/assemble_schedules.py +0 -367
  305. qiskit/assembler/disassemble.py +0 -310
  306. qiskit/assembler/run_config.py +0 -77
  307. qiskit/circuit/bit.py +0 -106
  308. qiskit/circuit/classicalfunction/__init__.py +0 -152
  309. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  310. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  311. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  312. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  313. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  314. qiskit/circuit/classicalfunction/types.py +0 -18
  315. qiskit/circuit/classicalfunction/utils.py +0 -91
  316. qiskit/circuit/classicalregister.py +0 -57
  317. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  318. qiskit/circuit/quantumregister.py +0 -75
  319. qiskit/circuit/register.py +0 -246
  320. qiskit/compiler/assembler.py +0 -689
  321. qiskit/compiler/scheduler.py +0 -109
  322. qiskit/compiler/sequencer.py +0 -71
  323. qiskit/primitives/backend_estimator.py +0 -486
  324. qiskit/primitives/backend_sampler.py +0 -222
  325. qiskit/primitives/estimator.py +0 -172
  326. qiskit/primitives/sampler.py +0 -162
  327. qiskit/providers/backend_compat.py +0 -507
  328. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  333. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  335. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  336. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  339. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  341. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  343. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  344. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  345. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  348. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  349. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  350. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  351. qiskit/providers/fake_provider/fake_1q.py +0 -91
  352. qiskit/providers/fake_provider/fake_backend.py +0 -165
  353. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  354. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  355. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  356. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  357. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  358. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  359. qiskit/providers/models/__init__.py +0 -89
  360. qiskit/providers/models/backendconfiguration.py +0 -1040
  361. qiskit/providers/models/backendproperties.py +0 -535
  362. qiskit/providers/models/backendstatus.py +0 -104
  363. qiskit/providers/models/jobstatus.py +0 -77
  364. qiskit/providers/models/pulsedefaults.py +0 -305
  365. qiskit/providers/provider.py +0 -95
  366. qiskit/pulse/__init__.py +0 -158
  367. qiskit/pulse/builder.py +0 -2262
  368. qiskit/pulse/calibration_entries.py +0 -381
  369. qiskit/pulse/channels.py +0 -227
  370. qiskit/pulse/configuration.py +0 -245
  371. qiskit/pulse/exceptions.py +0 -45
  372. qiskit/pulse/filters.py +0 -309
  373. qiskit/pulse/instruction_schedule_map.py +0 -424
  374. qiskit/pulse/instructions/__init__.py +0 -67
  375. qiskit/pulse/instructions/acquire.py +0 -150
  376. qiskit/pulse/instructions/delay.py +0 -71
  377. qiskit/pulse/instructions/directives.py +0 -154
  378. qiskit/pulse/instructions/frequency.py +0 -135
  379. qiskit/pulse/instructions/instruction.py +0 -270
  380. qiskit/pulse/instructions/phase.py +0 -152
  381. qiskit/pulse/instructions/play.py +0 -99
  382. qiskit/pulse/instructions/reference.py +0 -100
  383. qiskit/pulse/instructions/snapshot.py +0 -82
  384. qiskit/pulse/library/__init__.py +0 -97
  385. qiskit/pulse/library/continuous.py +0 -430
  386. qiskit/pulse/library/pulse.py +0 -148
  387. qiskit/pulse/library/samplers/__init__.py +0 -15
  388. qiskit/pulse/library/samplers/decorators.py +0 -295
  389. qiskit/pulse/library/samplers/strategies.py +0 -71
  390. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  391. qiskit/pulse/library/waveform.py +0 -136
  392. qiskit/pulse/macros.py +0 -262
  393. qiskit/pulse/parameter_manager.py +0 -445
  394. qiskit/pulse/parser.py +0 -314
  395. qiskit/pulse/reference_manager.py +0 -58
  396. qiskit/pulse/schedule.py +0 -1854
  397. qiskit/pulse/transforms/__init__.py +0 -106
  398. qiskit/pulse/transforms/alignments.py +0 -406
  399. qiskit/pulse/transforms/base_transforms.py +0 -71
  400. qiskit/pulse/transforms/canonicalization.py +0 -498
  401. qiskit/pulse/transforms/dag.py +0 -122
  402. qiskit/pulse/utils.py +0 -149
  403. qiskit/qobj/__init__.py +0 -75
  404. qiskit/qobj/common.py +0 -81
  405. qiskit/qobj/converters/__init__.py +0 -18
  406. qiskit/qobj/converters/lo_config.py +0 -177
  407. qiskit/qobj/converters/pulse_instruction.py +0 -897
  408. qiskit/qobj/pulse_qobj.py +0 -709
  409. qiskit/qobj/qasm_qobj.py +0 -708
  410. qiskit/qobj/utils.py +0 -46
  411. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  412. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  413. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  414. qiskit/result/mitigation/utils.py +0 -217
  415. qiskit/scheduler/__init__.py +0 -40
  416. qiskit/scheduler/config.py +0 -37
  417. qiskit/scheduler/lowering.py +0 -187
  418. qiskit/scheduler/methods/__init__.py +0 -15
  419. qiskit/scheduler/methods/basic.py +0 -140
  420. qiskit/scheduler/schedule_circuit.py +0 -69
  421. qiskit/scheduler/sequence.py +0 -104
  422. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  423. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  424. qiskit/transpiler/passes/calibration/builders.py +0 -20
  425. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  426. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  427. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  428. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  429. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  430. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  431. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  432. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  433. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  434. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  435. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  436. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  437. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  438. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  439. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  440. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  441. qiskit/utils/deprecate_pulse.py +0 -119
  442. qiskit/utils/multiprocessing.py +0 -56
  443. qiskit/visualization/pulse_v2/__init__.py +0 -21
  444. qiskit/visualization/pulse_v2/core.py +0 -901
  445. qiskit/visualization/pulse_v2/device_info.py +0 -173
  446. qiskit/visualization/pulse_v2/drawings.py +0 -253
  447. qiskit/visualization/pulse_v2/events.py +0 -254
  448. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  449. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  450. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  451. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  452. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  453. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  454. qiskit/visualization/pulse_v2/interface.py +0 -459
  455. qiskit/visualization/pulse_v2/layouts.py +0 -387
  456. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  457. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  458. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  459. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  460. qiskit/visualization/pulse_v2/types.py +0 -242
  461. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  462. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -1,901 +0,0 @@
1
- # This code is part of Qiskit.
2
- #
3
- # (C) Copyright IBM 2020.
4
- #
5
- # This code is licensed under the Apache License, Version 2.0. You may
6
- # obtain a copy of this license in the LICENSE.txt file in the root directory
7
- # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
- #
9
- # Any modifications or derivative works of this code must retain this
10
- # copyright notice, and modified files need to carry a notice indicating
11
- # that they have been altered from the originals.
12
-
13
- """
14
- Core module of the pulse drawer.
15
-
16
- This module provides the `DrawerCanvas` which is a collection of `Chart` object.
17
- The `Chart` object is a collection of drawings. A user can assign multiple channels
18
- to a single chart instance. For example, we can define a chart for specific qubit
19
- and assign all related channels to the chart. This chart-channel mapping is defined by
20
- the function specified by ``layout.chart_channel_map`` of the stylesheet.
21
-
22
- Because this chart instance is decoupled from the coordinate system of the plotter,
23
- we can arbitrarily place charts on the plotter canvas, i.e. if we want to create 3D plot,
24
- each chart may be placed on the X-Z plane and charts are arranged along the Y-axis.
25
- Thus this data model maximizes the flexibility to generate an output image.
26
-
27
- The chart instance is not just a container of drawings, as it also performs
28
- data processing like binding abstract coordinates and truncating long pulses for an axis break.
29
- Each chart object has `.parent` which points to the `DrawerCanvas` instance so that
30
- each child chart can refer to the global figure settings such as time range and axis break.
31
-
32
-
33
- Initialization
34
- ~~~~~~~~~~~~~~
35
- The `DataCanvas` and `Chart` are not exposed to users as they are implicitly
36
- initialized in the interface function. It is noteworthy that the data canvas is agnostic
37
- to plotters. This means once the canvas instance is initialized we can reuse this data
38
- among multiple plotters. The canvas is initialized with a stylesheet and quantum backend
39
- information :py:class:`~qiskit.visualization.pulse_v2.device_info.DrawerBackendInfo`.
40
- Chart instances are automatically generated when pulse program is loaded.
41
-
42
- ```python
43
- canvas = DrawerCanvas(stylesheet=stylesheet, device=device)
44
- canvas.load_program(sched)
45
- canvas.update()
46
- ```
47
-
48
- Once all properties are set, `.update` method is called to apply changes to drawings.
49
- If the `DrawDataContainer` is initialized without backend information, the output shows
50
- the time in units of the system cycle time `dt` and the frequencies are initialized to zero.
51
-
52
- Update
53
- ~~~~~~
54
- To update the image, a user can set new values to canvas and then call the `.update` method.
55
-
56
- ```python
57
- canvas.set_time_range(2000, 3000, seconds=False)
58
- canvas.update()
59
- ```
60
-
61
- All stored drawings are updated accordingly. The plotter API can access to
62
- drawings with `.collections` property of chart instance. This returns
63
- an iterator of drawing with the unique data key.
64
- If a plotter provides object handler for plotted shapes, the plotter API can manage
65
- the lookup table of the handler and the drawing by using this data key.
66
- """
67
-
68
- from __future__ import annotations
69
-
70
- from collections.abc import Iterator, Sequence
71
- from copy import deepcopy
72
- from enum import Enum
73
- from functools import partial
74
- from itertools import chain
75
-
76
- import numpy as np
77
- from qiskit import pulse
78
- from qiskit.pulse.transforms import target_qobj_transform
79
- from qiskit.visualization.exceptions import VisualizationError
80
- from qiskit.visualization.pulse_v2 import events, types, drawings, device_info
81
- from qiskit.visualization.pulse_v2.stylesheet import QiskitPulseStyle
82
-
83
-
84
- class DrawerCanvas:
85
- """Collection of `Chart` and configuration data.
86
-
87
- Pulse channels are associated with some `Chart` instance and
88
- drawing data object are stored in the `Chart` instance.
89
-
90
- Device, stylesheet, and some user generators are stored in the `DrawingCanvas`
91
- and `Chart` instances are also attached to the `DrawerCanvas` as children.
92
- Global configurations are accessed by those children to modify
93
- the appearance of the `Chart` output.
94
- """
95
-
96
- def __init__(self, stylesheet: QiskitPulseStyle, device: device_info.DrawerBackendInfo):
97
- """Create new data container with backend system information.
98
-
99
- Args:
100
- stylesheet: Stylesheet to decide appearance of output image.
101
- device: Backend information to run the program.
102
- """
103
- # stylesheet
104
- self.formatter = stylesheet.formatter
105
- self.generator = stylesheet.generator
106
- self.layout = stylesheet.layout
107
-
108
- # device info
109
- self.device = device
110
-
111
- # chart
112
- self.global_charts = Chart(parent=self, name="global")
113
- self.charts: list[Chart] = []
114
-
115
- # visible controls
116
- self.disable_chans: set[pulse.channels.Channel] = set()
117
- self.disable_types: set[str] = set()
118
-
119
- # data scaling
120
- self.chan_scales: dict[
121
- pulse.channels.DriveChannel
122
- | pulse.channels.MeasureChannel
123
- | pulse.channels.ControlChannel
124
- | pulse.channels.AcquireChannel,
125
- float,
126
- ] = {}
127
-
128
- # global time
129
- self._time_range = (0, 0)
130
- self._time_breaks: list[tuple[int, int]] = []
131
-
132
- # title
133
- self.fig_title = ""
134
-
135
- @property
136
- def time_range(self) -> tuple[int, int]:
137
- """Return current time range to draw.
138
-
139
- Calculate net duration and add side margin to edge location.
140
-
141
- Returns:
142
- Time window considering side margin.
143
- """
144
- t0, t1 = self._time_range
145
-
146
- total_time_elimination = 0
147
- for t0b, t1b in self.time_breaks:
148
- if t1b > t0 and t0b < t1:
149
- total_time_elimination += t1b - t0b
150
- net_duration = t1 - t0 - total_time_elimination
151
-
152
- new_t0 = t0 - net_duration * self.formatter["margin.left_percent"]
153
- new_t1 = t1 + net_duration * self.formatter["margin.right_percent"]
154
-
155
- return new_t0, new_t1
156
-
157
- @time_range.setter
158
- def time_range(self, new_range: tuple[int, int]):
159
- """Update time range to draw."""
160
- self._time_range = new_range
161
-
162
- @property
163
- def time_breaks(self) -> list[tuple[int, int]]:
164
- """Return time breaks with time range.
165
-
166
- If an edge of time range is in the axis break period,
167
- the axis break period is recalculated.
168
-
169
- Raises:
170
- VisualizationError: When axis break is greater than time window.
171
-
172
- Returns:
173
- List of axis break periods considering the time window edges.
174
- """
175
- t0, t1 = self._time_range
176
-
177
- axis_breaks = []
178
- for t0b, t1b in self._time_breaks:
179
- if t0b >= t1 or t1b <= t0:
180
- # skip because break period is outside of time window
181
- continue
182
-
183
- if t0b < t0 and t1b > t1:
184
- raise VisualizationError(
185
- "Axis break is greater than time window. Nothing will be drawn."
186
- )
187
- if t0b < t0 < t1b:
188
- if t1b - t0 > self.formatter["axis_break.length"]:
189
- new_t0 = t0 + 0.5 * self.formatter["axis_break.max_length"]
190
- axis_breaks.append((new_t0, t1b))
191
- continue
192
- if t0b < t1 < t1b:
193
- if t1 - t0b > self.formatter["axis_break.length"]:
194
- new_t1 = t1 - 0.5 * self.formatter["axis_break.max_length"]
195
- axis_breaks.append((t0b, new_t1))
196
- continue
197
- axis_breaks.append((t0b, t1b))
198
-
199
- return axis_breaks
200
-
201
- @time_breaks.setter
202
- def time_breaks(self, new_breaks: list[tuple[int, int]]):
203
- """Set new time breaks."""
204
- self._time_breaks = sorted(new_breaks, key=lambda x: x[0])
205
-
206
- def load_program(
207
- self,
208
- program: pulse.Waveform | pulse.SymbolicPulse | pulse.Schedule | pulse.ScheduleBlock,
209
- ):
210
- """Load a program to draw.
211
-
212
- Args:
213
- program: Pulse program or waveform to draw.
214
-
215
- Raises:
216
- VisualizationError: When input program is invalid data format.
217
- """
218
- if isinstance(program, (pulse.Schedule, pulse.ScheduleBlock)):
219
- self._schedule_loader(program)
220
- elif isinstance(program, (pulse.Waveform, pulse.SymbolicPulse)):
221
- self._waveform_loader(program)
222
- else:
223
- raise VisualizationError(f"Data type {type(program)} is not supported.")
224
-
225
- # update time range
226
- self.set_time_range(0, program.duration, seconds=False)
227
-
228
- # set title
229
- self.fig_title = self.layout["figure_title"](program=program, device=self.device)
230
-
231
- def _waveform_loader(
232
- self,
233
- program: pulse.Waveform | pulse.SymbolicPulse,
234
- ):
235
- """Load Waveform instance.
236
-
237
- This function is sub-routine of py:method:`load_program`.
238
-
239
- Args:
240
- program: `Waveform` to draw.
241
- """
242
- chart = Chart(parent=self)
243
-
244
- # add waveform data
245
- fake_inst = pulse.Play(program, types.WaveformChannel())
246
- inst_data = types.PulseInstruction(
247
- t0=0,
248
- dt=self.device.dt,
249
- frame=types.PhaseFreqTuple(phase=0, freq=0),
250
- inst=fake_inst,
251
- is_opaque=program.is_parameterized(),
252
- )
253
- for gen in self.generator["waveform"]:
254
- obj_generator = partial(gen, formatter=self.formatter, device=self.device)
255
- for data in obj_generator(inst_data):
256
- chart.add_data(data)
257
-
258
- self.charts.append(chart)
259
-
260
- def _schedule_loader(self, program: pulse.Schedule | pulse.ScheduleBlock):
261
- """Load Schedule instance.
262
-
263
- This function is sub-routine of py:method:`load_program`.
264
-
265
- Args:
266
- program: `Schedule` to draw.
267
- """
268
- program = target_qobj_transform(program, remove_directives=False)
269
-
270
- # initialize scale values
271
- self.chan_scales = {}
272
- for chan in program.channels:
273
- if isinstance(chan, pulse.channels.DriveChannel):
274
- self.chan_scales[chan] = self.formatter["channel_scaling.drive"]
275
- elif isinstance(chan, pulse.channels.MeasureChannel):
276
- self.chan_scales[chan] = self.formatter["channel_scaling.measure"]
277
- elif isinstance(chan, pulse.channels.ControlChannel):
278
- self.chan_scales[chan] = self.formatter["channel_scaling.control"]
279
- elif isinstance(chan, pulse.channels.AcquireChannel):
280
- self.chan_scales[chan] = self.formatter["channel_scaling.acquire"]
281
- else:
282
- self.chan_scales[chan] = 1.0
283
-
284
- # create charts
285
- mapper = self.layout["chart_channel_map"]
286
- for name, chans in mapper(
287
- channels=program.channels, formatter=self.formatter, device=self.device
288
- ):
289
-
290
- chart = Chart(parent=self, name=name)
291
-
292
- # add standard pulse instructions
293
- for chan in chans:
294
- chart.load_program(program=program, chan=chan)
295
-
296
- # add barriers
297
- barrier_sched = program.filter(
298
- instruction_types=[pulse.instructions.RelativeBarrier], channels=chans
299
- )
300
- for t0, _ in barrier_sched.instructions:
301
- inst_data = types.BarrierInstruction(t0, self.device.dt, chans)
302
- for gen in self.generator["barrier"]:
303
- obj_generator = partial(gen, formatter=self.formatter, device=self.device)
304
- for data in obj_generator(inst_data):
305
- chart.add_data(data)
306
-
307
- # add chart axis
308
- chart_axis = types.ChartAxis(name=chart.name, channels=chart.channels)
309
- for gen in self.generator["chart"]:
310
- obj_generator = partial(gen, formatter=self.formatter, device=self.device)
311
- for data in obj_generator(chart_axis):
312
- chart.add_data(data)
313
-
314
- self.charts.append(chart)
315
-
316
- # add snapshot data to global
317
- snapshot_sched = program.filter(instruction_types=[pulse.instructions.Snapshot])
318
- for t0, inst in snapshot_sched.instructions:
319
- inst_data = types.SnapshotInstruction(t0, self.device.dt, inst.label, inst.channels)
320
- for gen in self.generator["snapshot"]:
321
- obj_generator = partial(gen, formatter=self.formatter, device=self.device)
322
- for data in obj_generator(inst_data):
323
- self.global_charts.add_data(data)
324
-
325
- # calculate axis break
326
- self.time_breaks = self._calculate_axis_break(program)
327
-
328
- def _calculate_axis_break(self, program: pulse.Schedule) -> list[tuple[int, int]]:
329
- """A helper function to calculate axis break of long pulse sequence.
330
-
331
- Args:
332
- program: A schedule to calculate axis break.
333
-
334
- Returns:
335
- List of axis break periods.
336
- """
337
- axis_breaks = []
338
-
339
- edges = set()
340
- for t0, t1 in chain.from_iterable(program.timeslots.values()):
341
- if t1 - t0 > 0:
342
- edges.add(t0)
343
- edges.add(t1)
344
- edges = sorted(edges)
345
-
346
- for t0, t1 in zip(edges[:-1], edges[1:]):
347
- if t1 - t0 > self.formatter["axis_break.length"]:
348
- t_l = t0 + 0.5 * self.formatter["axis_break.max_length"]
349
- t_r = t1 - 0.5 * self.formatter["axis_break.max_length"]
350
- axis_breaks.append((t_l, t_r))
351
-
352
- return axis_breaks
353
-
354
- def set_time_range(self, t_start: float, t_end: float, seconds: bool = True):
355
- """Set time range to draw.
356
-
357
- All child chart instances are updated when time range is updated.
358
-
359
- Args:
360
- t_start: Left boundary of drawing in units of cycle time or real time.
361
- t_end: Right boundary of drawing in units of cycle time or real time.
362
- seconds: Set `True` if times are given in SI unit rather than dt.
363
-
364
- Raises:
365
- VisualizationError: When times are given in float without specifying dt.
366
- """
367
- # convert into nearest cycle time
368
- if seconds:
369
- if self.device.dt is not None:
370
- t_start = int(np.round(t_start / self.device.dt))
371
- t_end = int(np.round(t_end / self.device.dt))
372
- else:
373
- raise VisualizationError(
374
- "Setting time range with SI units requires backend `dt` information."
375
- )
376
- self.time_range = (t_start, t_end)
377
-
378
- def set_disable_channel(self, channel: pulse.channels.Channel, remove: bool = True):
379
- """Interface method to control visibility of pulse channels.
380
-
381
- Specified object in the blocked list will not be shown.
382
-
383
- Args:
384
- channel: A pulse channel object to disable.
385
- remove: Set `True` to disable, set `False` to enable.
386
- """
387
- if remove:
388
- self.disable_chans.add(channel)
389
- else:
390
- self.disable_chans.discard(channel)
391
-
392
- def set_disable_type(self, data_type: types.DataTypes, remove: bool = True):
393
- """Interface method to control visibility of data types.
394
-
395
- Specified object in the blocked list will not be shown.
396
-
397
- Args:
398
- data_type: A drawing data type to disable.
399
- remove: Set `True` to disable, set `False` to enable.
400
- """
401
- if isinstance(data_type, Enum):
402
- data_type_str = str(data_type.value)
403
- else:
404
- data_type_str = data_type
405
-
406
- if remove:
407
- self.disable_types.add(data_type_str)
408
- else:
409
- self.disable_types.discard(data_type_str)
410
-
411
- def update(self):
412
- """Update all associated charts and generate actual drawing data from template object.
413
-
414
- This method should be called before the canvas is passed to the plotter.
415
- """
416
- for chart in self.charts:
417
- chart.update()
418
-
419
-
420
- class Chart:
421
- """A collection of drawing to be shown on the same line.
422
-
423
- Multiple pulse channels can be assigned to a single `Chart`.
424
- The parent `DrawerCanvas` should be specified to refer to the current user preference.
425
-
426
- The vertical value of each `Chart` should be in the range [-1, 1].
427
- This truncation should be performed in the plotter interface.
428
- """
429
-
430
- # unique index of chart
431
- chart_index = 0
432
-
433
- # list of waveform type names
434
- waveform_types = [
435
- str(types.WaveformType.REAL.value),
436
- str(types.WaveformType.IMAG.value),
437
- str(types.WaveformType.OPAQUE.value),
438
- ]
439
-
440
- def __init__(self, parent: DrawerCanvas, name: str | None = None):
441
- """Create new chart.
442
-
443
- Args:
444
- parent: `DrawerCanvas` that this `Chart` instance belongs to.
445
- name: Name of this `Chart` instance.
446
- """
447
- self.parent = parent
448
-
449
- # data stored in this channel
450
- self._collections: dict[str, drawings.ElementaryData] = {}
451
- self._output_dataset: dict[str, drawings.ElementaryData] = {}
452
-
453
- # channel metadata
454
- self.index = self._cls_index()
455
- self.name = name or ""
456
- self._channels: set[pulse.channels.Channel] = set()
457
-
458
- # vertical axis information
459
- self.vmax = 0
460
- self.vmin = 0
461
- self.scale = 1.0
462
-
463
- self._increment_cls_index()
464
-
465
- def add_data(self, data: drawings.ElementaryData):
466
- """Add drawing to collections.
467
-
468
- If the given object already exists in the collections,
469
- this interface replaces the old object instead of adding new entry.
470
-
471
- Args:
472
- data: New drawing to add.
473
- """
474
- self._collections[data.data_key] = data
475
-
476
- def load_program(self, program: pulse.Schedule, chan: pulse.channels.Channel):
477
- """Load pulse schedule.
478
-
479
- This method internally generates `ChannelEvents` to parse the program
480
- for the specified pulse channel. This method is called once
481
-
482
- Args:
483
- program: Pulse schedule to load.
484
- chan: A pulse channels associated with this instance.
485
- """
486
- chan_events = events.ChannelEvents.load_program(program, chan)
487
- chan_events.set_config(
488
- dt=self.parent.device.dt,
489
- init_frequency=self.parent.device.get_channel_frequency(chan),
490
- init_phase=0,
491
- )
492
-
493
- # create objects associated with waveform
494
- for gen in self.parent.generator["waveform"]:
495
- waveforms = chan_events.get_waveforms()
496
- obj_generator = partial(gen, formatter=self.parent.formatter, device=self.parent.device)
497
- drawing_items = [obj_generator(waveform) for waveform in waveforms]
498
- for drawing_item in list(chain.from_iterable(drawing_items)):
499
- self.add_data(drawing_item)
500
-
501
- # create objects associated with frame change
502
- for gen in self.parent.generator["frame"]:
503
- frames = chan_events.get_frame_changes()
504
- obj_generator = partial(gen, formatter=self.parent.formatter, device=self.parent.device)
505
- drawing_items = [obj_generator(frame) for frame in frames]
506
- for drawing_item in list(chain.from_iterable(drawing_items)):
507
- self.add_data(drawing_item)
508
-
509
- self._channels.add(chan)
510
-
511
- def update(self):
512
- """Update vertical data range and scaling factor of this chart.
513
-
514
- Those parameters are updated based on current time range in the parent canvas.
515
- """
516
- self._output_dataset.clear()
517
- self.vmax = 0
518
- self.vmin = 0
519
-
520
- # waveform
521
- for key, data in self._collections.items():
522
- if data.data_type not in Chart.waveform_types:
523
- continue
524
-
525
- # truncate, assume no abstract coordinate in waveform sample
526
- trunc_x, trunc_y = self._truncate_data(data)
527
-
528
- # no available data points
529
- if trunc_x.size == 0 or trunc_y.size == 0:
530
- continue
531
-
532
- # update y range
533
- scale = min(self.parent.chan_scales.get(chan, 1.0) for chan in data.channels)
534
- self.vmax = max(scale * np.max(trunc_y), self.vmax)
535
- self.vmin = min(scale * np.min(trunc_y), self.vmin)
536
-
537
- # generate new data
538
- new_data = deepcopy(data)
539
- new_data.xvals = trunc_x
540
- new_data.yvals = trunc_y
541
-
542
- self._output_dataset[key] = new_data
543
-
544
- # calculate chart level scaling factor
545
- if self.parent.formatter["control.auto_chart_scaling"]:
546
- max_val = max(
547
- abs(self.vmax), abs(self.vmin), self.parent.formatter["general.vertical_resolution"]
548
- )
549
- self.scale = min(1.0 / max_val, self.parent.formatter["general.max_scale"])
550
- else:
551
- self.scale = 1.0
552
-
553
- # update vertical range with scaling and limitation
554
- self.vmax = max(
555
- self.scale * self.vmax, self.parent.formatter["channel_scaling.pos_spacing"]
556
- )
557
-
558
- self.vmin = min(
559
- self.scale * self.vmin, self.parent.formatter["channel_scaling.neg_spacing"]
560
- )
561
-
562
- # other data
563
- for key, data in self._collections.items():
564
- if data.data_type in Chart.waveform_types:
565
- continue
566
-
567
- # truncate
568
- trunc_x, trunc_y = self._truncate_data(data)
569
-
570
- # no available data points
571
- if trunc_x.size == 0 or trunc_y.size == 0:
572
- continue
573
-
574
- # generate new data
575
- new_data = deepcopy(data)
576
- new_data.xvals = trunc_x
577
- new_data.yvals = trunc_y
578
-
579
- self._output_dataset[key] = new_data
580
-
581
- @property
582
- def is_active(self) -> bool:
583
- """Check if there is any active waveform data in this entry.
584
-
585
- Returns:
586
- Return `True` if there is any visible waveform in this chart.
587
- """
588
- for data in self._output_dataset.values():
589
- if data.data_type in Chart.waveform_types and self._check_visible(data):
590
- return True
591
- return False
592
-
593
- @property
594
- def collections(self) -> Iterator[tuple[str, drawings.ElementaryData]]:
595
- """Return currently active entries from drawing data collection.
596
-
597
- The object is returned with unique name as a key of an object handler.
598
- When the horizontal coordinate contains `AbstractCoordinate`,
599
- the value is substituted by current time range preference.
600
- """
601
- for name, data in self._output_dataset.items():
602
- # prepare unique name
603
- unique_id = f"chart{self.index:d}_{name}"
604
- if self._check_visible(data):
605
- yield unique_id, data
606
-
607
- @property
608
- def channels(self) -> list[pulse.channels.Channel]:
609
- """Return a list of channels associated with this chart.
610
-
611
- Returns:
612
- List of channels associated with this chart.
613
- """
614
- return list(self._channels)
615
-
616
- def _truncate_data(self, data: drawings.ElementaryData) -> tuple[np.ndarray, np.ndarray]:
617
- """A helper function to truncate drawings according to time breaks.
618
-
619
- # TODO: move this function to common module to support axis break for timeline.
620
-
621
- Args:
622
- data: Drawing object to truncate.
623
-
624
- Returns:
625
- Set of truncated numpy arrays for x and y coordinate.
626
- """
627
- xvals = self._bind_coordinate(data.xvals)
628
- yvals = self._bind_coordinate(data.yvals)
629
-
630
- if isinstance(data, drawings.BoxData):
631
- # truncate box data. these object don't require interpolation at axis break.
632
- return self._truncate_boxes(xvals, yvals)
633
- elif data.data_type in [types.LabelType.PULSE_NAME, types.LabelType.OPAQUE_BOXTEXT]:
634
- # truncate pulse labels. these objects are not removed by truncation.
635
- return self._truncate_pulse_labels(xvals, yvals)
636
- else:
637
- # other objects
638
- return self._truncate_vectors(xvals, yvals)
639
-
640
- def _truncate_pulse_labels(
641
- self, xvals: np.ndarray, yvals: np.ndarray
642
- ) -> tuple[np.ndarray, np.ndarray]:
643
- """A helper function to remove text according to time breaks.
644
-
645
- Args:
646
- xvals: Time points.
647
- yvals: Data points.
648
-
649
- Returns:
650
- Set of truncated numpy arrays for x and y coordinate.
651
- """
652
- xpos = xvals[0]
653
- t0, t1 = self.parent.time_range
654
-
655
- if xpos < t0 or xpos > t1:
656
- return np.array([]), np.array([])
657
- offset_accumulation = 0
658
- for tl, tr in self.parent.time_breaks:
659
- if xpos < tl:
660
- return np.array([xpos - offset_accumulation]), yvals
661
- if tl < xpos < tr:
662
- return np.array([tl - offset_accumulation]), yvals
663
- else:
664
- offset_accumulation += tr - tl
665
- return np.array([xpos - offset_accumulation]), yvals
666
-
667
- def _truncate_boxes(
668
- self, xvals: np.ndarray, yvals: np.ndarray
669
- ) -> tuple[np.ndarray, np.ndarray]:
670
- """A helper function to clip box object according to time breaks.
671
-
672
- Args:
673
- xvals: Time points.
674
- yvals: Data points.
675
-
676
- Returns:
677
- Set of truncated numpy arrays for x and y coordinate.
678
- """
679
- x0, x1 = xvals
680
- t0, t1 = self.parent.time_range
681
-
682
- if x1 < t0 or x0 > t1:
683
- # out of drawing range
684
- return np.array([]), np.array([])
685
-
686
- # clip outside
687
- x0 = max(t0, x0)
688
- x1 = min(t1, x1)
689
-
690
- offset_accumulate = 0
691
- for tl, tr in self.parent.time_breaks:
692
- tl -= offset_accumulate
693
- tr -= offset_accumulate
694
-
695
- #
696
- # truncate, there are 5 patterns wrt the relative position of truncation and xvals
697
- #
698
- if x1 < tl:
699
- break
700
-
701
- if tl < x0 and tr > x1:
702
- # case 1: all data points are truncated
703
- # : +-----+ :
704
- # : |/////| :
705
- # -----:---+-----+---:-----
706
- # l 0 1 r
707
- return np.array([]), np.array([])
708
- elif tl < x1 < tr:
709
- # case 2: t < tl, right side is truncated
710
- # +---:-----+ :
711
- # | ://///| :
712
- # -----+---:-----+---:-----
713
- # 0 l 1 r
714
- x1 = tl
715
- elif tl < x0 < tr:
716
- # case 3: tr > t, left side is truncated
717
- # : +-----:---+
718
- # : |/////: |
719
- # -----:---+-----:---+-----
720
- # l 0 r 1
721
- x0 = tl
722
- x1 = tl + t1 - tr
723
- elif tl > x0 and tr < x1:
724
- # case 4: tr > t > tl, middle part is truncated
725
- # +---:-----:---+
726
- # | ://///: |
727
- # -----+---:-----:---+-----
728
- # 0 l r 1
729
- x1 -= tr - tl
730
- elif tr < x0:
731
- # case 5: tr > t > tl, nothing truncated but need time shift
732
- # : : +---+
733
- # : : | |
734
- # -----:---:-----+---+-----
735
- # l r 0 1
736
- x0 -= tr - tl
737
- x1 -= tr - tl
738
-
739
- offset_accumulate += tr - tl
740
-
741
- return np.asarray([x0, x1], dtype=float), yvals
742
-
743
- def _truncate_vectors(
744
- self, xvals: np.ndarray, yvals: np.ndarray
745
- ) -> tuple[np.ndarray, np.ndarray]:
746
- """A helper function to remove sequential data points according to time breaks.
747
-
748
- Args:
749
- xvals: Time points.
750
- yvals: Data points.
751
-
752
- Returns:
753
- Set of truncated numpy arrays for x and y coordinate.
754
- """
755
- xvals = np.asarray(xvals, dtype=float)
756
- yvals = np.asarray(yvals, dtype=float)
757
- t0, t1 = self.parent.time_range
758
-
759
- if max(xvals) < t0 or min(xvals) > t1:
760
- # out of drawing range
761
- return np.array([]), np.array([])
762
-
763
- if min(xvals) < t0:
764
- # truncate x less than left limit
765
- inds = xvals > t0
766
- yvals = np.append(np.interp(t0, xvals, yvals), yvals[inds])
767
- xvals = np.append(t0, xvals[inds])
768
-
769
- if max(xvals) > t1:
770
- # truncate x larger than right limit
771
- inds = xvals < t1
772
- yvals = np.append(yvals[inds], np.interp(t1, xvals, yvals))
773
- xvals = np.append(xvals[inds], t1)
774
-
775
- # time breaks
776
- trunc_xvals = [xvals]
777
- trunc_yvals = [yvals]
778
- offset_accumulate = 0
779
- for tl, tr in self.parent.time_breaks:
780
- sub_xs = trunc_xvals.pop()
781
- sub_ys = trunc_yvals.pop()
782
- tl -= offset_accumulate
783
- tr -= offset_accumulate
784
-
785
- #
786
- # truncate, there are 5 patterns wrt the relative position of truncation and xvals
787
- #
788
- min_xs = min(sub_xs)
789
- max_xs = max(sub_xs)
790
- if max_xs < tl:
791
- trunc_xvals.append(sub_xs)
792
- trunc_yvals.append(sub_ys)
793
- break
794
-
795
- if tl < min_xs and tr > max_xs:
796
- # case 1: all data points are truncated
797
- # : +-----+ :
798
- # : |/////| :
799
- # -----:---+-----+---:-----
800
- # l min max r
801
- return np.array([]), np.array([])
802
- elif tl < max_xs < tr:
803
- # case 2: t < tl, right side is truncated
804
- # +---:-----+ :
805
- # | ://///| :
806
- # -----+---:-----+---:-----
807
- # min l max r
808
- inds = sub_xs > tl
809
- trunc_xvals.append(np.append(tl, sub_xs[inds]) - (tl - min_xs))
810
- trunc_yvals.append(np.append(np.interp(tl, sub_xs, sub_ys), sub_ys[inds]))
811
- elif tl < min_xs < tr:
812
- # case 3: tr > t, left side is truncated
813
- # : +-----:---+
814
- # : |/////: |
815
- # -----:---+-----:---+-----
816
- # l min r max
817
- inds = sub_xs < tr
818
- trunc_xvals.append(np.append(sub_xs[inds], tr))
819
- trunc_yvals.append(np.append(sub_ys[inds], np.interp(tr, sub_xs, sub_ys)))
820
- elif tl > min_xs and tr < max_xs:
821
- # case 4: tr > t > tl, middle part is truncated
822
- # +---:-----:---+
823
- # | ://///: |
824
- # -----+---:-----:---+-----
825
- # min l r max
826
- inds0 = sub_xs < tl
827
- trunc_xvals.append(np.append(sub_xs[inds0], tl))
828
- trunc_yvals.append(np.append(sub_ys[inds0], np.interp(tl, sub_xs, sub_ys)))
829
- inds1 = sub_xs > tr
830
- trunc_xvals.append(np.append(tr, sub_xs[inds1]) - (tr - tl))
831
- trunc_yvals.append(np.append(np.interp(tr, sub_xs, sub_ys), sub_ys[inds1]))
832
- elif tr < min_xs:
833
- # case 5: tr > t > tl, nothing truncated but need time shift
834
- # : : +---+
835
- # : : | |
836
- # -----:---:-----+---+-----
837
- # l r 0 1
838
- trunc_xvals.append(sub_xs - (tr - tl))
839
- trunc_yvals.append(sub_ys)
840
- else:
841
- # no need to truncate
842
- trunc_xvals.append(sub_xs)
843
- trunc_yvals.append(sub_ys)
844
- offset_accumulate += tr - tl
845
-
846
- new_x = np.concatenate(trunc_xvals)
847
- new_y = np.concatenate(trunc_yvals)
848
-
849
- return np.asarray(new_x, dtype=float), np.asarray(new_y, dtype=float)
850
-
851
- def _bind_coordinate(self, vals: Sequence[types.Coordinate] | np.ndarray) -> np.ndarray:
852
- """A helper function to bind actual coordinates to an `AbstractCoordinate`.
853
-
854
- Args:
855
- vals: Sequence of coordinate objects associated with a drawing.
856
-
857
- Returns:
858
- Numpy data array with substituted values.
859
- """
860
-
861
- def substitute(val: types.Coordinate):
862
- if val == types.AbstractCoordinate.LEFT:
863
- return self.parent.time_range[0]
864
- if val == types.AbstractCoordinate.RIGHT:
865
- return self.parent.time_range[1]
866
- if val == types.AbstractCoordinate.TOP:
867
- return self.vmax
868
- if val == types.AbstractCoordinate.BOTTOM:
869
- return self.vmin
870
- raise VisualizationError(f"Coordinate {val} is not supported.")
871
-
872
- try:
873
- return np.asarray(vals, dtype=float)
874
- except (TypeError, ValueError):
875
- return np.asarray(list(map(substitute, vals)), dtype=float)
876
-
877
- def _check_visible(self, data: drawings.ElementaryData) -> bool:
878
- """A helper function to check if the data is visible.
879
-
880
- Args:
881
- data: Drawing object to test.
882
-
883
- Returns:
884
- Return `True` if the data is visible.
885
- """
886
- is_active_type = data.data_type not in self.parent.disable_types
887
- is_active_chan = any(chan not in self.parent.disable_chans for chan in data.channels)
888
- if not (is_active_type and is_active_chan):
889
- return False
890
-
891
- return True
892
-
893
- @classmethod
894
- def _increment_cls_index(cls):
895
- """Increment counter of the chart."""
896
- cls.chart_index += 1
897
-
898
- @classmethod
899
- def _cls_index(cls) -> int:
900
- """Return counter index of the chart."""
901
- return cls.chart_index