qplotter 1.6.0b3__tar.gz → 1.6.2__tar.gz

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 (420) hide show
  1. {qplotter-1.6.0b3 → qplotter-1.6.2}/CHANGELOG.md +135 -4
  2. {qplotter-1.6.0b3 → qplotter-1.6.2}/CONTRIBUTING.md +1 -1
  3. {qplotter-1.6.0b3 → qplotter-1.6.2}/MANIFEST.in +1 -0
  4. {qplotter-1.6.0b3 → qplotter-1.6.2}/PKG-INFO +26 -12
  5. {qplotter-1.6.0b3 → qplotter-1.6.2}/README.md +23 -9
  6. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/architecture.md +10 -2
  7. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/demo-data.md +7 -0
  8. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/distribution.md +60 -20
  9. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/trusted-live-reader.md +18 -2
  10. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/user-guide.md +40 -13
  11. {qplotter-1.6.0b3 → qplotter-1.6.2}/pyproject.toml +8 -3
  12. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/benchmark_plot_launch.py +23 -10
  13. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/profile_trusted_reads.py +14 -4
  14. qplotter-1.6.2/scripts/revalidate_published_release.py +81 -0
  15. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/validate_compiler_free_install.py +14 -2
  16. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/validate_distribution.py +16 -1
  17. qplotter-1.6.2/scripts/write_build_info.py +32 -0
  18. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/__main__.py +2 -1
  19. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/_auxiliary_paths.py +4 -0
  20. qplotter-1.6.2/src/qplot/_build_info.json +1 -0
  21. qplotter-1.6.2/src/qplot/_metadata.py +84 -0
  22. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/config.py +7 -2
  23. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/config_schema.json +44 -0
  24. qplotter-1.6.2/src/qplot/configuration/fonts.py +3 -0
  25. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/themes/_base.py +18 -5
  26. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/LoadFromDB.py +14 -1
  27. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/_trusted_live_helper.py +9 -4
  28. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/database.py +10 -0
  29. qplotter-1.6.2/src/qplot/datahandling/parameter_data.py +345 -0
  30. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/qcodes_cache.py +17 -1
  31. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/readonly.py +32 -0
  32. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_array_preview.py +68 -12
  33. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_derived_rendering.py +33 -21
  34. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_heatmap.py +11 -6
  35. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_live.py +13 -2
  36. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_live_queries.py +38 -7
  37. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_live_service.py +26 -1
  38. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_plot.py +34 -9
  39. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/diagnostics.py +42 -7
  40. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/testdata.py +121 -14
  41. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/finite_means.py +12 -3
  42. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/general.py +19 -7
  43. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/heatmap_geometry.py +16 -6
  44. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/plot_tools.py +152 -31
  45. qplotter-1.6.2/src/qplot/tools/sample_statistics.py +120 -0
  46. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/worker.py +93 -28
  47. qplotter-1.6.2/src/qplot/windows/_auto_plot.py +201 -0
  48. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_commands.py +14 -14
  49. qplotter-1.6.2/src/qplot/windows/_csv_filenames.py +19 -0
  50. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_database_actions.py +39 -9
  51. qplotter-1.6.2/src/qplot/windows/_dataset_statistics.py +36 -0
  52. qplotter-1.6.2/src/qplot/windows/_display_precision.py +49 -0
  53. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_dragdrop.py +4 -5
  54. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_help.py +43 -2
  55. qplotter-1.6.2/src/qplot/windows/_mixed_appearance.py +303 -0
  56. qplotter-1.6.2/src/qplot/windows/_mixed_plots.py +462 -0
  57. qplotter-1.6.2/src/qplot/windows/_native_averaging.py +323 -0
  58. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_native_transforms.py +224 -19
  59. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot1d_snap.py +7 -3
  60. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot1d_traces.py +74 -21
  61. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot2d_colorbar.py +5 -4
  62. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot2d_layers.py +144 -50
  63. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plotWin.py +125 -36
  64. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_actions.py +182 -78
  65. qplotter-1.6.2/src/qplot/windows/_plot_annotation.py +186 -0
  66. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_appearance.py +9 -2
  67. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_axis_scaling.py +53 -17
  68. qplotter-1.6.2/src/qplot/windows/_plot_data_viewbox.py +94 -0
  69. qplotter-1.6.2/src/qplot/windows/_plot_drop_axes.py +234 -0
  70. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_export.py +23 -8
  71. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_feedback.py +8 -6
  72. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_marquee.py +35 -24
  73. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_refresh.py +33 -5
  74. qplotter-1.6.2/src/qplot/windows/_plot_source_promotion.py +206 -0
  75. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_state.py +21 -23
  76. qplotter-1.6.2/src/qplot/windows/_plot_status.py +115 -0
  77. qplotter-1.6.2/src/qplot/windows/_plot_tiling.py +35 -0
  78. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_preferences.py +106 -0
  79. qplotter-1.6.2/src/qplot/windows/_refresh_interval.py +172 -0
  80. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_run_controls.py +10 -49
  81. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_subplots/subplot1d.py +19 -18
  82. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_subplots/subplot2d.py +5 -2
  83. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_trusted_derived_qt.py +4 -0
  84. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/preview.py +9 -0
  85. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/run_list_items.py +7 -0
  86. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/treeWidgets.py +6 -0
  87. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_window_controls.py +1 -0
  88. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/main.py +4 -5
  89. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/plot1d.py +5 -3
  90. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/plot2d.py +50 -16
  91. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplotter.egg-info/SOURCES.txt +93 -0
  92. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/_window_lifecycle.py +33 -1
  93. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_array_preview.py +1 -1
  94. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_derived_rendering.py +1 -2
  95. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live.py +4 -0
  96. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_partial_frames.py +3 -1
  97. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_worker_integration.py +3 -0
  98. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_plot.py +36 -0
  99. qplotter-1.6.2/tests/datahandling/test_trusted_wal_contention.py +214 -0
  100. qplotter-1.6.2/tests/test_bug_hunt_array_bin_ranges.py +31 -0
  101. qplotter-1.6.2/tests/test_bug_hunt_auxiliary_safety.py +81 -0
  102. qplotter-1.6.2/tests/test_bug_hunt_average_view_updates.py +91 -0
  103. qplotter-1.6.2/tests/test_bug_hunt_bounded_mixed_means.py +125 -0
  104. qplotter-1.6.2/tests/test_bug_hunt_config.py +91 -0
  105. qplotter-1.6.2/tests/test_bug_hunt_constant_auto_recovery.py +69 -0
  106. qplotter-1.6.2/tests/test_bug_hunt_database_refresh.py +151 -0
  107. qplotter-1.6.2/tests/test_bug_hunt_derivative_cancellation.py +64 -0
  108. qplotter-1.6.2/tests/test_bug_hunt_duplicate_mean_cancellation.py +90 -0
  109. qplotter-1.6.2/tests/test_bug_hunt_fill_cancellation.py +96 -0
  110. qplotter-1.6.2/tests/test_bug_hunt_float_average_performance.py +130 -0
  111. qplotter-1.6.2/tests/test_bug_hunt_generator_fifo.py +96 -0
  112. qplotter-1.6.2/tests/test_bug_hunt_generator_safety.py +112 -0
  113. qplotter-1.6.2/tests/test_bug_hunt_heatmap_display_ranges.py +213 -0
  114. qplotter-1.6.2/tests/test_bug_hunt_integer_mean_cancellation.py +90 -0
  115. qplotter-1.6.2/tests/test_bug_hunt_line_display_ranges.py +242 -0
  116. qplotter-1.6.2/tests/test_bug_hunt_longdouble_samples.py +151 -0
  117. qplotter-1.6.2/tests/test_bug_hunt_marquee_statistics_performance.py +104 -0
  118. qplotter-1.6.2/tests/test_bug_hunt_measurement_generator.py +45 -0
  119. qplotter-1.6.2/tests/test_bug_hunt_measurement_lines.py +106 -0
  120. qplotter-1.6.2/tests/test_bug_hunt_measurement_previews.py +175 -0
  121. qplotter-1.6.2/tests/test_bug_hunt_mixed_average_performance.py +72 -0
  122. qplotter-1.6.2/tests/test_bug_hunt_native_averaging.py +85 -0
  123. qplotter-1.6.2/tests/test_bug_hunt_object_scan_cancellation.py +98 -0
  124. qplotter-1.6.2/tests/test_bug_hunt_shaped_coordinate_ranges.py +46 -0
  125. qplotter-1.6.2/tests/test_bug_hunt_snapshot_fifo.py +67 -0
  126. qplotter-1.6.2/tests/test_bug_hunt_tiny_heatmap_bins.py +64 -0
  127. qplotter-1.6.2/tests/test_bug_hunt_ui_cuts.py +73 -0
  128. qplotter-1.6.2/tests/test_bug_hunt_ui_display_precision.py +92 -0
  129. qplotter-1.6.2/tests/test_bug_hunt_ui_refresh.py +43 -0
  130. qplotter-1.6.2/tests/test_campaign_array_expansion_budget.py +221 -0
  131. qplotter-1.6.2/tests/test_campaign_boolean_derivative.py +195 -0
  132. qplotter-1.6.2/tests/test_campaign_clipped_trace_reparenting.py +63 -0
  133. qplotter-1.6.2/tests/test_campaign_diagnostics.py +104 -0
  134. qplotter-1.6.2/tests/test_campaign_empty_incremental_records.py +157 -0
  135. qplotter-1.6.2/tests/test_campaign_extended_float_centering.py +109 -0
  136. qplotter-1.6.2/tests/test_campaign_extended_float_derivative.py +109 -0
  137. qplotter-1.6.2/tests/test_campaign_extended_float_display.py +135 -0
  138. qplotter-1.6.2/tests/test_campaign_extended_float_fft.py +159 -0
  139. qplotter-1.6.2/tests/test_campaign_extended_float_heatmap.py +88 -0
  140. qplotter-1.6.2/tests/test_campaign_extended_float_previews.py +199 -0
  141. qplotter-1.6.2/tests/test_campaign_generator_backend.py +178 -0
  142. qplotter-1.6.2/tests/test_campaign_generator_input.py +37 -0
  143. qplotter-1.6.2/tests/test_campaign_heatmap_csv_precision.py +76 -0
  144. qplotter-1.6.2/tests/test_campaign_inferred_array_missing_cells.py +524 -0
  145. qplotter-1.6.2/tests/test_campaign_inferred_parameter_loading.py +259 -0
  146. qplotter-1.6.2/tests/test_campaign_live_schema_refresh.py +121 -0
  147. qplotter-1.6.2/tests/test_campaign_log_symlink_loops.py +81 -0
  148. qplotter-1.6.2/tests/test_campaign_measurement_coordinate_gaps.py +115 -0
  149. qplotter-1.6.2/tests/test_campaign_measurement_longdouble_csv.py +91 -0
  150. qplotter-1.6.2/tests/test_campaign_metadata_omission_recovery.py +154 -0
  151. qplotter-1.6.2/tests/test_campaign_mixed_extended_clipping.py +124 -0
  152. qplotter-1.6.2/tests/test_campaign_mixed_extended_finiteness.py +119 -0
  153. qplotter-1.6.2/tests/test_campaign_narrow_float_clipping.py +115 -0
  154. qplotter-1.6.2/tests/test_campaign_profiling_scripts.py +182 -0
  155. qplotter-1.6.2/tests/test_campaign_safety_cancellation.py +162 -0
  156. qplotter-1.6.2/tests/test_campaign_singleton_array_previews.py +448 -0
  157. qplotter-1.6.2/tests/test_campaign_split_storage_safety.py +148 -0
  158. qplotter-1.6.2/tests/test_campaign_ui_cut_axis_refresh.py +43 -0
  159. qplotter-1.6.2/tests/test_campaign_ui_cut_ownership.py +69 -0
  160. qplotter-1.6.2/tests/test_campaign_ui_manual_refresh.py +280 -0
  161. qplotter-1.6.2/tests/test_campaign_ui_paused_promotion.py +82 -0
  162. qplotter-1.6.2/tests/test_campaign_ui_pending_drop.py +110 -0
  163. qplotter-1.6.2/tests/test_campaign_ui_promoted_cut_mapping.py +64 -0
  164. qplotter-1.6.2/tests/test_campaign_ui_promotion.py +93 -0
  165. qplotter-1.6.2/tests/test_campaign_wal_artifact_observation.py +107 -0
  166. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_ci_artifacts.py +12 -0
  167. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_compiler_free_install.py +16 -1
  168. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_config.py +16 -1
  169. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_distribution_validator.py +24 -3
  170. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_packaging_split.py +1 -1
  171. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_release.py +71 -6
  172. qplotter-1.6.2/tests/test_version_info.py +161 -0
  173. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_array_measurements.py +2 -0
  174. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_boolean_heatmap_missing.py +2 -0
  175. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_operations.py +3 -3
  176. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_preview_dragdrop.py +8 -8
  177. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_run_details.py +3 -3
  178. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_appearance_swap_cuts.py +21 -0
  179. qplotter-1.6.2/tests/windows/test_auto_plot.py +203 -0
  180. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_axis_auto_padding_overflow.py +16 -4
  181. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_axis_global_auto_validation.py +4 -3
  182. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_bounded_shutdown.py +114 -19
  183. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_centering_extremes.py +12 -2
  184. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_commands.py +2 -2
  185. qplotter-1.6.2/tests/windows/test_csv_filenames.py +42 -0
  186. qplotter-1.6.2/tests/windows/test_cursor_precision_preference.py +136 -0
  187. qplotter-1.6.2/tests/windows/test_dataset_statistics.py +101 -0
  188. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_derivative_scale.py +12 -1
  189. qplotter-1.6.2/tests/windows/test_font_preferences.py +140 -0
  190. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_heatmap_color_range.py +1 -1
  191. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_heatmap_layer_integration.py +18 -8
  192. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_heatmap_limit_missing_samples.py +43 -0
  193. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_help_menu.py +80 -1
  194. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_independent_cancellation_mean.py +15 -7
  195. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_independent_native_extremes.py +18 -2
  196. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_limit_integer_integration.py +23 -6
  197. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_main_window.py +6 -4
  198. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_marquee_statistics_accuracy.py +13 -0
  199. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_merged_trace_metadata.py +10 -0
  200. qplotter-1.6.2/tests/windows/test_mixed_plot_drops.py +904 -0
  201. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_fft_coordinates.py +8 -8
  202. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_fft_dynamic_range.py +7 -1
  203. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_fft_float_precision.py +22 -7
  204. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_integer_transforms.py +31 -5
  205. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_transform_snapping.py +8 -7
  206. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_numeric_sample_preservation.py +3 -2
  207. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_numerical_stability.py +12 -3
  208. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot1d.py +14 -5
  209. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot1d_snap_precision.py +2 -2
  210. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot2d.py +14 -12
  211. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot2d_layers.py +48 -3
  212. qplotter-1.6.2/tests/windows/test_plot_annotation.py +118 -0
  213. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_dialog_lifecycle.py +31 -4
  214. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_integration.py +10 -11
  215. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_overlay_integration.py +9 -8
  216. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_progress_ui.py +102 -9
  217. qplotter-1.6.2/tests/windows/test_plot_tiling.py +89 -0
  218. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_window.py +4 -3
  219. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_preferences.py +11 -0
  220. qplotter-1.6.2/tests/windows/test_preview_drop_axes.py +395 -0
  221. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_refresh_lifecycle.py +29 -5
  222. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_testdata_gui.py +73 -2
  223. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_plot_launch.py +237 -1
  224. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_variable_array_records.py +19 -3
  225. qplotter-1.6.0b3/src/qplot/_metadata.py +0 -12
  226. qplotter-1.6.0b3/src/qplot/datahandling/parameter_data.py +0 -149
  227. qplotter-1.6.0b3/src/qplot/tools/sample_statistics.py +0 -56
  228. qplotter-1.6.0b3/src/qplot/windows/_native_averaging.py +0 -173
  229. qplotter-1.6.0b3/src/qplot/windows/_refresh_interval.py +0 -70
  230. {qplotter-1.6.0b3 → qplotter-1.6.2}/Agents.md +0 -0
  231. {qplotter-1.6.0b3 → qplotter-1.6.2}/LICENSE +0 -0
  232. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/assets/qplot-color-scale-dialog.png +0 -0
  233. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/assets/qplot-heatmap.png +0 -0
  234. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/assets/qplot-line-plot.png +0 -0
  235. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/assets/qplot-main-window.png +0 -0
  236. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/configuration.md +0 -0
  237. {qplotter-1.6.0b3 → qplotter-1.6.2}/docs/troubleshooting.md +0 -0
  238. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/README.md +0 -0
  239. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/benchmark_heatmap_aggregation.py +0 -0
  240. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/capture_demo_screenshots.py +0 -0
  241. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/liveplot.py +0 -0
  242. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/manual_run.py +0 -0
  243. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/release.py +0 -0
  244. {qplotter-1.6.0b3 → qplotter-1.6.2}/scripts/time_stress.py +0 -0
  245. {qplotter-1.6.0b3 → qplotter-1.6.2}/setup.cfg +0 -0
  246. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/__init__.py +0 -0
  247. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/_repair.py +0 -0
  248. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/_shutdown_supervisor.py +0 -0
  249. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/_version.py +0 -0
  250. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/_windows_shutdown_job.py +0 -0
  251. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/__init__.py +0 -0
  252. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/scripts.py +0 -0
  253. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/themes/__init__.py +0 -0
  254. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/themes/blank.py +0 -0
  255. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/themes/dark.py +0 -0
  256. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/configuration/themes/light.py +0 -0
  257. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/__init__.py +0 -0
  258. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/_trusted_live_protocol.py +0 -0
  259. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/dimensions.py +0 -0
  260. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/file_identity.py +0 -0
  261. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/plot_progress.py +0 -0
  262. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/qcodes_compat.py +0 -0
  263. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/readSQL.py +0 -0
  264. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/source_activity.py +0 -0
  265. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_derived_cache.py +0 -0
  266. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_live_supervisor.py +0 -0
  267. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_presentation.py +0 -0
  268. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_snapshot.py +0 -0
  269. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_work_coordinator.py +0 -0
  270. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/datahandling/trusted_work_scheduler.py +0 -0
  271. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_01_10mb.csv +0 -0
  272. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_02_25mb.csv +0 -0
  273. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_03_50mb.csv +0 -0
  274. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_04_100mb.csv +0 -0
  275. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_05_250mb.csv +0 -0
  276. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_06_500mb.csv +0 -0
  277. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_07_1gb.csv +0 -0
  278. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_08_5gb.csv +0 -0
  279. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_09_10gb.csv +0 -0
  280. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/resources/testdata/qplot_test_db_10_30gb.csv +0 -0
  281. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/__init__.py +0 -0
  282. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/tools/operation_registry.py +0 -0
  283. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/__init__.py +0 -0
  284. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_colorbar.py +0 -0
  285. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_config_persistence.py +0 -0
  286. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_dataset_handle.py +0 -0
  287. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_export_paths.py +0 -0
  288. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot2d_colorbar_dialog.py +0 -0
  289. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot2d_sweeps.py +0 -0
  290. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_plot_transform_labels.py +0 -0
  291. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_shortcuts.py +0 -0
  292. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_subplots/__init__.py +0 -0
  293. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_svg_export.py +0 -0
  294. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/__init__.py +0 -0
  295. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/_run_formatting.py +0 -0
  296. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/details_tables.py +0 -0
  297. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/dropbox.py +0 -0
  298. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/operations.py +0 -0
  299. {qplotter-1.6.0b3 → qplotter-1.6.2}/src/qplot/windows/_widgets/toolbar.py +0 -0
  300. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/_artifact_audit.py +0 -0
  301. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/_ci_scheduling.py +0 -0
  302. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/conftest.py +0 -0
  303. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/_wal_lineage_scenarios.py +0 -0
  304. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_array_record_metadata.py +0 -0
  305. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_database_worker_instance_binding.py +0 -0
  306. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_dimensions.py +0 -0
  307. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_inferred_planned_counts.py +0 -0
  308. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_integer_record_cache.py +0 -0
  309. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_live_acquired_point_counts.py +0 -0
  310. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_plot_progress.py +0 -0
  311. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_qcodes_cache.py +0 -0
  312. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_read_sql.py +0 -0
  313. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_read_sql_database_identity.py +0 -0
  314. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_readonly.py +0 -0
  315. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_snapshot_planned_setpoints.py +0 -0
  316. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_stage5c_real_qcodes.py +0 -0
  317. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_array_record_metadata.py +0 -0
  318. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_database_information.py +0 -0
  319. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_derived_cache.py +0 -0
  320. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_derived_cache_ownership.py +0 -0
  321. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_derived_live_integration.py +0 -0
  322. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_derived_queries.py +0 -0
  323. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_heatmap.py +0 -0
  324. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_protocol.py +0 -0
  325. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_queries.py +0 -0
  326. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_result_limits.py +0 -0
  327. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_service.py +0 -0
  328. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_stage4_integration.py +0 -0
  329. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_live_supervisor.py +0 -0
  330. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_presentation.py +0 -0
  331. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_read_scope.py +0 -0
  332. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_snapshot.py +0 -0
  333. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_source_identifiers.py +0 -0
  334. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_work_coordinator.py +0 -0
  335. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_trusted_work_scheduler.py +0 -0
  336. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/datahandling/test_wal_lineage_subprocess.py +0 -0
  337. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_auxiliary_database_protection.py +0 -0
  338. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_bounded_heatmap_means.py +0 -0
  339. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_bounded_integer_precision.py +0 -0
  340. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_ci_scheduling.py +0 -0
  341. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_demo_database_safety.py +0 -0
  342. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_derivative_numeric_ranges.py +0 -0
  343. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_diagnostics.py +0 -0
  344. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_heatmap_cancellation_residuals.py +0 -0
  345. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_heatmap_float_means.py +0 -0
  346. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_heatmap_geometry.py +0 -0
  347. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_independent_heatmap_extremes.py +0 -0
  348. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_liveplot_database_safety.py +0 -0
  349. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_native_fft_mixed_coordinates.py +0 -0
  350. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_nonuniform_cancellation.py +0 -0
  351. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_package_import.py +0 -0
  352. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_sample_statistics_accuracy.py +0 -0
  353. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_shutdown_supervisor.py +0 -0
  354. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_testdata.py +0 -0
  355. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_time_stress_database_safety.py +0 -0
  356. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_tools.py +0 -0
  357. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_windows_ci.py +0 -0
  358. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_windows_shutdown_job.py +0 -0
  359. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_array_heatmaps.py +0 -0
  360. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_complex_heatmaps.py +0 -0
  361. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_complex_lines.py +0 -0
  362. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_coordinate_precision.py +0 -0
  363. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_heatmap_limits.py +0 -0
  364. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_nonfinite_sql_heatmaps.py +0 -0
  365. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_shaped_coordinate_validity.py +0 -0
  366. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/test_worker_sidecar_identities.py +0 -0
  367. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_plot_preview_reuse.py +0 -0
  368. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_preview_database_instance.py +0 -0
  369. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_preview_extreme_range.py +0 -0
  370. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_preview_placeholders.py +0 -0
  371. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_run_list.py +0 -0
  372. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/widgets/test_themes.py +0 -0
  373. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/_trusted_derived_wal_ui.py +0 -0
  374. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_axis_limit_overflow.py +0 -0
  375. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_axis_limit_precision.py +0 -0
  376. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_color_scale_locale.py +0 -0
  377. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_complex_line_data.py +0 -0
  378. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_config_transactions.py +0 -0
  379. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_csv_shared_coordinates.py +0 -0
  380. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_cut_cursor_integration.py +0 -0
  381. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_database_information.py +0 -0
  382. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_database_worker_errors.py +0 -0
  383. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_differentiation_integration.py +0 -0
  384. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_export_paths.py +0 -0
  385. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_filtered_axis_autoscale.py +0 -0
  386. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_free_cursor_axis_assignment.py +0 -0
  387. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_heatmap_appearance.py +0 -0
  388. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_live_array_dtypes.py +0 -0
  389. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_average_cancellation.py +0 -0
  390. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_averaging.py +0 -0
  391. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_boolean_derivatives.py +0 -0
  392. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_fft_integer_precision.py +0 -0
  393. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_float_transforms.py +0 -0
  394. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_native_transform_labels.py +0 -0
  395. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_nonuniform_gradient_overflow.py +0 -0
  396. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_offset_precision_regressions.py +0 -0
  397. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_pending_preview_drop.py +0 -0
  398. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_planned_integer_array_extent.py +0 -0
  399. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_actions.py +0 -0
  400. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_csv_precision.py +0 -0
  401. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_plot_sidecar_binding.py +0 -0
  402. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_preferences_lifecycle.py +0 -0
  403. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_preferences_value_preservation.py +0 -0
  404. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_refresh_interval_precision.py +0 -0
  405. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_run_csv_export_race.py +0 -0
  406. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_run_csv_mixed_integer_precision.py +0 -0
  407. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_run_duration_wal.py +0 -0
  408. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_settings_decoder_limits.py +0 -0
  409. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_svg_export_integration.py +0 -0
  410. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_tiny_tick_labels.py +0 -0
  411. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_live_counts.py +0 -0
  412. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_qt.py +0 -0
  413. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_wal_grid_ui.py +0 -0
  414. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_wal_snapshot_ui.py +0 -0
  415. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_wal_tiers_ui.py +0 -0
  416. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_derived_wal_ui.py +0 -0
  417. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_trusted_live_ui.py +0 -0
  418. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_unloaded_database_export.py +0 -0
  419. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_visual_smoke.py +0 -0
  420. {qplotter-1.6.0b3 → qplotter-1.6.2}/tests/windows/test_window_controls.py +0 -0
@@ -2,16 +2,137 @@
2
2
 
3
3
  All notable user-facing changes are recorded here.
4
4
 
5
- Historical releases used GitHub source tags. The prepared split beta uses the
6
- PyPI distributions `qplotter` and `qplotter-native`; publication requires the
7
- release workflow and its validation gates. See `docs/distribution.md`.
5
+ ## 1.6.2 — Unreleased
8
6
 
9
- ## Unreleased
7
+ This bugfix release improves measurement correctness, live viewing and plot
8
+ lifecycle reliability. The native dependency remains `qplotter-native==1.0.1`.
9
+
10
+ ### Fixed
11
+
12
+ - Load inferred QCoDeS parameters and missing ancillary array cells, preserving
13
+ recorded samples across previews, plotting, incremental refresh and raw CSV.
14
+ - Handle singleton and empty array acquisitions consistently, including planned
15
+ scan shapes, and check expanded memory requirements before allocating them.
16
+ - Preserve extended floating-point and integer precision in derivatives, FFTs,
17
+ clipping, centering, statistics, heatmaps, previews and CSV exports.
18
+ Honor finite clipping bounds on float16/float32 measurement arrays.
19
+ - Preserve axis meaning and source ownership during mixed-plot promotion,
20
+ cut refresh and drag-and-drop; refresh retained sources while paused and
21
+ cancel pending work when its target window closes.
22
+ - Avoid Qt callback errors when reassigning axes on a clipped trace, and clear
23
+ obsolete omission warnings when live metadata becomes available again.
24
+ - Honor accepted reader cancellation and delayed helper cancellation without
25
+ publishing stale results or unnecessarily retiring healthy readers.
26
+ - Refresh live-reader schema descriptions when QCoDeS adds metadata, so newly
27
+ acquired runs expose their current columns without missing data or query errors.
28
+ - Protect measurement files from diagnostic-log reuse and synthetic generation
29
+ side effects; report malformed generator inputs and profiling failures cleanly.
30
+ Retire benchmark plot windows before Qt application teardown.
31
+ - Allow qPlot to start when the diagnostic log path contains a symlink loop.
32
+
33
+ ### Compatibility and validation
34
+
35
+ - Standard QCoDeS main-database storage remains supported. Runs using the
36
+ optional separate-per-dataset storage backend are refused before opening
37
+ their measurement files, since safe multi-file live viewing is not implemented.
38
+ - Main databases, WAL files and rollback journals remain physically read-only.
39
+ Only the pinned native reader may modify the exact colocated SHM file.
40
+ - Add regression coverage and independently reviewed fixes documented in
41
+ `BUG_HUNT.md`. No legacy settings migrations are introduced. This draft does
42
+ not publish a release.
43
+
44
+ ## 1.6.1
45
+
46
+ This patch release improves live acquisition viewing and release validation.
47
+
48
+ ### Fixed
49
+
50
+ - Restore Auto-plot in trusted live mode. Newly detected runs open automatically,
51
+ and enabling Auto-plot opens the newest incomplete run. Requests survive
52
+ selection changes and refreshes, retry while run metadata becomes available,
53
+ and cancel when Auto-plot is disabled, the database changes, or qPlot closes.
54
+ - Reduce unnecessary WAL coordination overhead that could cause deferred QCoDeS
55
+ writes to fail with `SQLITE_BUSY` during live viewing. Existing database
56
+ protections remain enforced.
57
+ - Display the main window title as `qPlot - <version>` without a duplicated
58
+ application-name suffix.
59
+ - Correct editable-install validation for source checkouts without generated
60
+ build metadata.
61
+
62
+ ### Maintenance
63
+
64
+ - Release the native-reader fix as `qplotter-native==1.0.1`, installed
65
+ automatically by the application's updated dependency pin.
66
+ - Add a workflow to revalidate published releases against their original
67
+ artifacts, retaining each release's original native dependency pin.
68
+ - Update live-reader, Auto-plot, and release-validation documentation and add
69
+ README badges.
70
+
71
+ ## 1.6.0
72
+
73
+ ### Highlights ###
74
+
75
+ - More improvements in handling large databases and datasets.
76
+ - Multiple heatmaps and traces can share the same plot window.
77
+ - Program now installs as a PyPi distribution for the first time, instead of via GitHub source tags.
78
+ - Numerous small improvements to the UI.
79
+ - Numerous bugs found by Codex Astra have been fixed. In particular, Codex now claims to rigorously enforce the rule that the database will never be modified by `qplot`. After about 30 rounds of automated bug searches, the last two rounds uncovered no bugs.
80
+ - To implement this database safety, the installation contains a small C extension 'qplotter-native' for reading live databases through SQLite.
81
+
82
+ ### Main changes since 1.5.0
83
+
84
+ (Everything in this section is AI-generated)
85
+
86
+ - Read supported local QCoDeS databases live without copying the whole
87
+ database. Main database, WAL, and rollback-journal handles remain physically
88
+ read-only; SQLite may update only the exact colocated SHM coordination file.
89
+ Reader work is bounded and cancellable.
90
+ - Load run metadata, thumbnails, previews, and explicit plots progressively,
91
+ prioritising selected and visible runs. Show clearer plot-loading progress
92
+ and keep cancellation, database switching, and shutdown responsive.
93
+ - Combine line traces and heatmaps in one plot, with axis-aware drag-and-drop,
94
+ shared appearance controls, and source annotations included in exports.
95
+ - Add system printing, configurable heatmap display grid limits, optional saved
96
+ run-table columns, plot tiling, cursor precision, and version/build information
97
+ in Help -> About qPlot and the main window title.
98
+ - Improve QCoDeS variable-shaped array support, missing-data handling, numerical
99
+ precision, native transforms, averaging, autoscaling, and live run refresh.
100
+ Reject drawing ranges that cannot faithfully represent recorded values.
101
+ - Fix CSV alignment and precision, standalone-measurement exports, SVG output,
102
+ and PDF publication. Strengthen protection against auxiliary outputs
103
+ overwriting database files and against blocking special-file inputs.
104
+ - Split the application into `qplotter` and the separately versioned
105
+ `qplotter-native==1.0.0`. Supported installations use prebuilt native wheels
106
+ without a compiler; imports and commands remain `qplot`. Release validation
107
+ covers CPython 3.11-3.14, Windows x64, macOS ARM64/Intel, and headless Linux
108
+ x86_64. Windows and macOS remain the supported desktop platforms.
109
+ - Strengthen application/helper shutdown and settings recovery, and save
110
+ configuration changes transactionally.
111
+
112
+ ### Upgrading
113
+
114
+ - Older or incompatible settings are reset to current defaults. Settings
115
+ migration is not supported.
116
+ - The old `qplot` distribution and `qplotter` share imports and commands and
117
+ must not coexist. Prefer a fresh virtual environment, or follow the removal
118
+ and reinstall instructions in `docs/distribution.md`.
119
+ - This entry is draft release text. Publication still requires the tagged
120
+ release workflow and all validation gates; this PR does not publish packages.
10
121
 
11
122
  ## 1.6.0b3 - Unreleased
12
123
 
13
124
  ### Added
14
125
 
126
+ - Combine line traces and heatmaps in one plot, with axis-aware preview drops
127
+ and a shared Appearance dialog. Removing the original dataset promotes a
128
+ remaining source while retaining the plot's appearance and state.
129
+ - Identify plotted databases, run IDs, and parameters in a shaded annotation
130
+ strip included in exports. A saved Show source annotation preference controls
131
+ visibility and is enabled by default.
132
+ - Add saved plot-tiling and cursor-precision preferences, and limit the graph
133
+ font-size preference to graph text.
134
+ - Add Help -> About qPlot with the running version, source commit and local
135
+ changes, plus commit and PR provenance in CI-built application packages.
15
136
  - Split pure-Python application distribution `qplotter` from native reader
16
137
  distribution `qplotter-native`, retaining the qPlot name, `qplot` imports and
17
138
  commands. Ordinary and editable application installation use prebuilt native
@@ -22,6 +143,9 @@ release workflow and its validation gates. See `docs/distribution.md`.
22
143
 
23
144
  ### Changed
24
145
 
146
+ - Consolidate plot feedback and loading progress in the refresh toolbar, with
147
+ accurate initial point counts and stable cursor readouts.
148
+ - Clarify refresh controls and incompatible-axis confirmations.
25
149
  - Load and refresh explicit plots through the trusted, physically read-only
26
150
  reader without copying the whole database. Small runs can open while a large
27
151
  run is loading, including with a single processing thread.
@@ -33,6 +157,13 @@ release workflow and its validation gates. See `docs/distribution.md`.
33
157
  exact source dimensions are not retained during downsampling. Right-align
34
158
  resolution information while keeping cursor coordinates left-aligned.
35
159
 
160
+ ### Fixed
161
+
162
+ - Preserve coordinate ownership, drawing order, native transforms, and specific
163
+ FFT validation messages when combining or replacing plot sources.
164
+ - Stabilize GUI test waits and release plot windows and background workers
165
+ during teardown.
166
+
36
167
  ## 1.6.0b1 - 2026-09-28
37
168
 
38
169
  ### Added
@@ -52,7 +52,7 @@ Linux is exercised in headless CI; Windows and macOS are supported desktop
52
52
  platforms. See the [platform matrix](docs/distribution.md#supported-platforms).
53
53
 
54
54
  The root distribution `qplotter` is pure Python. Install the compatible
55
- `qplotter-native==1.0.0` platform wheel with the application in editable
55
+ `qplotter-native==1.0.1` platform wheel with the application in editable
56
56
  mode. After the native release is on PyPI, no separate download is needed:
57
57
 
58
58
  ```console
@@ -27,6 +27,7 @@ prune src/qplotter.egg-info
27
27
 
28
28
  global-exclude .DS_Store
29
29
  global-exclude *.py[cod]
30
+ global-exclude *.py[cod].*
30
31
  global-exclude *.dll
31
32
  global-exclude *.dylib
32
33
  global-exclude *.pyd
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qplotter
3
- Version: 1.6.0b3
3
+ Version: 1.6.2
4
4
  Summary: PyQt-based viewer for completed and running QCoDeS database experiments
5
5
  Author-email: Ben Wordsworth <b.wordsworth@lancaster.ac.uk>, Edward Laird <e.a.laird@lancaster.ac.uk>
6
6
  License-Expression: MIT
@@ -8,7 +8,7 @@ Project-URL: Homepage, https://github.com/lairdgrouplancaster/QCoDeS-Plotter.git
8
8
  Project-URL: Source, https://github.com/lairdgrouplancaster/QCoDeS-Plotter
9
9
  Project-URL: Issues, https://github.com/lairdgrouplancaster/QCoDeS-Plotter/issues
10
10
  Keywords: qcodes,pyqt,pyqtgraph,data-visualization,scientific-computing
11
- Classifier: Development Status :: 4 - Beta
11
+ Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Environment :: MacOS X
13
13
  Classifier: Environment :: Win32 (MS Windows)
14
14
  Classifier: Intended Audience :: Science/Research
@@ -24,7 +24,7 @@ Classifier: Topic :: Scientific/Engineering :: Visualization
24
24
  Requires-Python: >=3.11
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
- Requires-Dist: qplotter-native==1.0.0
27
+ Requires-Dist: qplotter-native==1.0.1
28
28
  Requires-Dist: apsw==3.53.4.0
29
29
  Requires-Dist: jsonschema>=4.23.0
30
30
  Requires-Dist: numpy>=2.3.1
@@ -46,6 +46,11 @@ Dynamic: license-file
46
46
  # QCoDeS-Plotter
47
47
 
48
48
  [![release](https://img.shields.io/github/v/release/lairdgrouplancaster/QCoDeS-Plotter?label=release)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/releases/latest)
49
+ [![CI](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/actions/workflows/ci.yml)
50
+ [![License](https://img.shields.io/github/license/lairdgrouplancaster/QCoDeS-Plotter)](LICENSE)
51
+ [![Python](https://img.shields.io/badge/Python-3.11–3.14-blue?logo=python)](#requirements)
52
+ [![PyPI](https://img.shields.io/pypi/v/qplotter)](https://pypi.org/project/qplotter/)
53
+
49
54
  [![pre-release](https://img.shields.io/github/v/release/lairdgrouplancaster/QCoDeS-Plotter?include_prereleases&label=pre-release&sort=semver)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/releases)
50
55
 
51
56
  QCoDeS-Plotter, or qPlot, is a PyQt-based data viewer for QCoDeS databases. It
@@ -79,6 +84,11 @@ selected run's plain detail view without copying the database. Main-database,
79
84
  WAL, and rollback-journal handles remain read-only; SQLite may update only the
80
85
  exact colocated `-shm` file as transient WAL coordination state.
81
86
 
87
+ Measurement viewing supports QCoDeS's standard `sqlite_main_db` storage backend.
88
+ Runs using the optional `sqlite_per_dataset_db` backend can appear in the run
89
+ list, but their measurement actions are refused before opening the separate
90
+ raw-data files. Safe multi-file live viewing is not yet implemented.
91
+
82
92
  Normal `qplot`, `python -m qplot`, and `qplot.run()` launches put the complete
83
93
  qPlot process tree behind a shutdown boundary before Qt or reader helpers can
84
94
  start. The command-line process is the launcher. A public `qplot.run()` call
@@ -116,16 +126,20 @@ fields and an unavailable detail state without starting a selected-detail
116
126
  reader or preparing an additional selected-detail snapshot. That claim applies
117
127
  only to row selection: fallback metadata and retained preview paths can still
118
128
  create private snapshots. Plot and CSV actions also acquire action-owned
119
- snapshots. Automatic trusted live
120
- previews and thumbnails are disabled until the Stage 5 scheduler and disk cache
121
- are implemented. See
129
+ snapshots. Trusted live previews and thumbnails load progressively through a bounded
130
+ scheduler and application cache. See
122
131
  [Trusted live QCoDeS reader](docs/trusted-live-reader.md).
123
132
 
124
133
  ## Packages
125
134
 
126
135
  The application distribution is `qplotter`; its Python imports and
127
136
  console commands remain `qplot`, `qplot-cfg`, and `qplot-generate-db`.
128
- The separately built `qplotter-native==1.0.0` supplies the protected
137
+ Use **Help → About qPlot** to see the version in use on every platform.
138
+ Source checkouts also show the commit and
139
+ whether there are local changes. CI-built packages retain their build commit
140
+ and, for pull-request builds, the PR number. Packages installed without build
141
+ provenance still show the release number.
142
+ The separately built `qplotter-native==1.0.1` supplies the protected
129
143
  SQLite reader through `qplot_native`. The application's exact dependency pin
130
144
  installs the compatible native wheel automatically. Both packages pin the same
131
145
  APSW/SQLite runtime, preserving trusted live reading and database protections.
@@ -143,8 +157,8 @@ source builds, and release validation.
143
157
  ## Install
144
158
 
145
159
  Install qPlot inside a supported Python virtual environment. This checkout
146
- prepares the first split PyPI release, application `1.6.0b3` with native `1.0.0`;
147
- the commands targeting these packages work after publication. Until then, use
160
+ prepares the stable application release `1.6.2`, with native `1.0.1`.
161
+ The installation examples below work after publication; until then, use
148
162
  validated local artifacts as described in [Distribution](docs/distribution.md).
149
163
 
150
164
  ### Prelude
@@ -174,9 +188,9 @@ For ordinary installation after a stable PyPI release is available:
174
188
  python -m pip install --only-binary=:all: qplotter
175
189
  ```
176
190
 
177
- For the first split beta, explicitly select the prerelease:
191
+ To select version 1.6.2 explicitly after publication:
178
192
  ```console
179
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
193
+ python -m pip install --only-binary=:all: qplotter==1.6.2
180
194
  ```
181
195
 
182
196
  Both commands install the full runtime dependency set as wheels, with no C
@@ -198,7 +212,7 @@ installing the new packages:
198
212
 
199
213
  ```console
200
214
  python -m pip uninstall -y qplot qcodes-plotter qcodes-plotter-native qplotter qplotter-native
201
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
215
+ python -m pip install --only-binary=:all: qplotter==1.6.2
202
216
  python -m pip check
203
217
  ```
204
218
 
@@ -1,6 +1,11 @@
1
1
  # QCoDeS-Plotter
2
2
 
3
3
  [![release](https://img.shields.io/github/v/release/lairdgrouplancaster/QCoDeS-Plotter?label=release)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/releases/latest)
4
+ [![CI](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/actions/workflows/ci.yml)
5
+ [![License](https://img.shields.io/github/license/lairdgrouplancaster/QCoDeS-Plotter)](LICENSE)
6
+ [![Python](https://img.shields.io/badge/Python-3.11–3.14-blue?logo=python)](#requirements)
7
+ [![PyPI](https://img.shields.io/pypi/v/qplotter)](https://pypi.org/project/qplotter/)
8
+
4
9
  [![pre-release](https://img.shields.io/github/v/release/lairdgrouplancaster/QCoDeS-Plotter?include_prereleases&label=pre-release&sort=semver)](https://github.com/lairdgrouplancaster/QCoDeS-Plotter/releases)
5
10
 
6
11
  QCoDeS-Plotter, or qPlot, is a PyQt-based data viewer for QCoDeS databases. It
@@ -34,6 +39,11 @@ selected run's plain detail view without copying the database. Main-database,
34
39
  WAL, and rollback-journal handles remain read-only; SQLite may update only the
35
40
  exact colocated `-shm` file as transient WAL coordination state.
36
41
 
42
+ Measurement viewing supports QCoDeS's standard `sqlite_main_db` storage backend.
43
+ Runs using the optional `sqlite_per_dataset_db` backend can appear in the run
44
+ list, but their measurement actions are refused before opening the separate
45
+ raw-data files. Safe multi-file live viewing is not yet implemented.
46
+
37
47
  Normal `qplot`, `python -m qplot`, and `qplot.run()` launches put the complete
38
48
  qPlot process tree behind a shutdown boundary before Qt or reader helpers can
39
49
  start. The command-line process is the launcher. A public `qplot.run()` call
@@ -71,16 +81,20 @@ fields and an unavailable detail state without starting a selected-detail
71
81
  reader or preparing an additional selected-detail snapshot. That claim applies
72
82
  only to row selection: fallback metadata and retained preview paths can still
73
83
  create private snapshots. Plot and CSV actions also acquire action-owned
74
- snapshots. Automatic trusted live
75
- previews and thumbnails are disabled until the Stage 5 scheduler and disk cache
76
- are implemented. See
84
+ snapshots. Trusted live previews and thumbnails load progressively through a bounded
85
+ scheduler and application cache. See
77
86
  [Trusted live QCoDeS reader](docs/trusted-live-reader.md).
78
87
 
79
88
  ## Packages
80
89
 
81
90
  The application distribution is `qplotter`; its Python imports and
82
91
  console commands remain `qplot`, `qplot-cfg`, and `qplot-generate-db`.
83
- The separately built `qplotter-native==1.0.0` supplies the protected
92
+ Use **Help → About qPlot** to see the version in use on every platform.
93
+ Source checkouts also show the commit and
94
+ whether there are local changes. CI-built packages retain their build commit
95
+ and, for pull-request builds, the PR number. Packages installed without build
96
+ provenance still show the release number.
97
+ The separately built `qplotter-native==1.0.1` supplies the protected
84
98
  SQLite reader through `qplot_native`. The application's exact dependency pin
85
99
  installs the compatible native wheel automatically. Both packages pin the same
86
100
  APSW/SQLite runtime, preserving trusted live reading and database protections.
@@ -98,8 +112,8 @@ source builds, and release validation.
98
112
  ## Install
99
113
 
100
114
  Install qPlot inside a supported Python virtual environment. This checkout
101
- prepares the first split PyPI release, application `1.6.0b3` with native `1.0.0`;
102
- the commands targeting these packages work after publication. Until then, use
115
+ prepares the stable application release `1.6.2`, with native `1.0.1`.
116
+ The installation examples below work after publication; until then, use
103
117
  validated local artifacts as described in [Distribution](docs/distribution.md).
104
118
 
105
119
  ### Prelude
@@ -129,9 +143,9 @@ For ordinary installation after a stable PyPI release is available:
129
143
  python -m pip install --only-binary=:all: qplotter
130
144
  ```
131
145
 
132
- For the first split beta, explicitly select the prerelease:
146
+ To select version 1.6.2 explicitly after publication:
133
147
  ```console
134
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
148
+ python -m pip install --only-binary=:all: qplotter==1.6.2
135
149
  ```
136
150
 
137
151
  Both commands install the full runtime dependency set as wheels, with no C
@@ -153,7 +167,7 @@ installing the new packages:
153
167
 
154
168
  ```console
155
169
  python -m pip uninstall -y qplot qcodes-plotter qcodes-plotter-native qplotter qplotter-native
156
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
170
+ python -m pip install --only-binary=:all: qplotter==1.6.2
157
171
  python -m pip check
158
172
  ```
159
173
 
@@ -245,8 +245,16 @@ unavailable detail state: ordinary selection starts no selected-detail worker
245
245
  and prepares no additional selected-detail snapshot. A trusted detail failure
246
246
  also does not trigger an automatic fallback copy. This is a property of the
247
247
  selection action, not the whole fallback session: fallback metadata and retained
248
- preview paths can still create private snapshots. Only explicit plot and CSV
249
- actions materialise a DataSet.
248
+ preview paths can still create private snapshots. Fallback plot actions
249
+ (including Auto-plot) and CSV actions can materialise a DataSet.
250
+
251
+ Trusted Auto-plot owns a deduplicated queue independently of selected-detail
252
+ and refresh requests. It submits one bounded plot-metadata request at a time,
253
+ then uses the same asynchronous plot pipeline as manual plotting. Unavailable
254
+ descriptions are operation-local failures that leave the reader session usable.
255
+ Retries use bounded backoff; later run-metadata changes wake exhausted requests.
256
+ Disabling Auto-plot, committing a database switch, closing the database, and
257
+ shutdown cancel the queue. Source identity checks still guard publication.
250
258
 
251
259
  Stage 5A's `trusted_work_scheduler.py` owns the exact derived priority key
252
260
  `(run tier, work kind, stable run index)` without materialising one task per
@@ -65,6 +65,13 @@ database and each run, including elapsed times and whether generation completed,
65
65
  was cancelled, or failed. These appear alongside QCoDeS's existing
66
66
  `Starting experimental run with id:` messages.
67
67
 
68
+ Generation requires QCoDeS's `dataset.raw_data_backend` to be `sqlite_main_db`,
69
+ `dataset.export_automatic` to be false, and
70
+ `subscription.default_subscribers` to be empty. Other settings are rejected
71
+ before creating files because they can write outside the selected output.
72
+ qPlot leaves these global settings unchanged and uses an empty private station
73
+ so synthetic measurements do not read parameters from an acquisition station.
74
+
68
75
  Every nonblank CSV row creates one run, named `run_1`, `run_2`, and so on. A 1D
69
76
  row sweeps `V_SD`; a 2D row sweeps both `V_SD` and `V_G`. Each measured signal
70
77
  is the sum of two sinusoids with independently randomised amplitudes,
@@ -29,11 +29,15 @@ virtual environment with:
29
29
  python -m pip install --only-binary=:all: qplotter
30
30
  ```
31
31
 
32
- The first prepared application release is the beta `1.6.0b3`, with exact native
33
- dependency `1.0.0`. Once published, install that prerelease explicitly:
32
+ The current development target is the stable application release `1.6.2`,
33
+ with exact native dependency `1.0.1`. Existing candidate tags do not establish
34
+ that publication succeeded. Preparing a PR does not publish either package.
35
+
36
+ The prepared stable application release is `1.6.2`, with exact native
37
+ dependency `1.0.1`. Once published, install that release explicitly:
34
38
 
35
39
  ```console
36
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
40
+ python -m pip install --only-binary=:all: qplotter==1.6.2
37
41
  ```
38
42
 
39
43
  The earlier `native-and-app/v1.6.0b2` candidate did not pass its complete hosted
@@ -55,7 +59,7 @@ wheel paths from this revision's validated artifacts together. For example,
55
59
  on Windows x64 (replace the application version when appropriate):
56
60
 
57
61
  ```console
58
- python -m pip install --only-binary=:all: dist/qplotter_native-1.0.0-cp311-abi3-win_amd64.whl dist/qplotter-1.6.0b3-py3-none-any.whl
62
+ python -m pip install --only-binary=:all: dist/qplotter_native-1.0.1-cp311-abi3-win_amd64.whl dist/qplotter-1.6.2-py3-none-any.whl
59
63
  ```
60
64
 
61
65
  Use your platform's native filename on macOS/Linux. Never mix artifacts from
@@ -87,7 +91,7 @@ application names before installing the replacement:
87
91
 
88
92
  ```console
89
93
  python -m pip uninstall -y qplot qcodes-plotter qcodes-plotter-native qplotter qplotter-native
90
- python -m pip install --only-binary=:all: qplotter==1.6.0b3
94
+ python -m pip install --only-binary=:all: qplotter==1.6.2
91
95
  python -m pip check
92
96
  python -c "from importlib.metadata import packages_distributions; p = packages_distributions(); assert set(p['qplot']) == {'qplotter'}; assert set(p['qplot_native']) == {'qplotter-native'}"
93
97
  ```
@@ -217,7 +221,7 @@ wheels must build the extension from source.
217
221
 
218
222
  The native wheel contains the `cp311-abi3` extension
219
223
  `qplot_native._trusted_vfs_native` and is platform-specific. The application
220
- wheel is `py3-none-any`. The application requires exactly native version 1.0.0;
224
+ wheel is `py3-none-any`. The application requires exactly native version 1.0.1;
221
225
  both distributions pin APSW 3.53.4.0. Keep these dependencies, the validator's
222
226
  pins, and the Python/native SQLite 3.53.4 and source-ID checks coordinated.
223
227
  The reader also rejects an incompatible native distribution version, SQLite
@@ -395,8 +399,8 @@ application version from `pyproject.toml`:
395
399
 
396
400
  | Tag | Native handling | PyPI uploads |
397
401
  | --- | --- | --- |
398
- | `native-and-app/v1.6.0b3` | Build/validate native `1.0.0` at this revision | Native wheels first, then application wheel/sdist |
399
- | `v1.6.0b4` (example later version) | Fetch/validate the application's exact published native pin | Application wheel/sdist only |
402
+ | `native-and-app/v1.6.2` | Build/validate native `1.0.1` at this revision, if unpublished | Native wheels first, then application wheel/sdist |
403
+ | `v1.6.2` | Fetch/validate the application's exact published native pin | Application wheel/sdist only |
400
404
 
401
405
  The workflow calls the entire CI workflow at the tagged revision. Failure of
402
406
  any build, static check, source-distribution suite, database-protection suite,
@@ -428,9 +432,9 @@ After application publication and byte verification, `public-installations`
428
432
  runs on all four platforms and every advertised CPython version (3.11–3.14).
429
433
  Each entry creates two fresh environments outside the original checkout.
430
434
  The ordinary path runs `python -m pip install --only-binary=:all:
431
- qplotter==1.6.0b3` against the public PyPI index with all runtime dependencies.
435
+ qplotter==1.6.2` against the public PyPI index with all runtime dependencies.
432
436
  The editable path fetches the exact tested commit into a fresh checkout and
433
- installs `.[dev]` with `qplotter-native==1.0.0` resolved from public PyPI.
437
+ installs `.[dev]` with `qplotter-native==1.0.1` resolved from public PyPI.
434
438
  Neither path installs a local release wheel; the validated artifacts are only
435
439
  comparison receipts for the pip report and installed-file hashes. All runtime
436
440
  and development dependencies must resolve to public wheels. Both paths disable
@@ -440,7 +444,10 @@ protections. Editable acceptance additionally observes a Python edit without
440
444
  reinstalling and checks that the native binary's bytes, identity and timestamp
441
445
  remain unchanged. Windows uses the standard-user wrapper for both paths.
442
446
  Publication is irreversible; failures in these post-publication checks must
443
- be reported and fixed in a new release, rather than described as acceptance.
447
+ be reported. Changes to published package contents require a new release.
448
+ A defect confined to the validation tools can instead be corrected and the
449
+ existing release rechecked as described below; the failed original run remains
450
+ part of the release record.
444
451
 
445
452
  ### One-time account configuration
446
453
 
@@ -484,10 +491,14 @@ and [pending-publisher instructions](https://docs.pypi.org/trusted-publishers/cr
484
491
  release version before tagging; never move a published tag. If migrating
485
492
  from token publishing, revoke/remove the old upload tokens/secrets.
486
493
 
487
- ### First release commands
494
+ ### Application 1.6.2 release commands
495
+
496
+ Version 1.6.2 contains Python-only changes and retains the published native
497
+ 1.0.1 dependency. Use the application-only tag below; published native files
498
+ remain unchanged.
488
499
 
489
500
  Complete the account setup and merge the reviewed packaging/release changes
490
- to `main`. With application `1.6.0b3` and native `1.0.0`, use the configured
501
+ to `main`. With application `1.6.2` and native `1.0.1`, use the configured
491
502
  Git remote/credentials:
492
503
 
493
504
  ```console
@@ -495,22 +506,22 @@ git fetch origin
495
506
  git switch main
496
507
  git pull --ff-only origin main
497
508
  python scripts/validate_distribution.py --check-clean
498
- git tag -a native-and-app/v1.6.0b3 -m "qPlot 1.6.0b3 with native reader 1.0.0"
499
- git push origin refs/tags/native-and-app/v1.6.0b3
509
+ git tag -a v1.6.2 -m "qPlot 1.6.2"
510
+ git push origin refs/tags/v1.6.2
500
511
  ```
501
512
 
502
513
  Use the activated project venv for Python; on macOS set
503
514
  `MPLCONFIGDIR=/private/tmp/qplot-matplotlib-cache` for Python commands that may
504
515
  import Matplotlib. The tag push is the publication trigger. Review its hosted
505
- CI results, then approve the `pypi-native` environment. Confirm native
506
- verification succeeds before approving `pypi-application`. The final PyPI
516
+ CI results and confirm verification of the published native dependency
517
+ succeeds before approving `pypi-application`. No native publication is needed. The final PyPI
507
518
  verification and all `public-installations` jobs must succeed before announcing the release. No GitHub Release
508
519
  object is needed to trigger publication; use the connected GitHub app for any
509
520
  subsequent release/PR operations if supported, never `gh`.
510
521
 
511
522
  ### Later Python-only releases
512
523
 
513
- Update the application version (for example to `1.6.0b4`) and changelog, keep
524
+ Update the application version (for example to `1.6.3`) and changelog, keep
514
525
  the exact native/APSW pins when still compatible, and merge the changes. Do
515
526
  not change native sources/ABI under an existing native version. Then:
516
527
 
@@ -519,8 +530,8 @@ git fetch origin
519
530
  git switch main
520
531
  git pull --ff-only origin main
521
532
  python scripts/validate_distribution.py --check-clean
522
- git tag -a v1.6.0b4 -m "qPlot 1.6.0b4"
523
- git push origin refs/tags/v1.6.0b4
533
+ git tag -a v1.6.3 -m "qPlot 1.6.3"
534
+ git push origin refs/tags/v1.6.3
524
535
  ```
525
536
 
526
537
  The native release must already contain all four non-yanked compatible wheels.
@@ -537,6 +548,35 @@ the application remains blocked. Once the complete native release is verified,
537
548
  an application-only tag for the still-unpublished application version can also
538
549
  recover a failed paired release after a new validation run.
539
550
 
551
+ ### Recheck an existing published release
552
+
553
+ If post-publication acceptance fails because of a validation-tool defect,
554
+ fix and review the tools, then merge them to `main`. Do not move the release
555
+ tag or rerun a successful publication job. In GitHub Actions, select
556
+ **Revalidate published qPlot release**, then **Run workflow**, using branch
557
+ `main`. Supply the original release tag and publication workflow run ID.
558
+ For the 1.6.0 resource-inventory correction these are `v1.6.0` and
559
+ `38429734516`.
560
+
561
+ This manual workflow uses the corrected tools from `main`, but checks out
562
+ the original release source separately. It checks the native package version
563
+ pinned by that original source while retaining the tools' supported APSW/SQLite
564
+ ABI checks. It downloads the `qplot-release` artifact from the original
565
+ publication run, verifies its tag, commit, run ID,
566
+ and hashes, and checks the published PyPI bytes against those receipts. The
567
+ artifact must still be available; a missing/expired receipt is a failed gate,
568
+ not permission to substitute a new build. The receipts are comparison inputs;
569
+ ordinary and editable dependencies are still installed from public PyPI.
570
+ All four platforms and CPython 3.11-3.14 run both installation paths, including
571
+ GUI startup and the trusted live reader/database-protection smokes. Windows
572
+ runs unprivileged. The workflow has only read permissions and no publishing
573
+ jobs or deployment approvals.
574
+
575
+ Wait for all 16 matrix jobs to pass before reporting corrected acceptance.
576
+ Link both the original publication run and the new validation run in the
577
+ release notes. If any failure requires an application or native package change,
578
+ use a new package version and the normal release workflow.
579
+
540
580
  ### Local and hosted results
541
581
 
542
582
  Local tests and actionlint validate release configuration and failure gates.
@@ -265,8 +265,19 @@ proof handles, actual SQLite handles, source pathnames, rollback-journal absence
265
265
  and active SHM bindings. Only after that succeeds may page reads reuse pathname
266
266
  proofs until operation cleanup. Every page read still validates the retained and
267
267
  actual handle identities and their physically read-only permissions, before and
268
- after delegation. Other callbacks, including SHM mapping/locking, retain their
269
- full existing checks. Newly opened or promoted WAL handles are fully validated.
268
+ after delegation. SHM mapping and newly opened or promoted WAL handles retain
269
+ their full checks. SHM locks and memory barriers use the binding already proved
270
+ by mapping and operation-boundary validation, without filesystem calls inside
271
+ SQLite's WAL critical sections. Unlocks are forwarded even after a latched
272
+ validation error, allowing SQLite to release its coordination locks on cleanup.
273
+
274
+ SQLite reads the two WAL-index header copies around `xShmBarrier`. Filesystem
275
+ checks in that callback widen the race with a commit and can force even a
276
+ read-only connection to acquire `WAL_WRITE_LOCK` to retry the header. Checks
277
+ after acquisition or before release then prolong that lock, causing a QCoDeS
278
+ deferred read-to-write upgrade to fail with `SQLITE_BUSY`. The native callbacks
279
+ retain the platform memory fence and real SHM locking, including legitimate
280
+ WAL-index recovery; they neither suppress locks nor bypass them.
270
281
 
271
282
  Cleanup disables pathname reuse and performs full native validation before any
272
283
  materialised result is published, including error, deadline and cancellation
@@ -279,6 +290,11 @@ transaction. Reads outside the explicit finite scope retain per-read path checks
279
290
  Native audit counters include `read_path_reused`, `read_validation_ns` and
280
291
  `read_io_ns`. The timings separate page-read validation from the delegated OS VFS
281
292
  read, not total SQL or IPC time, and never govern safety checks or deadlines.
293
+ `shm_write_lock_attempts`, `shm_write_lock_acquired`, `shm_write_lock_ns` and
294
+ `shm_write_lock_max_ns` expose transient WAL write-lock contention. The durations
295
+ run from successful acquisition return through successful release return; these
296
+ diagnostics do not control locking. A read-only connection can legitimately
297
+ acquire this lock to coordinate the writable WAL index.
282
298
  `scripts/profile_trusted_reads.py DATABASE RUN_ID` profiles finite 65,536-row
283
299
  intervals through the pinned reader and checks protected-file sizes/timestamps.
284
300
  It does not clear OS caches or modify the selected database. Use the actual plot