rootfig 0.4.0__tar.gz → 0.5.0__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 (291) hide show
  1. {rootfig-0.4.0 → rootfig-0.5.0}/PKG-INFO +1 -1
  2. {rootfig-0.4.0 → rootfig-0.5.0}/docs/composable.md +1 -1
  3. {rootfig-0.4.0 → rootfig-0.5.0}/docs/plotting.md +2 -1
  4. {rootfig-0.4.0 → rootfig-0.5.0}/examples/gallery/__init__.py +27 -18
  5. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/__init__.py +1 -1
  6. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/_common.py +2 -2
  7. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/data.py +1 -1
  8. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/measures.py +5 -5
  9. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/plots1d.py +3 -3
  10. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/build.py +3 -3
  11. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/normalize.py +2 -2
  12. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/pipeline.py +2 -2
  13. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/samples.py +7 -7
  14. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/style.py +2 -2
  15. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/variables.py +2 -2
  16. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_api.py +3 -1
  17. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_histograms.py +8 -8
  18. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_model.py +23 -21
  19. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_plotting.py +2 -2
  20. {rootfig-0.4.0 → rootfig-0.5.0}/.gitignore +0 -0
  21. {rootfig-0.4.0 → rootfig-0.5.0}/CONTRIBUTING.md +0 -0
  22. {rootfig-0.4.0 → rootfig-0.5.0}/LICENSE +0 -0
  23. {rootfig-0.4.0 → rootfig-0.5.0}/README.md +0 -0
  24. {rootfig-0.4.0 → rootfig-0.5.0}/docs/api.md +0 -0
  25. {rootfig-0.4.0 → rootfig-0.5.0}/docs/ecosystem.md +0 -0
  26. {rootfig-0.4.0 → rootfig-0.5.0}/docs/expressions.md +0 -0
  27. {rootfig-0.4.0 → rootfig-0.5.0}/docs/gallery/index.md +0 -0
  28. {rootfig-0.4.0 → rootfig-0.5.0}/docs/hooks/gallery.py +0 -0
  29. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-alice-dark.png +0 -0
  30. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-alice.png +0 -0
  31. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-atlas-dark.png +0 -0
  32. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-atlas.png +0 -0
  33. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-cms-dark.png +0 -0
  34. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-cms.png +0 -0
  35. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-dark.png +0 -0
  36. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-dune-dark.png +0 -0
  37. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-dune.png +0 -0
  38. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-lhcb-dark.png +0 -0
  39. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays-lhcb.png +0 -0
  40. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/arrays.png +0 -0
  41. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-alice-dark.png +0 -0
  42. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-alice.png +0 -0
  43. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-atlas-dark.png +0 -0
  44. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-atlas.png +0 -0
  45. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-cms-dark.png +0 -0
  46. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-cms.png +0 -0
  47. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-dark.png +0 -0
  48. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-dune-dark.png +0 -0
  49. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-dune.png +0 -0
  50. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-lhcb-dark.png +0 -0
  51. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation-lhcb.png +0 -0
  52. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/correlation.png +0 -0
  53. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-alice-dark.png +0 -0
  54. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-alice.png +0 -0
  55. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-atlas-dark.png +0 -0
  56. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-atlas.png +0 -0
  57. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-cms-dark.png +0 -0
  58. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-cms.png +0 -0
  59. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-dark.png +0 -0
  60. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-dune-dark.png +0 -0
  61. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-dune.png +0 -0
  62. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-lhcb-dark.png +0 -0
  63. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow-lhcb.png +0 -0
  64. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/density_flow.png +0 -0
  65. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-alice-dark.png +0 -0
  66. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-alice.png +0 -0
  67. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-atlas-dark.png +0 -0
  68. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-atlas.png +0 -0
  69. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-cms-dark.png +0 -0
  70. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-cms.png +0 -0
  71. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-dark.png +0 -0
  72. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-dune-dark.png +0 -0
  73. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-dune.png +0 -0
  74. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-lhcb-dark.png +0 -0
  75. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency-lhcb.png +0 -0
  76. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/efficiency.png +0 -0
  77. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-alice-dark.png +0 -0
  78. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-alice.png +0 -0
  79. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-atlas-dark.png +0 -0
  80. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-atlas.png +0 -0
  81. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-cms-dark.png +0 -0
  82. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-cms.png +0 -0
  83. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-dark.png +0 -0
  84. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-dune-dark.png +0 -0
  85. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-dune.png +0 -0
  86. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-lhcb-dark.png +0 -0
  87. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions-lhcb.png +0 -0
  88. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/expressions.png +0 -0
  89. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-alice-dark.png +0 -0
  90. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-alice.png +0 -0
  91. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-atlas-dark.png +0 -0
  92. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-atlas.png +0 -0
  93. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-cms-dark.png +0 -0
  94. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-cms.png +0 -0
  95. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-dark.png +0 -0
  96. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-dune-dark.png +0 -0
  97. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-dune.png +0 -0
  98. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-lhcb-dark.png +0 -0
  99. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats-lhcb.png +0 -0
  100. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/fill_stats.png +0 -0
  101. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-alice-dark.png +0 -0
  102. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-alice.png +0 -0
  103. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-atlas-dark.png +0 -0
  104. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-atlas.png +0 -0
  105. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-cms-dark.png +0 -0
  106. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-cms.png +0 -0
  107. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-dark.png +0 -0
  108. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-dune-dark.png +0 -0
  109. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-dune.png +0 -0
  110. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-lhcb-dark.png +0 -0
  111. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d-lhcb.png +0 -0
  112. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/hist2d.png +0 -0
  113. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-alice-dark.png +0 -0
  114. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-alice.png +0 -0
  115. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-atlas-dark.png +0 -0
  116. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-atlas.png +0 -0
  117. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-cms-dark.png +0 -0
  118. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-cms.png +0 -0
  119. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-dark.png +0 -0
  120. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-dune-dark.png +0 -0
  121. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-dune.png +0 -0
  122. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-lhcb-dark.png +0 -0
  123. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes-lhcb.png +0 -0
  124. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/log_axes.png +0 -0
  125. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/luminosity-dark.png +0 -0
  126. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/luminosity.png +0 -0
  127. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/many_plots-dark.png +0 -0
  128. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/many_plots.png +0 -0
  129. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-alice-dark.png +0 -0
  130. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-alice.png +0 -0
  131. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-atlas-dark.png +0 -0
  132. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-atlas.png +0 -0
  133. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-cms-dark.png +0 -0
  134. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-cms.png +0 -0
  135. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-dark.png +0 -0
  136. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-dune-dark.png +0 -0
  137. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-dune.png +0 -0
  138. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-lhcb-dark.png +0 -0
  139. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event-lhcb.png +0 -0
  140. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/object_vs_event.png +0 -0
  141. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-alice-dark.png +0 -0
  142. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-alice.png +0 -0
  143. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-atlas-dark.png +0 -0
  144. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-atlas.png +0 -0
  145. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-cms-dark.png +0 -0
  146. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-cms.png +0 -0
  147. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-dark.png +0 -0
  148. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-dune-dark.png +0 -0
  149. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-dune.png +0 -0
  150. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-lhcb-dark.png +0 -0
  151. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio-lhcb.png +0 -0
  152. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/overlay_ratio.png +0 -0
  153. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-alice-dark.png +0 -0
  154. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-alice.png +0 -0
  155. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-atlas-dark.png +0 -0
  156. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-atlas.png +0 -0
  157. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-cms-dark.png +0 -0
  158. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-cms.png +0 -0
  159. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-dark.png +0 -0
  160. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-dune-dark.png +0 -0
  161. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-dune.png +0 -0
  162. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-lhcb-dark.png +0 -0
  163. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile-lhcb.png +0 -0
  164. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/profile.png +0 -0
  165. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-alice-dark.png +0 -0
  166. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-alice.png +0 -0
  167. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-atlas-dark.png +0 -0
  168. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-atlas.png +0 -0
  169. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-cms-dark.png +0 -0
  170. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-cms.png +0 -0
  171. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-dark.png +0 -0
  172. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-dune-dark.png +0 -0
  173. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-dune.png +0 -0
  174. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-lhcb-dark.png +0 -0
  175. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick-lhcb.png +0 -0
  176. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/quick.png +0 -0
  177. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-alice-dark.png +0 -0
  178. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-alice.png +0 -0
  179. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-atlas-dark.png +0 -0
  180. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-atlas.png +0 -0
  181. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-cms-dark.png +0 -0
  182. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-cms.png +0 -0
  183. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-dark.png +0 -0
  184. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-dune-dark.png +0 -0
  185. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-dune.png +0 -0
  186. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-lhcb-dark.png +0 -0
  187. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference-lhcb.png +0 -0
  188. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/ratio_reference.png +0 -0
  189. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/robust_range-dark.png +0 -0
  190. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/robust_range.png +0 -0
  191. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-alice-dark.png +0 -0
  192. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-alice.png +0 -0
  193. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-atlas-dark.png +0 -0
  194. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-atlas.png +0 -0
  195. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-cms-dark.png +0 -0
  196. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-cms.png +0 -0
  197. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-dark.png +0 -0
  198. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-dune-dark.png +0 -0
  199. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-dune.png +0 -0
  200. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-lhcb-dark.png +0 -0
  201. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data-lhcb.png +0 -0
  202. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/stack_data.png +0 -0
  203. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/style_colors-dark.png +0 -0
  204. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/style_colors.png +0 -0
  205. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-alice-dark.png +0 -0
  206. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-alice.png +0 -0
  207. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-atlas-dark.png +0 -0
  208. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-atlas.png +0 -0
  209. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-cms-dark.png +0 -0
  210. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-cms.png +0 -0
  211. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-dark.png +0 -0
  212. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-dune-dark.png +0 -0
  213. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-dune.png +0 -0
  214. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-lhcb-dark.png +0 -0
  215. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics-lhcb.png +0 -0
  216. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/systematics.png +0 -0
  217. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-alice-dark.png +0 -0
  218. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-alice.png +0 -0
  219. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-atlas-dark.png +0 -0
  220. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-atlas.png +0 -0
  221. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-cms-dark.png +0 -0
  222. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-cms.png +0 -0
  223. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-dark.png +0 -0
  224. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-dune-dark.png +0 -0
  225. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-dune.png +0 -0
  226. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-lhcb-dark.png +0 -0
  227. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins-lhcb.png +0 -0
  228. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/variable_bins.png +0 -0
  229. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-alice-dark.png +0 -0
  230. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-alice.png +0 -0
  231. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-atlas-dark.png +0 -0
  232. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-atlas.png +0 -0
  233. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-cms-dark.png +0 -0
  234. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-cms.png +0 -0
  235. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-dark.png +0 -0
  236. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-dune-dark.png +0 -0
  237. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-dune.png +0 -0
  238. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-lhcb-dark.png +0 -0
  239. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio-lhcb.png +0 -0
  240. {rootfig-0.4.0 → rootfig-0.5.0}/docs/images/gallery/xbreak_ratio.png +0 -0
  241. {rootfig-0.4.0 → rootfig-0.5.0}/docs/index.md +0 -0
  242. {rootfig-0.4.0 → rootfig-0.5.0}/docs/quickstart.md +0 -0
  243. {rootfig-0.4.0 → rootfig-0.5.0}/docs/stylesheets/gallery.css +0 -0
  244. {rootfig-0.4.0 → rootfig-0.5.0}/examples/gallery/__main__.py +0 -0
  245. {rootfig-0.4.0 → rootfig-0.5.0}/examples/gallery/data.py +0 -0
  246. {rootfig-0.4.0 → rootfig-0.5.0}/examples/gallery/registry.py +0 -0
  247. {rootfig-0.4.0 → rootfig-0.5.0}/mkdocs.yml +0 -0
  248. {rootfig-0.4.0 → rootfig-0.5.0}/pyproject.toml +0 -0
  249. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/_mapping.py +0 -0
  250. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/_typing.py +0 -0
  251. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/__init__.py +0 -0
  252. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/plots2d.py +0 -0
  253. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/api/tables.py +0 -0
  254. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/errors.py +0 -0
  255. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/expressions/__init__.py +0 -0
  256. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/expressions/functions.py +0 -0
  257. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/expressions/parser.py +0 -0
  258. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/__init__.py +0 -0
  259. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/cutflow.py +0 -0
  260. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/efficiency.py +0 -0
  261. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/ratio.py +0 -0
  262. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/stats.py +0 -0
  263. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/histograms/systematics.py +0 -0
  264. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/io/__init__.py +0 -0
  265. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/io/sources.py +0 -0
  266. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/__init__.py +0 -0
  267. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/binning.py +0 -0
  268. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/cuts.py +0 -0
  269. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/systematics.py +0 -0
  270. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/model/units.py +0 -0
  271. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/__init__.py +0 -0
  272. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/annotations.py +0 -0
  273. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/correlation.py +0 -0
  274. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/figure.py +0 -0
  275. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/hist1d.py +0 -0
  276. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/hist2d.py +0 -0
  277. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/points.py +0 -0
  278. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/ratio.py +0 -0
  279. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/result.py +0 -0
  280. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/plotting/style.py +0 -0
  281. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/py.typed +0 -0
  282. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/selection/__init__.py +0 -0
  283. {rootfig-0.4.0 → rootfig-0.5.0}/src/rootfig/selection/columns.py +0 -0
  284. {rootfig-0.4.0 → rootfig-0.5.0}/tests/conftest.py +0 -0
  285. {rootfig-0.4.0 → rootfig-0.5.0}/tests/data/split_collection.root +0 -0
  286. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_expressions.py +0 -0
  287. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_gallery.py +0 -0
  288. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_io.py +0 -0
  289. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_selection.py +0 -0
  290. {rootfig-0.4.0 → rootfig-0.5.0}/tests/test_tutorials.py +0 -0
  291. {rootfig-0.4.0 → rootfig-0.5.0}/tests/type_checks/systematics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rootfig
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Publication-quality figures straight from ROOT trees, without ROOT: uproot + Awkward + hist + mplhep with a TTree::Draw-like API.
5
5
  Project-URL: Homepage, https://github.com/jbeirer/rootfig
