jarvisplot 2.1.7__tar.gz → 2.1.8__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 (277) hide show
  1. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/PKG-INFO +38 -1
  2. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/SOURCES.txt +10 -0
  3. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/PKG-INFO +38 -1
  4. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/README.md +37 -0
  5. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/config_runtime.py +3 -1
  6. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/figure.py +31 -7
  7. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/layer_runtime.py +1 -1
  8. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/preprocessor.py +28 -1
  9. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/preprocessor_runtime.py +27 -5
  10. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/style_runtime.py +14 -0
  11. jarvisplot-2.1.8/jarvisplot/cache_registry.py +346 -0
  12. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cache_store.py +78 -8
  13. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/args.json +13 -2
  14. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/column_demand.py +35 -0
  15. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/core.py +50 -6
  16. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/core_runtime.py +189 -43
  17. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_access.py +15 -15
  18. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_loader.py +37 -2
  19. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_loader_hdf5.py +0 -2
  20. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_loader_runtime.py +60 -16
  21. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/dryrun_runtime.py +32 -0
  22. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/legend_cards.py +2 -2
  23. jarvisplot-2.1.8/jarvisplot/manual_cards/cache.yaml +57 -0
  24. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/cli-map.yaml +3 -1
  25. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/manifest.yaml +1 -0
  26. jarvisplot-2.1.8/jarvisplot/utils/expression.py +425 -0
  27. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/validation.py +19 -2
  28. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/__init__.py +1 -0
  29. jarvisplot-2.1.8/jarvisplot/verbs/cache.py +179 -0
  30. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/pyproject.toml +1 -1
  31. jarvisplot-2.1.8/tests/test_add_column.py +58 -0
  32. jarvisplot-2.1.8/tests/test_cache_cleanup.py +75 -0
  33. jarvisplot-2.1.8/tests/test_cache_registry.py +455 -0
  34. jarvisplot-2.1.8/tests/test_column_pruning.py +251 -0
  35. jarvisplot-2.1.8/tests/test_examples_validate.py +29 -0
  36. jarvisplot-2.1.8/tests/test_expression_semantics.py +185 -0
  37. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_parse_data_metadata.py +75 -0
  38. jarvisplot-2.1.8/tests/test_render_lifecycle.py +175 -0
  39. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_template_catalog.py +7 -0
  40. jarvisplot-2.1.7/jarvisplot/utils/expression.py +0 -125
  41. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/dependency_links.txt +0 -0
  42. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/entry_points.txt +0 -0
  43. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/requires.txt +0 -0
  44. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/JarvisPLOT.egg-info/top_level.txt +0 -0
  45. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/__init__.py +0 -0
  46. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/adapters_rect.py +0 -0
  47. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/adapters_ternary.py +0 -0
  48. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/adaptive_cdf_runtime.py +0 -0
  49. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/bin_stat_runtime.py +0 -0
  50. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/cards/std_axes_adapter_config.json +0 -0
  51. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/colorbar_runtime.py +0 -0
  52. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/corr_layout.py +0 -0
  53. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/corr_layout_diamond.py +0 -0
  54. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/corr_order.py +0 -0
  55. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/correlation_runtime.py +0 -0
  56. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/corrplot_runtime.py +0 -0
  57. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/data_pipelines.py +0 -0
  58. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/debug_config.py +0 -0
  59. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/density_cell_runtime.py +0 -0
  60. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/design_runtime.py +0 -0
  61. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/distribution_1d_runtime.py +0 -0
  62. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/dynesty_runtime.py +0 -0
  63. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/figure_types.py +0 -0
  64. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/helper.py +0 -0
  65. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/interp_2d_runtime.py +0 -0
  66. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/interp_natural_neighbor.py +0 -0
  67. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/interp_natural_neighbor_exact.py +0 -0
  68. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/layout_runtime.py +0 -0
  69. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/legend_runtime.py +0 -0
  70. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/method_registry.py +0 -0
  71. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/posterior_density_runtime.py +0 -0
  72. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/posterior_hpd.py +0 -0
  73. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/posterior_mesh.py +0 -0
  74. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/profile_runtime.py +0 -0
  75. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/Figure/significance_runtime.py +0 -0
  76. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/__init__.py +0 -0
  77. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/agent_digest.py +0 -0
  78. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/agent_io.py +0 -0
  79. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/capabilities.py +0 -0
  80. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/1x1/ternary.json +0 -0
  81. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/dynesty_runplot.json +0 -0
  82. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/rect.json +0 -0
  83. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/rect5x1.json +0 -0
  84. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/rect_cmap.json +0 -0
  85. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/rect_marginal.json +0 -0
  86. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/rectratio.json +0 -0
  87. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/ternary.json +0 -0
  88. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/2x1/ternary_cmap.json +0 -0
  89. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/4x1/rect.json +0 -0
  90. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/4x1/rect_cmap.json +0 -0
  91. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/4x1/ternary.json +0 -0
  92. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/a4paper/4x1/ternary_cmap.json +0 -0
  93. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/colors/colormaps.json +0 -0
  94. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/corrplot/diamond.json +0 -0
  95. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/corrplot/matrix.json +0 -0
  96. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/default/output.json +0 -0
  97. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/flowchart/default.json +0 -0
  98. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/gambit/1x1/ternary.json +0 -0
  99. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/gambit/2x1/rect_cmap.json +0 -0
  100. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/gambit/2x1/ternary.json +0 -0
  101. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/gambit/2x1/ternary_cmap.json +0 -0
  102. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/JarvisHEP.png +0 -0
  103. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/JarvisHEP.png +0 -0
  104. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/calculator.png +0 -0
  105. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/inputfile.png +0 -0
  106. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/opera.png +0 -0
  107. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/outputfile.png +0 -0
  108. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/flowchart/sampler.png +0 -0
  109. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/gambit.png +0 -0
  110. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/icons/gambit_small.png +0 -0
  111. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/legends/compact/legend-card.json +0 -0
  112. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/legends/default/legend-card.json +0 -0
  113. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/legends/paper/legend-card.json +0 -0
  114. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/legends/presentation/legend-card.json +0 -0
  115. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cards/style_preference.json +0 -0
  116. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cli.py +0 -0
  117. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/cli_help.py +0 -0
  118. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/client.py +0 -0
  119. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/column_probe.py +0 -0
  120. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/config.py +0 -0
  121. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/config_address.py +0 -0
  122. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/core_assets.py +0 -0
  123. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_generation_contracts.py +0 -0
  124. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/data_loader_summary.py +0 -0
  125. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/dataset_types.py +0 -0
  126. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/diagnostic_guidance.py +0 -0
  127. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/diagnostics.py +0 -0
  128. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/distribution_1d_config.py +0 -0
  129. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/expr_names.py +0 -0
  130. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/fix_apply.py +0 -0
  131. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/flowchart.py +0 -0
  132. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/generated_data.py +0 -0
  133. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/inner_func.py +0 -0
  134. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/man_catalog.py +0 -0
  135. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/man_methods.py +0 -0
  136. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/man_render_agent.py +0 -0
  137. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/man_render_human.py +0 -0
  138. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/man_transforms.py +0 -0
  139. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/agent-output.yaml +0 -0
  140. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/data-columns.yaml +0 -0
  141. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/debug-overlay.yaml +0 -0
  142. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/diagnostics.yaml +0 -0
  143. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/dryrun-viz.yaml +0 -0
  144. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/field-interp.yaml +0 -0
  145. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/generated-data.yaml +0 -0
  146. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/layer-method.yaml +0 -0
  147. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/legend.yaml +0 -0
  148. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/method_notes.yaml +0 -0
  149. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/style-axes.yaml +0 -0
  150. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/type-correlation-matrix.yaml +0 -0
  151. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/type-posterior-2d.yaml +0 -0
  152. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/type-profile-2d.yaml +0 -0
  153. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/validate.yaml +0 -0
  154. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/workflow.yaml +0 -0
  155. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/manual_cards/yaml-root.yaml +0 -0
  156. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/memtrace.py +0 -0
  157. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/method_contracts.py +0 -0
  158. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/render_health.py +0 -0
  159. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/common.json +0 -0
  160. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/dataset.json +0 -0
  161. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/distribution-1d.json +0 -0
  162. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/figure.json +0 -0
  163. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/generated-data.json +0 -0
  164. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/layer.json +0 -0
  165. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/legend-card.json +0 -0
  166. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/legend.json +0 -0
  167. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/core/transform.json +0 -0
  168. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/manifest.json +0 -0
  169. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/bar.json +0 -0
  170. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/barh.json +0 -0
  171. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/contour.json +0 -0
  172. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/contourf.json +0 -0
  173. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/corrplot.json +0 -0
  174. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/dynesty_runplot.json +0 -0
  175. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/errorbar.json +0 -0
  176. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/fill.json +0 -0
  177. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/fill_between.json +0 -0
  178. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/fill_betweenx.json +0 -0
  179. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/hist.json +0 -0
  180. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/hist2d.json +0 -0
  181. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/imshow.json +0 -0
  182. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/jpcontour.json +0 -0
  183. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/jpcontourf.json +0 -0
  184. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/jpfield.json +0 -0
  185. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/pcolor.json +0 -0
  186. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/pcolormesh.json +0 -0
  187. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/plot.json +0 -0
  188. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/quiver.json +0 -0
  189. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/scatter.json +0 -0
  190. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/stairs.json +0 -0
  191. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/step.json +0 -0
  192. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/tricontour.json +0 -0
  193. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/tricontourf.json +0 -0
  194. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/tripcolor.json +0 -0
  195. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/tripcolor_axes.json +0 -0
  196. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/triplot.json +0 -0
  197. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/voronoi.json +0 -0
  198. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/methods/voronoif.json +0 -0
  199. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema/plot-config.json +0 -0
  200. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema_catalog.py +0 -0
  201. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/schema_diagnostics.py +0 -0
  202. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/templates_catalog.py +0 -0
  203. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/transform_contracts.py +0 -0
  204. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/utils/__init__.py +0 -0
  205. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/utils/cmaps.py +0 -0
  206. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/utils/dataframes.py +0 -0
  207. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/utils/interpolator.py +0 -0
  208. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/utils/pathing.py +0 -0
  209. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/cap.py +0 -0
  210. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/config_cmd.py +0 -0
  211. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/data.py +0 -0
  212. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/doctor.py +0 -0
  213. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/dryrun.py +0 -0
  214. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/explain.py +0 -0
  215. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/man.py +0 -0
  216. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/suggest.py +0 -0
  217. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/template.py +0 -0
  218. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/verbs/validate.py +0 -0
  219. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/jarvisplot/yaml_io.py +0 -0
  220. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/setup.cfg +0 -0
  221. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_adaptive_cdf.py +0 -0
  222. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_agent_digest.py +0 -0
  223. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_agent_envelope.py +0 -0
  224. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_axis_title.py +0 -0
  225. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_capabilities.py +0 -0
  226. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_card_debug_shape.py +0 -0
  227. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_cli_help.py +0 -0
  228. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_cli_verbs.py +0 -0
  229. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_cmaps.py +0 -0
  230. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_column_existence.py +0 -0
  231. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_config_addressing.py +0 -0
  232. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_config_edit.py +0 -0
  233. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_config_expand.py +0 -0
  234. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_correlation_runtime.py +0 -0
  235. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_corrplot.py +0 -0
  236. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_data_access.py +0 -0
  237. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_data_describe.py +0 -0
  238. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_data_head_eval.py +0 -0
  239. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_data_loader_contracts.py +0 -0
  240. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_data_pipelines.py +0 -0
  241. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_debug_config.py +0 -0
  242. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_debug_switches.py +0 -0
  243. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_debug_yaml_override.py +0 -0
  244. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_density_cell_transform.py +0 -0
  245. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_design_runtime.py +0 -0
  246. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_diagnostic_guidance.py +0 -0
  247. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_distribution_1d_transform.py +0 -0
  248. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_docs_status_labels.py +0 -0
  249. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_doctor_partial.py +0 -0
  250. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_explain.py +0 -0
  251. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_figure_contracts.py +0 -0
  252. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_figure_type_expander.py +0 -0
  253. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_fix_application.py +0 -0
  254. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_flowchart_renderer.py +0 -0
  255. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_generated_data.py +0 -0
  256. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_imshow_adapter.py +0 -0
  257. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_interp_2d_transform.py +0 -0
  258. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_interp_natural_neighbor.py +0 -0
  259. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_interpolator_contracts.py +0 -0
  260. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_jpcontour_methods.py +0 -0
  261. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_layer_legend.py +0 -0
  262. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_legend_cards.py +0 -0
  263. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_legend_runtime.py +0 -0
  264. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_man_cli.py +0 -0
  265. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_method_contracts.py +0 -0
  266. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_pathing_contracts.py +0 -0
  267. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_posterior_hpd.py +0 -0
  268. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_profile_runtime.py +0 -0
  269. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_render_health.py +0 -0
  270. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_row_ledger.py +0 -0
  271. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_schema_catalog.py +0 -0
  272. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_suggest.py +0 -0
  273. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_suggest_axes.py +0 -0
  274. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_template_json.py +0 -0
  275. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_ternary_debug.py +0 -0
  276. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_transform_contracts.py +0 -0
  277. {jarvisplot-2.1.7 → jarvisplot-2.1.8}/tests/test_validate_no_matplotlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.7
3
+ Version: 2.1.8
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -66,6 +66,7 @@ Render with a bare path — there is no `jplot run`:
66
66
  ```bash
67
67
  jplot path/to/config.yaml
68
68
  jplot path/to/config.yaml --rebuild-cache
69
+ jplot path/to/config.yaml --print
69
70
  ```
70
71
 
71
72
  Everything else is discovery and judgement, in three groups.
@@ -218,9 +219,45 @@ from jarvisplot import render_flowchart, render_flowchart_file
218
219
  - You can set `project.workdir` in YAML.
219
220
  - If `output.dir` is omitted, Jarvis-PLOT defaults to `<workdir>/plots/`.
220
221
  - Data cache is stored in `<workdir>/.cache/`.
222
+ - `--print` accepts the current settings and renders final figures without the logo. It announces that, after all enabled figures are saved successfully, cache payloads used or created by this run will be deleted (pipeline data and metadata, named/shared data, summaries, and HDF5 materialization slots). Rendering failures or a run with no enabled figures keep the cache. Unrelated cache entries and the lightweight fingerprint manifest are retained; later renders rebuild deleted entries as needed.
221
223
  - Profiling pipelines are prebuilt once and reused from cache when source fingerprint and profile settings are unchanged.
222
224
  - Profiling uses a fast two-stage grid reduction (`pregrid` + render `bin`) for large datasets.
223
225
 
226
+ Plot caches are automatically registered in `~/.jarvis/plot.json` (or
227
+ `$JARVIS_HOME/plot.json`). The registry groups caches by workdir and records
228
+ associated YAML paths and last use; payloads stay in their original directories.
229
+ This includes caches created by `data describe` and default `dryrun --with-data`
230
+ exports. Sizes are calculated when listing, rather than stored in the registry.
231
+
232
+ ```bash
233
+ jplot cache list
234
+ jplot cache scan ~/Jarvis-Workshop # register existing plot caches
235
+ jplot cache clean --workdir /path/to/project # this directory and all nested projects; repeatable
236
+ jplot cache clean --all --older-than 30 # unused for at least 30 days
237
+ jplot cache clean --all --dry-run # preview; no deletion/index changes
238
+ jplot cache clean --all # clean all registered inactive caches
239
+ jplot cache -h
240
+ jplot man cache
241
+ ```
242
+
243
+ `--workdir PATH` selects registered caches in PATH itself and all of its
244
+ subdirectories, even when PATH has no cache of its own. Repeat it to select
245
+ multiple directory trees; overlapping selections are deduplicated. Use
246
+ `cache scan PATH` first for old caches that have not been registered.
247
+
248
+ All cache subcommands accept `--json` and use the existing CLI envelope and
249
+ exit codes (0 success/partial, 1 failure, 2 usage). Non-TTY stdout defaults to
250
+ JSON; human results go to stderr. Active caches are skipped (`ok: null` when
251
+ the remaining operation succeeds), and records for missing paths are pruned
252
+ during cleanup. Only marked Jarvis-PLOT components are removed; source data,
253
+ plots, and unrelated `.cache` content are retained. Failed deletions retain
254
+ their registry entries. Scanning adopts legacy caches only when the four
255
+ pipeline directories and a compatible `manifest.json` identify them; old
256
+ unmarked twin-only directories need a new `dryrun --with-data` run to register.
257
+ An explicitly supplied `--out-dir` is an export directory and is not registered.
258
+ Concurrent registry writes use a lock and atomic replacement. Registration
259
+ failures warn without preventing rendering.
260
+
224
261
  ### Example: SUSYRun2 Ternary Plots
225
262
 
226
263
  ```bash
@@ -9,6 +9,7 @@ JarvisPLOT.egg-info/top_level.txt
9
9
  jarvisplot/__init__.py
10
10
  jarvisplot/agent_digest.py
11
11
  jarvisplot/agent_io.py
12
+ jarvisplot/cache_registry.py
12
13
  jarvisplot/cache_store.py
13
14
  jarvisplot/capabilities.py
14
15
  jarvisplot/cli.py
@@ -127,6 +128,7 @@ jarvisplot/cards/legends/default/legend-card.json
127
128
  jarvisplot/cards/legends/paper/legend-card.json
128
129
  jarvisplot/cards/legends/presentation/legend-card.json
129
130
  jarvisplot/manual_cards/agent-output.yaml
131
+ jarvisplot/manual_cards/cache.yaml
130
132
  jarvisplot/manual_cards/cli-map.yaml
131
133
  jarvisplot/manual_cards/data-columns.yaml
132
134
  jarvisplot/manual_cards/debug-overlay.yaml
@@ -193,6 +195,7 @@ jarvisplot/utils/expression.py
193
195
  jarvisplot/utils/interpolator.py
194
196
  jarvisplot/utils/pathing.py
195
197
  jarvisplot/verbs/__init__.py
198
+ jarvisplot/verbs/cache.py
196
199
  jarvisplot/verbs/cap.py
197
200
  jarvisplot/verbs/config_cmd.py
198
201
  jarvisplot/verbs/data.py
@@ -204,15 +207,19 @@ jarvisplot/verbs/suggest.py
204
207
  jarvisplot/verbs/template.py
205
208
  jarvisplot/verbs/validate.py
206
209
  tests/test_adaptive_cdf.py
210
+ tests/test_add_column.py
207
211
  tests/test_agent_digest.py
208
212
  tests/test_agent_envelope.py
209
213
  tests/test_axis_title.py
214
+ tests/test_cache_cleanup.py
215
+ tests/test_cache_registry.py
210
216
  tests/test_capabilities.py
211
217
  tests/test_card_debug_shape.py
212
218
  tests/test_cli_help.py
213
219
  tests/test_cli_verbs.py
214
220
  tests/test_cmaps.py
215
221
  tests/test_column_existence.py
222
+ tests/test_column_pruning.py
216
223
  tests/test_config_addressing.py
217
224
  tests/test_config_edit.py
218
225
  tests/test_config_expand.py
@@ -232,7 +239,9 @@ tests/test_diagnostic_guidance.py
232
239
  tests/test_distribution_1d_transform.py
233
240
  tests/test_docs_status_labels.py
234
241
  tests/test_doctor_partial.py
242
+ tests/test_examples_validate.py
235
243
  tests/test_explain.py
244
+ tests/test_expression_semantics.py
236
245
  tests/test_figure_contracts.py
237
246
  tests/test_figure_type_expander.py
238
247
  tests/test_fix_application.py
@@ -253,6 +262,7 @@ tests/test_pathing_contracts.py
253
262
  tests/test_posterior_hpd.py
254
263
  tests/test_profile_runtime.py
255
264
  tests/test_render_health.py
265
+ tests/test_render_lifecycle.py
256
266
  tests/test_row_ledger.py
257
267
  tests/test_schema_catalog.py
258
268
  tests/test_suggest.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.7
3
+ Version: 2.1.8
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -66,6 +66,7 @@ Render with a bare path — there is no `jplot run`:
66
66
  ```bash
67
67
  jplot path/to/config.yaml
68
68
  jplot path/to/config.yaml --rebuild-cache
69
+ jplot path/to/config.yaml --print
69
70
  ```
70
71
 
71
72
  Everything else is discovery and judgement, in three groups.
@@ -218,9 +219,45 @@ from jarvisplot import render_flowchart, render_flowchart_file
218
219
  - You can set `project.workdir` in YAML.
219
220
  - If `output.dir` is omitted, Jarvis-PLOT defaults to `<workdir>/plots/`.
220
221
  - Data cache is stored in `<workdir>/.cache/`.
222
+ - `--print` accepts the current settings and renders final figures without the logo. It announces that, after all enabled figures are saved successfully, cache payloads used or created by this run will be deleted (pipeline data and metadata, named/shared data, summaries, and HDF5 materialization slots). Rendering failures or a run with no enabled figures keep the cache. Unrelated cache entries and the lightweight fingerprint manifest are retained; later renders rebuild deleted entries as needed.
221
223
  - Profiling pipelines are prebuilt once and reused from cache when source fingerprint and profile settings are unchanged.
222
224
  - Profiling uses a fast two-stage grid reduction (`pregrid` + render `bin`) for large datasets.
223
225
 
226
+ Plot caches are automatically registered in `~/.jarvis/plot.json` (or
227
+ `$JARVIS_HOME/plot.json`). The registry groups caches by workdir and records
228
+ associated YAML paths and last use; payloads stay in their original directories.
229
+ This includes caches created by `data describe` and default `dryrun --with-data`
230
+ exports. Sizes are calculated when listing, rather than stored in the registry.
231
+
232
+ ```bash
233
+ jplot cache list
234
+ jplot cache scan ~/Jarvis-Workshop # register existing plot caches
235
+ jplot cache clean --workdir /path/to/project # this directory and all nested projects; repeatable
236
+ jplot cache clean --all --older-than 30 # unused for at least 30 days
237
+ jplot cache clean --all --dry-run # preview; no deletion/index changes
238
+ jplot cache clean --all # clean all registered inactive caches
239
+ jplot cache -h
240
+ jplot man cache
241
+ ```
242
+
243
+ `--workdir PATH` selects registered caches in PATH itself and all of its
244
+ subdirectories, even when PATH has no cache of its own. Repeat it to select
245
+ multiple directory trees; overlapping selections are deduplicated. Use
246
+ `cache scan PATH` first for old caches that have not been registered.
247
+
248
+ All cache subcommands accept `--json` and use the existing CLI envelope and
249
+ exit codes (0 success/partial, 1 failure, 2 usage). Non-TTY stdout defaults to
250
+ JSON; human results go to stderr. Active caches are skipped (`ok: null` when
251
+ the remaining operation succeeds), and records for missing paths are pruned
252
+ during cleanup. Only marked Jarvis-PLOT components are removed; source data,
253
+ plots, and unrelated `.cache` content are retained. Failed deletions retain
254
+ their registry entries. Scanning adopts legacy caches only when the four
255
+ pipeline directories and a compatible `manifest.json` identify them; old
256
+ unmarked twin-only directories need a new `dryrun --with-data` run to register.
257
+ An explicitly supplied `--out-dir` is an export directory and is not registered.
258
+ Concurrent registry writes use a lock and atomic replacement. Registration
259
+ failures warn without preventing rendering.
260
+
224
261
  ### Example: SUSYRun2 Ternary Plots
225
262
 
226
263
  ```bash
@@ -44,6 +44,7 @@ Render with a bare path — there is no `jplot run`:
44
44
  ```bash
45
45
  jplot path/to/config.yaml
46
46
  jplot path/to/config.yaml --rebuild-cache
47
+ jplot path/to/config.yaml --print
47
48
  ```
48
49
 
49
50
  Everything else is discovery and judgement, in three groups.
@@ -196,9 +197,45 @@ from jarvisplot import render_flowchart, render_flowchart_file
196
197
  - You can set `project.workdir` in YAML.
197
198
  - If `output.dir` is omitted, Jarvis-PLOT defaults to `<workdir>/plots/`.
198
199
  - Data cache is stored in `<workdir>/.cache/`.
200
+ - `--print` accepts the current settings and renders final figures without the logo. It announces that, after all enabled figures are saved successfully, cache payloads used or created by this run will be deleted (pipeline data and metadata, named/shared data, summaries, and HDF5 materialization slots). Rendering failures or a run with no enabled figures keep the cache. Unrelated cache entries and the lightweight fingerprint manifest are retained; later renders rebuild deleted entries as needed.
199
201
  - Profiling pipelines are prebuilt once and reused from cache when source fingerprint and profile settings are unchanged.
200
202
  - Profiling uses a fast two-stage grid reduction (`pregrid` + render `bin`) for large datasets.
201
203
 
204
+ Plot caches are automatically registered in `~/.jarvis/plot.json` (or
205
+ `$JARVIS_HOME/plot.json`). The registry groups caches by workdir and records
206
+ associated YAML paths and last use; payloads stay in their original directories.
207
+ This includes caches created by `data describe` and default `dryrun --with-data`
208
+ exports. Sizes are calculated when listing, rather than stored in the registry.
209
+
210
+ ```bash
211
+ jplot cache list
212
+ jplot cache scan ~/Jarvis-Workshop # register existing plot caches
213
+ jplot cache clean --workdir /path/to/project # this directory and all nested projects; repeatable
214
+ jplot cache clean --all --older-than 30 # unused for at least 30 days
215
+ jplot cache clean --all --dry-run # preview; no deletion/index changes
216
+ jplot cache clean --all # clean all registered inactive caches
217
+ jplot cache -h
218
+ jplot man cache
219
+ ```
220
+
221
+ `--workdir PATH` selects registered caches in PATH itself and all of its
222
+ subdirectories, even when PATH has no cache of its own. Repeat it to select
223
+ multiple directory trees; overlapping selections are deduplicated. Use
224
+ `cache scan PATH` first for old caches that have not been registered.
225
+
226
+ All cache subcommands accept `--json` and use the existing CLI envelope and
227
+ exit codes (0 success/partial, 1 failure, 2 usage). Non-TTY stdout defaults to
228
+ JSON; human results go to stderr. Active caches are skipped (`ok: null` when
229
+ the remaining operation succeeds), and records for missing paths are pruned
230
+ during cleanup. Only marked Jarvis-PLOT components are removed; source data,
231
+ plots, and unrelated `.cache` content are retained. Failed deletions retain
232
+ their registry entries. Scanning adopts legacy caches only when the four
233
+ pipeline directories and a compatible `manifest.json` identify them; old
234
+ unmarked twin-only directories need a new `dryrun --with-data` run to register.
235
+ An explicitly supplied `--out-dir` is an export directory and is not registered.
236
+ Concurrent registry writes use a lock and atomic replacement. Registration
237
+ failures warn without preventing rendering.
238
+
202
239
  ### Example: SUSYRun2 Ternary Plots
203
240
 
204
241
  ```bash
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  from pathlib import Path
4
4
  from typing import Mapping
5
5
 
6
+ from .style_runtime import normalize_style_tokens
7
+
6
8
 
7
9
  def apply_figure_config(fig, info: Mapping) -> bool:
8
10
  """Apply a YAML figure block to a Figure instance."""
@@ -55,7 +57,7 @@ def apply_figure_config(fig, info: Mapping) -> bool:
55
57
  )
56
58
 
57
59
  if "style" in info:
58
- style_tokens = info["style"]
60
+ style_tokens = normalize_style_tokens(info["style"])
59
61
  else:
60
62
  style_tokens = ["a4paper_2x1"]
61
63
  fig.style = style_tokens
@@ -11,7 +11,7 @@ from types import MethodType
11
11
  from .adapters_rect import StdAxesAdapter
12
12
  from .adapters_ternary import TernaryAxesAdapter
13
13
  from .method_registry import resolve_callable
14
- from .style_runtime import resolve_style_bundle_payload
14
+ from .style_runtime import normalize_style_tokens, resolve_style_bundle_payload
15
15
  from .config_runtime import apply_figure_config
16
16
  from .design_runtime import draw_design_reference
17
17
  from .legend_runtime import apply_legend
@@ -399,10 +399,13 @@ class Figure:
399
399
 
400
400
 
401
401
  @style.setter
402
- def style(self, value) -> None:
403
- if len(value) not in (1, 2):
404
- self.logger.error("Undefined style -> {}".format(value))
405
- raise TypeError
402
+ def style(self, value) -> None:
403
+ value = normalize_style_tokens(value)
404
+ if not isinstance(value, list) or len(value) not in (1, 2):
405
+ raise TypeError(
406
+ "style must name a card family or [family, variant], e.g. "
407
+ "a4paper_2x1 or [a4paper_2x1, rect]; got {!r}".format(value)
408
+ )
406
409
  family, selected, bundle = resolve_style_bundle_payload(self.jpstyles, value)
407
410
  self._frame = deepcopy(bundle["Frame"])
408
411
  self._legend_disabled_axes = set()
@@ -508,7 +511,7 @@ class Figure:
508
511
  return {kk: self._ensure_pandas_data(vv, reason=reason) for kk, vv in data.items()}
509
512
  return data
510
513
 
511
- def _concat_loaded_data(self, items):
514
+ def _concat_loaded_data(self, items, layer_name: str = ""):
512
515
  if len(items) == 0:
513
516
  return None
514
517
  if len(items) == 1:
@@ -519,7 +522,28 @@ class Figure:
519
522
  pandas_items = [self._ensure_pandas_data(item, reason="concat-layer") for item in items]
520
523
  try:
521
524
  return pd.concat(pandas_items, ignore_index=False)
522
- except Exception:
525
+ except Exception as exc:
526
+ # Keep drawing what can be drawn, but never drop data silently.
527
+ if self.logger:
528
+ shapes = ", ".join(
529
+ str(getattr(item, "shape", type(item).__name__)) for item in pandas_items
530
+ )
531
+ self.logger.warning(
532
+ "Layer '{}': the {} data blocks could not be concatenated, so only "
533
+ "the first block is drawn and the other {} are dropped.\n"
534
+ "\t reason \t-> {}: {}\n"
535
+ "\t blocks \t-> {}\n"
536
+ "\t hint \t\t-> blocks combined with `combine: concat` must be tables "
537
+ "with compatible columns (no duplicated column names); use "
538
+ "`combine: separate` to draw them independently.".format(
539
+ layer_name or "<unnamed>",
540
+ len(pandas_items),
541
+ len(pandas_items) - 1,
542
+ type(exc).__name__,
543
+ exc,
544
+ shapes,
545
+ )
546
+ )
523
547
  return pandas_items[0]
524
548
 
525
549
  def _store_share_data_if_needed(self, layer, data, cache_ref: str | None = None):
@@ -642,7 +642,7 @@ def _load_layer_data(fig, layer):
642
642
  fig.logger.error("DataSet -> {} not specified".format(src))
643
643
  if len(dts) == 0:
644
644
  return None, None
645
- combined = fig._concat_loaded_data(dts)
645
+ combined = fig._concat_loaded_data(dts, layer_name=str(layer.get("name", "") or ""))
646
646
  cache_ref = None
647
647
  if len(dts) == 1 and combined is dts[0] and len(cache_keys) == 1:
648
648
  cache_ref = cache_keys[0]
@@ -883,6 +883,7 @@ class DataPreprocessor:
883
883
  "mode": str(mode),
884
884
  "projection": self._projection_list(projection),
885
885
  }
886
+ self._add_source_column_scope(payload, source, projection)
886
887
  if self.cache is not None:
887
888
  return self.cache.cache_key(payload)
888
889
  return self._stable_hash(payload)
@@ -896,7 +897,7 @@ class DataPreprocessor:
896
897
  projection: Optional[Sequence[str]] = None,
897
898
  ) -> Dict[str, Any]:
898
899
  eff_transform = self._effective_transform(source, transform)
899
- return {
900
+ payload = {
900
901
  "schema": "jp-demand-v8",
901
902
  "source": self._source_token(source, combine=combine),
902
903
  "extra_sources": self._transform_extra_source_tokens(eff_transform),
@@ -905,6 +906,29 @@ class DataPreprocessor:
905
906
  "mode": str(mode),
906
907
  "projection": self._projection_list(projection),
907
908
  }
909
+ self._add_source_column_scope(payload, source, projection)
910
+ return payload
911
+
912
+ def _add_source_column_scope(self, payload: Dict[str, Any], source: Any, projection) -> None:
913
+ """Key an unprojected pipeline on the columns its datasets were loaded with.
914
+
915
+ A projected pipeline keeps the same columns whatever the column plan
916
+ loaded. An unprojected one (a published table, a step that takes the
917
+ whole table) carries every loaded column, so a result cached under one
918
+ plan would be missing columns a later config asks for. The scope is only
919
+ added when a dataset is actually pruned, so other keys stay as they were.
920
+ """
921
+ if self._projection_list(projection) is not None:
922
+ return
923
+ names = [source] if isinstance(source, str) else list(source) if isinstance(source, (list, tuple)) else []
924
+ scope = {}
925
+ for name in names:
926
+ dts = self.dataset_registry.get(str(name))
927
+ planned = getattr(dts, "required_columns", None) if dts is not None else None
928
+ if planned:
929
+ scope[str(name)] = sorted(planned)
930
+ if scope:
931
+ payload["source_columns"] = scope
908
932
 
909
933
  def _demand_fingerprint(
910
934
  self,
@@ -935,6 +959,9 @@ class DataPreprocessor:
935
959
  profile_sig = self._runtime_profile_signature(tf)
936
960
  if profile_sig is not None:
937
961
  token["profile_signature"] = profile_sig
962
+ self._add_source_column_scope(
963
+ token, src, self._runtime_projection(tf, self.layer_demand_columns(layer))
964
+ )
938
965
  tokens.append(token)
939
966
  payload = {
940
967
  "name": layer.get("name"),
@@ -235,7 +235,7 @@ def filter_df(df, condition, logger):
235
235
  return df.copy(deep=False)
236
236
  if low in {"false", "f", "no", "n"}:
237
237
  return df.iloc[0:0].copy()
238
- s = s.replace("&&", " & ").replace("||", " | ")
238
+ # `&&` / `||` / and / or / not are handled by the shared parser.
239
239
  condition = s
240
240
  else:
241
241
  raise TypeError(f"Unsupported condition type: {type(condition)}")
@@ -255,13 +255,35 @@ def filter_df(df, condition, logger):
255
255
  return pd.DataFrame(index=df.index).iloc[0:0].copy()
256
256
 
257
257
 
258
+ def add_column_spec_problem(adds) -> Optional[str]:
259
+ """Why an ``add_column`` step cannot run, or ``None`` when it can."""
260
+ if not isinstance(adds, Mapping):
261
+ return f"add_column skipped: expected {{name, expr}}, got {adds!r}"
262
+ missing = []
263
+ if not str(adds.get("name") or "").strip():
264
+ missing.append("name")
265
+ expr = adds.get("expr")
266
+ if expr is None or not str(expr).strip():
267
+ missing.append("expr")
268
+ if missing:
269
+ return "add_column skipped: missing {} -> {}".format(" and ".join(missing), dict(adds))
270
+ return None
271
+
272
+
258
273
  def add_column(df, adds, logger):
259
274
  try:
260
- name = adds.get("name", False)
261
- expr = adds.get("expr", False)
262
- if not (name and expr):
263
- logger.error("Error in loading add_column -> {}".format(adds))
275
+ problem = add_column_spec_problem(adds)
276
+ if problem:
277
+ # Nothing sensible to add: carry on without the column rather than
278
+ # inventing one (an absent expr used to evaluate to False).
279
+ logger.error(problem)
280
+ return df
281
+ name = str(adds.get("name")).strip()
282
+ expr = adds.get("expr")
264
283
  value = eval_dataframe_expression(df, expr, logger=logger, allow_column=True)
284
+ # The frame may be a table other blocks still read (a preprofile pass
285
+ # works on the source itself); add to a copy, never into the caller's.
286
+ df = df.copy(deep=False)
265
287
  df[name] = value
266
288
  return df
267
289
  except Exception as e:
@@ -8,8 +8,22 @@ from typing import Any, Mapping, Tuple
8
8
  PREFERRED_STYLE_VARIANTS = ("rect", "Ternary", "rect_5x1", "dynesty_runplot", "rectcmap", "TernaryCmap")
9
9
 
10
10
 
11
+ def normalize_style_tokens(value):
12
+ """``style: a4paper_2x1`` and ``style: [a4paper_2x1]`` name the same card.
13
+
14
+ The schema accepts both spellings; everything downstream indexes tokens,
15
+ and a bare string would be read one character at a time.
16
+ """
17
+ if isinstance(value, str):
18
+ return [value]
19
+ if isinstance(value, tuple):
20
+ return list(value)
21
+ return value
22
+
23
+
11
24
  def resolve_style_bundle_payload(jpstyles: Mapping[str, Any], value) -> Tuple[str, str, dict]:
12
25
  """Resolve style tokens to a full bundle payload."""
26
+ value = normalize_style_tokens(value)
13
27
  if len(value) == 2:
14
28
  family_name = value[0]
15
29
  variant_name = value[1]