6
6
  Project-URL: Documentation, https://jbeirer.github.io/rootfig/
@@ -56,7 +56,7 @@ mem = rf.Sample({"x": awkward_array, "w": weights}, label="in memory")
56
56
  ([`Systematic.samples`][rootfig.Systematic]). Sources with
57
57
  the same name are correlated across samples; see
58
58
  [Systematic uncertainties](plotting.md#systematic-uncertainties).
59
- - `sample.with_(label="...")` returns a modified copy; replacement values are
59
+ - `sample.replace(label="...")` returns a copy with the given fields changed; new values are
60
60
  validated like constructor arguments.
61
61
 
62
62
  Passing a list of files to `plot()` creates one sample per file. To merge
@@ -113,7 +113,8 @@ Pre-filled histograms take variations directly and are drawn the same way:
113
113
  [`sum_histograms`][rootfig.histograms.sum_histograms] work on them too.
114
114
 
115
115
  Use `(h_up, None)` for a mirrored variation. `Sample.systematics` and
116
- `Histogram.variations` are read-only; change them with `with_(...)`.
116
+ `Histogram.variations` are read-only; `sample.replace(systematics=...)` and
117
+ `histogram.replace(variations=...)` return copies with other ones.
117
118
 
118
119
  ## Luminosity
119
120
 
@@ -231,7 +231,7 @@ def stack_data(mc: list[rf.Sample], data: rf.Sample, pt: rf.Variable, style: rf.
231
231
  "Systematic uncertainties in a stack and its ratio panel",
232
232
  section=SIMULATION_AND_DATA,
233
233
  )
234
- def systematics(mc: list[rf.Sample], data: rf.Sample, met: rf.Variable, style: rf.Style) -> rf.Plot:
234
+ def systematics(signal: rf.Sample, data: rf.Sample, met: rf.Variable, style: rf.Style) -> rf.Plot:
235
235
  """A sample lists its sources of systematic uncertainty by name: a pair of weight
236
236
  expressions, a relative normalisation uncertainty, or a mapping of shifted branches,
237
237
  which also move the selection. ``systematics=`` on the plot adds a
@@ -239,15 +239,24 @@ def systematics(mc: list[rf.Sample], data: rf.Sample, met: rf.Variable, style: r
239
239
  statistical and systematic uncertainties; a source with the same name in several
240
240
  samples is correlated, different sources add in quadrature. ``p.uncertainty()``
241
241
  returns every component."""
242
- zjets, diboson, signal = mc
243
242
  jes = {"MET": ("MET_jesUp", "MET_jesDown")}
244
- varied = [
245
- zjets.with_(systematics={"pileup": ("weight_pu_up", "weight_pu_down"), "jes": jes}),
246
- diboson.with_(systematics={"jes": jes, "xsec": 0.10}),
247
- signal,
248
- ]
243
+ zjets = rf.Sample(
244
+ "background.root",
245
+ tree="events",
246
+ label="Z + jets",
247
+ weight="weight",
248
+ systematics={"pileup": ("weight_pu_up", "weight_pu_down"), "jes": jes},
249
+ )
250
+ diboson = rf.Sample(
251
+ "diboson.root",
252
+ tree="events",
253
+ label="Diboson",
254
+ weight="weight",
255
+ scale=0.15,
256
+ systematics={"jes": jes, "xsec": 0.10},
257
+ )
249
258
  return rf.plot(
250
- varied,
259
+ [zjets, diboson, signal],
251
260
  met,
252
261
  observed=data,
253
262
  stack=True,
@@ -272,9 +281,9 @@ def ratio_reference(
272
281
  stays visible on light and dark pages."""
273
282
  return rf.plot(
274
283
  [
275
- zjets.with_(color=plt.rcParams["text.color"], histtype="errorbar"),
276
- diboson.with_(color="#d95f02"),
277
- signal.with_(color="#1b9e77", histtype="fill"),
284
+ zjets.replace(color=plt.rcParams["text.color"], histtype="errorbar"),
285
+ diboson.replace(color="#d95f02"),
286
+ signal.replace(color="#1b9e77", histtype="fill"),
278
287
  ],
279
288
  rf.Variable("nJet", bins=(9, -0.5, 8.5), label="Jet multiplicity"),
280
289
  normalize=True,
@@ -413,12 +422,12 @@ def density_flow(
413
422
  def object_vs_event(signal: rf.Sample, pt: rf.Variable, style: rf.Style) -> rf.Plot:
414
423
  """``Muon_pt`` is a list per event. A per-object cut such as ``Muon_pt > 100`` masks
415
424
  individual muons, while ``any(Muon_pt > 100)`` is per event: it keeps whole events, with all
416
- their muons, soft ones included. ``Sample.with_`` derives variants of a sample."""
425
+ their muons, soft ones included. ``Sample.replace`` derives variants of a sample."""
417
426
  return rf.plot(
418
427
  [
419
- signal.with_(label="All muons"),
420
- signal.with_(label="Muon_pt > 100", selection="Muon_pt > 100"),
421
- signal.with_(label="any(Muon_pt > 100)", selection="any(Muon_pt > 100)"),
428
+ signal.replace(label="All muons"),
429
+ signal.replace(label="Muon_pt > 100", selection="Muon_pt > 100"),
430
+ signal.replace(label="any(Muon_pt > 100)", selection="any(Muon_pt > 100)"),
422
431
  ],
423
432
  pt,
424
433
  logy=True,
@@ -433,12 +442,12 @@ def expressions(signal: rf.Sample, pt: rf.Variable, style: rf.Style) -> rf.Plot:
433
442
  ``rf.histogram`` returns a plain ``hist.Hist``; ``rf.plot_histograms`` draws any collection
434
443
  of them with the usual options."""
435
444
  all_muons = rf.histogram(signal, pt)
436
- leading = rf.histogram(signal, pt.with_(expression="first(Muon_pt)"))
437
- momentum = rf.histogram(signal, pt.with_(expression="Muon_pt * cosh(Muon_eta)"))
445
+ leading = rf.histogram(signal, pt.replace(expression="first(Muon_pt)"))
446
+ momentum = rf.histogram(signal, pt.replace(expression="Muon_pt * cosh(Muon_eta)"))
438
447
  return rf.plot_histograms(
439
448
  [all_muons, leading, momentum],
440
449
  labels=["All muons", "Leading muon", r"Muon $|\vec{p}|$"],
441
- variable=pt.with_(label=r"$p_T^{\mu}$ or $|\vec{p}^{\,\mu}|$"),
450
+ variable=pt.replace(label=r"$p_T^{\mu}$ or $|\vec{p}^{\,\mu}|$"),
442
451
  logy=True,
443
452
  style=style,
444
453
  )
@@ -54,7 +54,7 @@ from rootfig.histograms import (
54
54
  from rootfig.model import Cut, Sample, Style, Systematic, Variable, log_bins
55
55
  from rootfig.plotting import Plot, dark_theme, use_style
56
56
 
57
- __version__ = "0.4.0"
57
+ __version__ = "0.5.0"
58
58
 
59
59
  __all__ = [
60
60
  "BinningError",
@@ -40,12 +40,12 @@ def style_for(
40
40
  """Resolve ``style`` and add free text lines and the luminosity used for scaling."""
41
41
  resolved = as_style(style)
42
42
  if lumi is not None and resolved.lumi is None:
43
- resolved = resolved.with_(lumi=lumi)
43
+ resolved = resolved.replace(lumi=lumi)
44
44
  if text is None:
45
45
  return resolved
46
46
  existing = list(resolved.text_lines)
47
47
  extra = [text] if isinstance(text, str) else list(text)
48
- return resolved.with_(text=[*existing, *extra])
48
+ return resolved.replace(text=[*existing, *extra])
49
49
 
50
50
 
51
51
  def normalize_for_plot(histogram_: Histogram, spec: NormalizeSpec) -> Histogram:
@@ -167,7 +167,7 @@ def histogram(
167
167
  ... ) # doctest: +SKIP
168
168
  >>> h.values().sum() # doctest: +SKIP
169
169
  """
170
- samples = [sample.with_(systematics={}) for sample in as_samples(data, tree=tree)]
170
+ samples = [sample.replace(systematics={}) for sample in as_samples(data, tree=tree)]
171
171
  results = histograms(
172
172
  samples,
173
173
  variable,
@@ -95,13 +95,13 @@ def efficiency(
95
95
  ... ) # doctest: +SKIP
96
96
  """
97
97
  # efficiencies are statistical only: systematics are neither evaluated nor needed
98
- samples = [s.with_(systematics={}) for s in as_samples(data, tree=tree, labels=label)]
98
+ samples = [s.replace(systematics={}) for s in as_samples(data, tree=tree, labels=label)]
99
99
  var = as_variable(variable, bins=bins, range=range, label=xlabel, unit=unit)
100
100
  logx = var.log if logx is None else logx
101
101
  totals = build_histograms(
102
102
  samples, var, selection=selection, weight=weight, lumi=lumi, nonfinite=nonfinite
103
103
  )
104
- fixed = var.with_(bins=totals[0].axis) # same binning for the numerators
104
+ fixed = var.replace(bins=totals[0].axis) # same binning for the numerators
105
105
  pass_cut = as_cut(passed)
106
106
  if pass_cut is None:
107
107
  msg = "efficiency() needs a 'passed' selection"
@@ -117,7 +117,7 @@ def efficiency(
117
117
  ]
118
118
  resolved_style = style_for(style, text, lumi)
119
119
  if legend is not None:
120
- resolved_style = resolved_style.with_(legend=legend)
120
+ resolved_style = resolved_style.replace(legend=legend)
121
121
  with style_context(resolved_style) as st:
122
122
  layout = make_figure(st, ratio=False, ax=ax, figsize=figsize)
123
123
  cycle = iter(color_cycle(len(samples), st))
@@ -249,7 +249,7 @@ def profile(
249
249
  ]
250
250
  resolved_style = style_for(style, text, lumi)
251
251
  if legend is not None:
252
- resolved_style = resolved_style.with_(legend=legend)
252
+ resolved_style = resolved_style.replace(legend=legend)
253
253
  if ylabel is None:
254
254
  ylabel = var_y.axis_label if statistic == "mean" else f"Std. dev. of {var_y.axis_label}"
255
255
  with style_context(resolved_style) as st:
@@ -260,7 +260,7 @@ def profile(
260
260
  finish_axes(
261
261
  layout.main,
262
262
  data_range=(low, high),
263
- xlabel=var_x.with_(bins=axis).axis_label,
263
+ xlabel=var_x.replace(bins=axis).axis_label,
264
264
  ylabel=ylabel,
265
265
  xlim=xlim or (float(edges[0]), float(edges[-1])),
266
266
  ylim=ylim,
@@ -231,7 +231,7 @@ def plot(
231
231
  samples = as_samples(data, tree=tree, labels=label)
232
232
  if observed is not None:
233
233
  observed_samples = [
234
- s if s.is_data else s.with_(is_data=True) for s in as_samples(observed, tree=tree)
234
+ s if s.is_data else s.replace(is_data=True) for s in as_samples(observed, tree=tree)
235
235
  ]
236
236
  samples = [*samples, *observed_samples]
237
237
  var = as_variable(variable, bins=bins, range=range, label=xlabel, unit=unit)
@@ -335,7 +335,7 @@ def plot_histograms(
335
335
  histograms_ = [normalize_for_plot(h, normalize) for h in histograms_]
336
336
  resolved_style = as_style(style)
337
337
  if legend is not None:
338
- resolved_style = resolved_style.with_(legend=legend)
338
+ resolved_style = resolved_style.replace(legend=legend)
339
339
 
340
340
  # The y label quotes the bin width of the histogram as filled, before flow bins are added.
341
341
  label_widths = histograms_[0].widths
@@ -559,7 +559,7 @@ def _wrap_hists(
559
559
  wrapped: list[Histogram] = []
560
560
  for index, item in enumerate(hists):
561
561
  if isinstance(item, Histogram):
562
- wrapped.append(item if labels is None else item.with_(label=labels[index]))
562
+ wrapped.append(item if labels is None else item.replace(label=labels[index]))
563
563
  continue
564
564
  if labels is not None:
565
565
  label = labels[index]
@@ -147,7 +147,7 @@ class Histogram:
147
147
  up shift around the nominal contents. Summarised by
148
148
  :func:`~rootfig.histograms.uncertainty`. The mapping is copied and made
149
149
  read-only; every stored pair contains two histograms. Use
150
- ``histogram.with_(variations=...)`` to replace it. The underlying
150
+ ``histogram.replace(variations=...)`` to replace it. The underlying
151
151
  ``hist.Hist`` objects remain mutable. Observed data (``is_data``) cannot
152
152
  carry variations, as for :class:`~rootfig.model.Sample`.
153
153
  """
@@ -307,8 +307,8 @@ class Histogram:
307
307
  """
308
308
  return None if self.stats is None else self.stats.entries
309
309
 
310
- def with_(self, **changes: Any) -> Histogram:
311
- """Return a copy with the given fields replaced."""
310
+ def replace(self, **changes: Any) -> Histogram:
311
+ """Return a copy with the given fields changed, e.g. ``h.replace(label="B")``."""
312
312
  return replace(self, **changes)
313
313
 
314
314
  def map_hists(self, transform: Callable[[Hist], Hist]) -> Histogram:
@@ -154,7 +154,7 @@ def normalize(histogram: Histogram, spec: NormalizeSpec) -> Histogram:
154
154
  return histogram
155
155
  result, applied = _normalize_hist(histogram.hist, spec)
156
156
  if not applied:
157
- return histogram.with_(hist=result, normalization=None)
157
+ return histogram.replace(hist=result, normalization=None)
158
158
  label = normalization_label(spec)
159
159
  variations = {}
160
160
  for name, pair in histogram.variations.items():
@@ -169,7 +169,7 @@ def normalize(histogram: Histogram, spec: NormalizeSpec) -> Histogram:
169
169
  raise SystematicError(msg)
170
170
  normalized.append(shifted)
171
171
  variations[name] = (normalized[0], normalized[1])
172
- return histogram.with_(hist=result, normalization=label, variations=variations)
172
+ return histogram.replace(hist=result, normalization=label, variations=variations)
173
173
 
174
174
 
175
175
  def normalization_label(spec: NormalizeSpec) -> str | None:
@@ -384,7 +384,7 @@ def _variant_sample(sample: Sample, spec: Any, context: str) -> Sample:
384
384
  nominal sample's resolved number of generated events; files read their own.
385
385
  """
386
386
  if isinstance(spec, Sample):
387
- return spec.with_(label=context)
387
+ return spec.replace(label=context)
388
388
  nominal = sample.source
389
389
  try:
390
390
  if isinstance(nominal, FileSource | ArraySource) and (
@@ -413,7 +413,7 @@ def _variant_sample(sample: Sample, spec: Any, context: str) -> Sample:
413
413
  and not callable(getattr(source, "read_scalar", None))
414
414
  ):
415
415
  changes["ngen"] = sample.generated_events()
416
- return sample.with_(**changes)
416
+ return sample.replace(**changes)
417
417
 
418
418
 
419
419
  def _is_file_spec(spec: Any) -> bool:
@@ -77,7 +77,7 @@ class Sample:
77
77
  ``Systematic.samples(...)`` for varied files. Sources
78
78
  with the same name in several samples are fully correlated; different
79
79
  names are independent. Not allowed together with ``is_data=True``. The mapping is copied and
80
- made read-only; use ``sample.with_(systematics=...)`` to change it.
80
+ made read-only; use ``sample.replace(systematics=...)`` to change it.
81
81
 
82
82
  Examples
83
83
  --------
@@ -198,10 +198,10 @@ class Sample:
198
198
  """The resolved input files, or an empty tuple for in-memory sources."""
199
199
  return self.source.files if isinstance(self.source, FileSource) else ()
200
200
 
201
- def with_(self, **changes: Any) -> Sample:
202
- """Return a copy with the given fields replaced, e.g. ``sample.with_(label="B")``.
201
+ def replace(self, **changes: Any) -> Sample:
202
+ """Return a copy with the given fields changed, e.g. ``sample.replace(label="B")``.
203
203
 
204
- Replacement values are validated and normalised exactly as by the
204
+ New values are validated and normalised exactly as by the
205
205
  constructor (``selection`` accepts a string, ``source`` anything
206
206
  :func:`~rootfig.io.as_source` accepts, ``scale`` must be finite, ...).
207
207
  """
@@ -222,7 +222,7 @@ class Sample:
222
222
  return clone
223
223
 
224
224
 
225
- # -- field validation shared by the constructor and with_() ---------------------------------
225
+ # -- field validation shared by the constructor and replace() ---------------------------------
226
226
 
227
227
 
228
228
  def _normalise_weight(weight: str | None, label: str) -> str | None:
@@ -319,7 +319,7 @@ def as_samples(
319
319
  samples = [data]
320
320
  elif isinstance(data, Mapping) and _looks_like_label_map(data):
321
321
  samples = [
322
- value.with_(label=key)
322
+ value.replace(label=key)
323
323
  if isinstance(value, Sample)
324
324
  else Sample(value, tree=tree, label=key, entry_start=entry_start, entry_stop=entry_stop)
325
325
  for key, value in data.items()
@@ -342,7 +342,7 @@ def as_samples(
342
342
  if len(label_list) != len(samples):
343
343
  msg = f"got {len(label_list)} labels for {len(samples)} samples"
344
344
  raise SourceError(msg)
345
- samples = [s.with_(label=lab) for s, lab in zip(samples, label_list, strict=True)]
345
+ samples = [s.replace(label=lab) for s, lab in zip(samples, label_list, strict=True)]
346
346
  return samples
347
347
 
348
348
 
@@ -115,8 +115,8 @@ class Style:
115
115
  return tuple(self.text.split("\n"))
116
116
  return tuple(self.text)
117
117
 
118
- def with_(self, **changes: Any) -> Style:
119
- """Return a copy with the given fields replaced (``dataclasses.replace``)."""
118
+ def replace(self, **changes: Any) -> Style:
119
+ """Return a copy with the given fields changed, e.g. ``style.replace(lumi=140)``."""
120
120
  return replace(self, **changes)
121
121
 
122
122
 
@@ -91,8 +91,8 @@ class Variable:
91
91
  base = self.label if self.label is not None else self.expression
92
92
  return f"{base} [{self.unit}]" if self.unit else base
93
93
 
94
- def with_(self, **changes: Any) -> Variable:
95
- """Return a copy with the given fields replaced (``dataclasses.replace``)."""
94
+ def replace(self, **changes: Any) -> Variable:
95
+ """Return a copy with the given fields changed, e.g. ``var.replace(bins=20)``."""
96
96
  return replace(self, **changes)
97
97
 
98
98
 
@@ -975,7 +975,9 @@ class TestFigureShape:
975
975
  [narrow_name] = [t for t in narrow.ax.texts if isinstance(t, hep.label.ExpLabel)]
976
976
  assert narrow_name.get_fontsize() < wide_name.get_fontsize()
977
977
  # an explicit position inside the frame is kept for 2D plots too
978
- inside = rf.plot2d(signal_file, "MET", "nMuon", tree="events", style=cms.with_(label_loc=1))
978
+ inside = rf.plot2d(
979
+ signal_file, "MET", "nMuon", tree="events", style=cms.replace(label_loc=1)
980
+ )
979
981
  inside.fig.canvas.draw()
980
982
  renderer = inside.fig.canvas.get_renderer() # type: ignore[attr-defined]
981
983
  [name] = [t for t in inside.ax.texts if isinstance(t, hep.label.ExpLabel)]
@@ -98,7 +98,7 @@ class TestHistogram:
98
98
  scaled = histogram.scaled(2.0)
99
99
  assert scaled.values().tolist() == [4.0, 4.0, 2.0]
100
100
  assert scaled.variances().tolist() == [8.0, 16.0, 4.0]
101
- assert histogram.with_(label="x").label == "x"
101
+ assert histogram.replace(label="x").label == "x"
102
102
 
103
103
  def test_scaled_keeps_statistics_consistent(self, histogram: Histogram) -> None:
104
104
  assert histogram.stats is not None
@@ -1026,13 +1026,13 @@ class TestVariations:
1026
1026
  del histogram.variations["shape"] # type: ignore[attr-defined]
1027
1027
  with pytest.raises(TypeError):
1028
1028
  Histogram(nominal, "MC").variations["new"] = (up, up) # type: ignore[index]
1029
- changed = histogram.with_(variations={"norm": (nominal * 1.1, None)})
1029
+ changed = histogram.replace(variations={"norm": (nominal * 1.1, None)})
1030
1030
  assert list(changed.variations) == ["norm"]
1031
1031
  assert list(histogram.variations) == ["shape"]
1032
1032
  with pytest.raises(TypeError):
1033
1033
  changed.variations["new"] = (up, up) # type: ignore[index]
1034
1034
  with pytest.raises(SystematicError, match="binning"):
1035
- histogram.with_(variations={"bad": (contents([1.0]), None)})
1035
+ histogram.replace(variations={"bad": (contents([1.0]), None)})
1036
1036
 
1037
1037
  @pytest.mark.parametrize("operation", ["copy", "deepcopy", "pickle"])
1038
1038
  def test_variations_support_copy_and_pickle(self, operation: str) -> None:
@@ -1057,7 +1057,7 @@ class TestVariations:
1057
1057
  histogram = Histogram(
1058
1058
  nominal, "MC", sample, stats, False, "red", "step", "unity", {"s": (nominal, None)}
1059
1059
  )
1060
- changed = histogram.with_(label="renamed")
1060
+ changed = histogram.replace(label="renamed")
1061
1061
  assert changed.label == "renamed"
1062
1062
  assert changed.sample is sample
1063
1063
  assert changed.stats is stats
@@ -1095,8 +1095,8 @@ class TestVariations:
1095
1095
  Histogram(nominal, "Data", is_data=True, variations={"s": (nominal, None)})
1096
1096
  simulated = Histogram(nominal, "MC", variations={"s": (nominal, None)})
1097
1097
  with pytest.raises(SystematicError, match="observed data"):
1098
- simulated.with_(is_data=True)
1099
- assert simulated.with_(is_data=True, variations={}).is_data
1098
+ simulated.replace(is_data=True)
1099
+ assert simulated.replace(is_data=True, variations={}).is_data
1100
1100
 
1101
1101
  def test_down_is_mirrored_and_binning_checked(self) -> None:
1102
1102
  nominal = contents([10.0, 20.0])
@@ -1264,7 +1264,7 @@ class TestSystematicsPipeline:
1264
1264
  np.testing.assert_allclose(hists[0].variations["lumi"][0].values(), 1.5 * hists[0].values())
1265
1265
  assert hists[1].variations == {}
1266
1266
  with pytest.raises(SystematicError, match="observed data"):
1267
- build_histograms([data.with_(systematics={"s": 0.1})], "x")
1267
+ build_histograms([data.replace(systematics={"s": 0.1})], "x")
1268
1268
 
1269
1269
  def test_binning_from_nominal_and_single_read(self, arrays: dict[str, Any]) -> None:
1270
1270
  sample = Sample(
@@ -1471,7 +1471,7 @@ class TestSystematicsRegressions:
1471
1471
  with pytest.raises(MissingBranchError, match="pi"):
1472
1472
  build_histograms([sample], Variable("x", bins=(2, 0, 2)))
1473
1473
  # A name resolving to a mathematical constant is not a branch to replace.
1474
- sample = sample.with_(systematics={"s": {"pi": "missing"}})
1474
+ sample = sample.replace(systematics={"s": {"pi": "missing"}})
1475
1475
  (h,) = build_histograms([sample], Variable("pi", bins=(4, 0, 4)))
1476
1476
  np.testing.assert_allclose(h.variations["s"][0].values(), h.values())
1477
1477
 
@@ -82,7 +82,7 @@ class TestVariable:
82
82
  var = Variable("Muon_pt / 1000", label=r"$p_T$", unit="GeV")
83
83
  assert var.axis_label == r"$p_T$ [GeV]"
84
84
  assert var.safe_name == "Muon_pt_1000"
85
- assert var.with_(name="pt").safe_name == "pt"
85
+ assert var.replace(name="pt").safe_name == "pt"
86
86
 
87
87
  def test_invalid_expression(self) -> None:
88
88
  with pytest.raises(ExpressionError):
@@ -117,7 +117,7 @@ class TestVariable:
117
117
  with pytest.raises(ValueError, match="path separators"):
118
118
  Variable("x", name=name)
119
119
  with pytest.raises(ValueError, match="path separators"):
120
- Variable("x").with_(name=name)
120
+ Variable("x").replace(name=name)
121
121
 
122
122
  def test_name_keeps_plain_stems(self) -> None:
123
123
  assert Variable("x", name="pt-lead.window").safe_name == "pt-lead.window"
@@ -442,7 +442,7 @@ class TestSample:
442
442
 
443
443
  def test_with(self, signal_file: Path) -> None:
444
444
  sample = Sample(signal_file, tree="events")
445
- other = sample.with_(label="new", selection="MET > 1")
445
+ other = sample.replace(label="new", selection="MET > 1")
446
446
  assert other.label == "new"
447
447
  assert other.selection == Cut("MET > 1")
448
448
  assert other.source is sample.source
@@ -450,21 +450,21 @@ class TestSample:
450
450
  def test_with_validates_like_init(self) -> None:
451
451
  sample = Sample({"x": np.arange(2.0)})
452
452
  with pytest.raises(ValueError, match="scale must be"):
453
- sample.with_(scale=np.nan)
453
+ sample.replace(scale=np.nan)
454
454
  with pytest.raises(LuminosityError, match="finite"):
455
- sample.with_(ngen=np.inf)
455
+ sample.replace(ngen=np.inf)
456
456
  with pytest.raises(LuminosityError):
457
- sample.with_(xsec="bad")
457
+ sample.replace(xsec="bad")
458
458
  with pytest.raises(SourceError, match="cannot interpret"):
459
- sample.with_(source=42)
459
+ sample.replace(source=42)
460
460
  with pytest.raises(TypeError, match="weight must be"):
461
- sample.with_(weight=42)
461
+ sample.replace(weight=42)
462
462
  with pytest.raises(TypeError, match="label must be"):
463
- sample.with_(label=3)
464
- assert sample.with_(weight=" ").weight is None
465
- assert sample.with_(scale=2).scale == 2.0
466
- assert sample.with_(source=sample.source).source is sample.source
467
- assert sample.with_(xsec="1.2 fb").xsec == "1.2 fb"
463
+ sample.replace(label=3)
464
+ assert sample.replace(weight=" ").weight is None
465
+ assert sample.replace(scale=2).scale == 2.0
466
+ assert sample.replace(source=sample.source).source is sample.source
467
+ assert sample.replace(xsec="1.2 fb").xsec == "1.2 fb"
468
468
 
469
469
  def test_existing_source_rejects_entry_range(self, signal_file: Path) -> None:
470
470
  source = FileSource(signal_file, tree="events")
@@ -531,7 +531,7 @@ class TestStyle:
531
531
  assert as_style("ggplot") == Style(base="ggplot")
532
532
  style = Style(lumi=140)
533
533
  assert as_style(style) is style
534
- assert style.with_(com=13.6).com == 13.6
534
+ assert style.replace(com=13.6).com == 13.6
535
535
  with pytest.raises(TypeError):
536
536
  as_style(3) # type: ignore[arg-type]
537
537
 
@@ -742,10 +742,12 @@ class TestSystematic:
742
742
  sample = Sample({"x": [1.0, 2.0]}, label="S", systematics={"n": 0.1})
743
743
  assert sample.systematics == {"n": Systematic("norm", 1.1, 0.9)}
744
744
  assert "systematics=['n']" in repr(sample)
745
- assert sample.with_(systematics={"w": "x"}).systematics == {"w": Systematic("weight", "x")}
745
+ assert sample.replace(systematics={"w": "x"}).systematics == {
746
+ "w": Systematic("weight", "x")
747
+ }
746
748
  assert Sample({"x": [1.0]}).systematics == {}
747
749
  with pytest.raises(SystematicError, match="sample 'S': systematic 'bad'"):
748
- sample.with_(systematics={"bad": object()})
750
+ sample.replace(systematics={"bad": object()})
749
751
 
750
752
  @pytest.mark.parametrize(
751
753
  ("kind", "up", "down"),
@@ -787,12 +789,12 @@ class TestSystematic:
787
789
  Sample(columns, is_data=True, systematics={"s": 0.1})
788
790
  data = Sample(columns, is_data=True, systematics={}) # an empty mapping is fine
789
791
  with pytest.raises(SystematicError, match="observed data"):
790
- data.with_(systematics={"s": 0.1})
792
+ data.replace(systematics={"s": 0.1})
791
793
  mc = Sample(columns, systematics={"s": 0.1})
792
794
  with pytest.raises(SystematicError, match="observed data"):
793
- mc.with_(is_data=True)
794
- assert mc.with_(is_data=True, systematics={}).is_data
795
- assert data.with_(is_data=False, systematics={"s": 0.1}).systematics
795
+ mc.replace(is_data=True)
796
+ assert mc.replace(is_data=True, systematics={}).is_data
797
+ assert data.replace(is_data=False, systematics={"s": 0.1}).systematics
796
798
 
797
799
  def test_systematic_mappings_are_read_only_snapshots(self) -> None:
798
800
  branches = {"x": ("x_up", "x_down")}
@@ -812,7 +814,7 @@ class TestSystematic:
812
814
  with pytest.raises(TypeError):
813
815
  Sample({"x": [1.0]}).systematics["extra"] = systematic # type: ignore[index]
814
816
 
815
- updated = sample.with_(systematics={"norm": 0.1})
817
+ updated = sample.replace(systematics={"norm": 0.1})
816
818
  assert list(updated.systematics) == ["norm"]
817
819
  assert list(sample.systematics) == ["shape"]
818
820
  with pytest.raises(TypeError):
@@ -1220,7 +1220,7 @@ class TestHist2DMask:
1220
1220
 
1221
1221
 
1222
1222
  def with_variation(histogram: Histogram, factor: float) -> Histogram:
1223
- return histogram.with_(variations={"s": (histogram.hist * factor, None)})
1223
+ return histogram.replace(variations={"s": (histogram.hist * factor, None)})
1224
1224
 
1225
1225
 
1226
1226
  class TestSystematicDrawing:
@@ -1251,7 +1251,7 @@ class TestSystematicDrawing:
1251
1251
  def test_flow_bins_carry_variations(self) -> None:
1252
1252
  nominal = make_hist([1.5, 5.0], label="A") # 5.0 is overflow
1253
1253
  up = make_hist([-1.0, 1.5], label="up") # underflow only in the variation
1254
- varied = nominal.with_(variations={"s": (up.hist, None)})
1254
+ varied = nominal.replace(variations={"s": (up.hist, None)})
1255
1255
  (shown,), (under, over) = show_flow_bins([varied])
1256
1256
  assert (under, over) == (True, True)
1257
1257
  np.testing.assert_allclose(shown.variations["s"][0].values(), [1, 0, 1, 0, 0, 0])
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes