uproot 5.7.3__tar.gz → 5.7.4__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.
- {uproot-5.7.3 → uproot-5.7.4}/.github/workflows/build-test.yml +13 -9
- {uproot-5.7.3 → uproot-5.7.4}/.github/workflows/upload-nightly-wheels.yml +1 -1
- {uproot-5.7.3 → uproot-5.7.4}/.pre-commit-config.yaml +2 -2
- {uproot-5.7.3 → uproot-5.7.4}/PKG-INFO +1 -1
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/basic.rst +16 -5
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TProfile.py +62 -26
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/reading.py +11 -6
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/fsspec.py +26 -10
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/version.py +2 -2
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/_cascade.py +37 -34
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/_dask_write.py +15 -12
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/identify.py +91 -20
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/writable.py +25 -18
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1000-write-TProfiles.py +1 -1
- uproot-5.7.4/tests/test_1085_dask_write.py +89 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1393_TTree_virtual_arrays.py +9 -10
- uproot-5.7.4/tests/test_1609_tprofiles.py +307 -0
- uproot-5.7.4/tests/test_1622_bigfile_boundary_crossing.py +33 -0
- uproot-5.7.3/tests/test_1085_dask_write.py +0 -83
- {uproot-5.7.3 → uproot-5.7.4}/.all-contributorsrc +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/dependabot.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/workflows/build-distributions.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/workflows/deploy.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.github/workflows/semantic-pr-title.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.gitignore +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/.readthedocs.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/CITATION.cff +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/CONTRIBUTING.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/LICENSE +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/README.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/codecov.yml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/dev/custom-interpretation/README.md +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/dev/example-objects.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/dev/make-models.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/diagrams/abstraction-layers.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/diagrams/abstraction-layers.svg +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/diagrams/example-dask-graph.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/diagrams/uproot-awkward-timeline.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/diagrams/uproot-awkward-timeline.svg +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/logo/logo-300px-white.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/logo/logo-300px.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/logo/logo-600px.png +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/logo/logo.svg +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-img/photos/switcheroo.jpg +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/_templates/breadcrumbs.html +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/conf.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/index.rst +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/make_changelog.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/prepare_docstrings.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/requirements.txt +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/docs-sphinx/uproot3-to-4.rst +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/pyproject.toml +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/_awkwardforth.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/_dask.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/_util.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behavior.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/RNTuple.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/RooCurve.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/RooHist.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TAxis.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TBranch.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TBranchElement.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TDatime.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TGraph.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TGraphAsymmErrors.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TGraphErrors.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TH1.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TH2.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TH2Poly.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TH3.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TParameter.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TProfile2D.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TProfile3D.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/TTree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/behaviors/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/cache.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/compression.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/const.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/containers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/deserialization.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/dynamic.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/exceptions.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/extras.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/custom.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/grouped.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/identify.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/jagged.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/known_forth/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/known_forth/atlas.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/library.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/numerical.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/objects.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/interpretation/strings.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/language/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/language/python.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/model.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/RNTuple.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TArray.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TAtt.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TBasket.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TBranch.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TClonesArray.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TDatime.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TGraph.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TH.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/THashList.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TLeaf.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TList.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TMatrixT.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TNamed.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TObjArray.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TObjString.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TObject.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TRef.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TString.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TTable.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TTime.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/TTree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/models/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/pyroot.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/serialization.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/sink/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/sink/file.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/chunk.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/coalesce.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/cufile_interface.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/cursor.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/file.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/futures.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/http.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/object.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/source/xrootd.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/streamers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/_cascadentuple.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/_cascadetree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/src/uproot/writing/interpret.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/conftest.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/samples/h_dynamic.pkl +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0001_source_class.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0006_notify_when_downloaded.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0007_single_chunk_interface.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0008_start_interpretation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0009_nested_directories.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0010_start_streamers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0011_generate_classes_from_streamers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0013_rntuple_anchor.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0014_all_ttree_versions.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0016_interpretations.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0017_multi_basket_multi_branch_fetch.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0018_array_fetching_interface.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0022_number_of_branches.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0023_more_interpretations_1.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0023_ttree_versions.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0028_fallback_to_read_streamer.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0029_more_string_types.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0031_test_stl_containers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0033_more_interpretations_2.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0034_generic_objects_in_ttrees.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0035_datatype_generality.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0038_memberwise_serialization.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0043_iterate_function.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0044_concatenate_function.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0046_histograms_bh_hist.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0053_parents_should_not_be_bases.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0058_detach_model_objects_from_files.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0066_fix_http_fallback_freeze.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0067_common_entry_offsets.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0081_dont_parse_colons.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0087_memberwise_splitting_not_implemented_messages.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0088_read_with_http.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0099_read_from_file_object.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0112_fix_pandas_with_cut.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0118_fix_name_fetch_again.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0123_atlas_issues.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0126_turn_unknown_emptyarrays_into_known_types.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0167_use_the_common_histogram_interface.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0172_allow_allocators_in_vector_typenames.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0173_empty_and_multiprocessing_bugs.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0182_complain_about_missing_files.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0194_fix_lost_cuts_in_iterate.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0220_contiguous_byte_ranges_in_http.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0228_read_TProfiles.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0240_read_TGraphAsymmErrors.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0278_specializations_for_TParameter.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0302_pickle.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0303_empty_jagged_array.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0320_start_working_on_ROOT_writing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0322_writablefile_infrastructure.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0329_update_existing_root_files.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0335_empty_ttree_division_by_zero.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0341_manipulate_streamer_info.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0344_writabledirectory_can_read.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0345_bulk_copy_method.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0349_write_TObjString.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0350_read_RooCurve_RooHist.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0351_write_TList.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0352_write_THashList.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0384_move_behavior_of_and_fix_383.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0398_dimensions_in_leaflist.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0405_write_a_histogram.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0406_write_a_ttree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0407_read_TDatime.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0412_write_multidimensional_numpy_to_ttree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0414_write_jagged_arrays.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0416_writing_compressed_data.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0418_read_TTable.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0420_pyroot_uproot_interoperability.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0422_hist_integration.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0430_global_index_for_tuples_of_DataFrames.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0438_TClonesArray_is_not_AsGrouped.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0439_check_awkward_before_numpy.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0442_regular_TClonesArray.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0472_tstreamerinfo_for_ttree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0475_remember_to_update_freesegments.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0484_manually_add_model_for_TMatrixTSym_double_.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0487_implement_asdtypeinplace.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0498_create_leaf_branch_in_extend.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0519_remove_memmap_copy.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0520_dynamic_classes_cant_be_abc_subclasses.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0569_fBits_is_4_bytes.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0576_unicode_in_names.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0578_dask_for_numpy.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0580_round_trip_for_no_flow_histograms.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0589_explicitly_interpret_RVec_type.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0603_dask_delayed_open.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0609_num_enteries_func.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0610_awkward_form.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0630_rntuple_basics.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0637_setup_tests_for_AwkwardForth.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0643_reading_vector_pair_TLorentzVector_int.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0651_implement_transformed_axis.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0652_dask_for_awkward.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0662_rntuple_stl_containers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0692_fsspec_reading.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0692_fsspec_writing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0700_dask_empty_arrays.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0705_rntuple_writing_metadata.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0750_avoid_empty_TBasket_issue.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0755_dask_awkward_column_projection.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0791_protect_uproot_project_columns_from_dask_node_names.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0798_DAOD_PHYSLITE.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0808_fix_awkward_form_for_AsStridedObjects.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0816_separate_AwkwardForth_machines_by_TBranch.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0832_ak_add_doc_should_also_add_to_typetracer.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0840_support_tleafG.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0841_fix_814.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0844_fix_delete_hist_from_root.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0852_fix_strided_interp_extra_offsets.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0870_writing_arrays_of_type_unknown_fix_822.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0876_uproot_dask_blind_steps.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0886_fix_awkward_form_breadcrumbs.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0910_fix_906_members_non_numerical_branches.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0911_fix_interp_array_non_numerical_objs_issue_880.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0912_fix_pandas_and_double_nested_vectors_issue_885.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0916_read_from_s3.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0927_dont_assume_uproot_in_global_scope_in_TPython_Eval.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0930_expressions_in_pandas.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0940_feat_add_TLeafC_string_support.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0962_rntuple_update.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0965_inverted_axes_variances_hist_888.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_0976_path_object_split.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1043_const_std_string.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1058_dask_awkward_report.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1063_dask_distributed.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1070_pandas_dataframe_building_performance_fix.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1102_any_locks_in_models_must_be_transient.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1114_fix_attempt_to_concatenate_numpy_with_awkward.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1120_check_decompression_executor_pass_for_dask.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1127_fix_allow_colon_in_key_names.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1128_TGraph_writing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1146_split_ranges_for_large_files_over_http.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1154_classof_using_relative_path.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1159_rntuple_cluster_groups.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1160_std_string_in_TDirectory.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1180_read_free_floating_vector_issue_1179.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1181_support_for_stl_list.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1182_add_support_for_bitset.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1183_ttime_custom.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1186_dtype_might_raise_ValueError.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1189_dask_failing_on_duplicate_keys.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1191_rntuple_fixes.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1198_coalesce.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1207_fix_title_of_TBranch_with_counter.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1212_dont_let_update_mess_up_file_version.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1221_AwkwardForth_bug.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1223_more_rntuple_types.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1229_const_in_typename.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1250_rntuple_improvements.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1254_test_threadpool_executor_for_dask.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1264_write_NumPy_array_of_strings.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1275_fix_TStreamerLoop_code_generation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1282_add_known_forth_for_atlas.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1285_rntuple_multicluster_concatenation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1318_dont_compare_big_endian_in_awkward.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1321_pandas_changed_api_again.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1347_rntuple_floats_suppressed_cols.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1356_basic_rntuple_writing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1375_extend_ak_add_doc.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1395_rntuple_writing_lists_and_structs.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1406_improved_rntuple_methods.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1411_rntuple_physlite_ATLAS.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1412_rntuple_dask.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1465_ignorecase_extension.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1467_rntuple_akform_construction.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1476_rntuple_jagged_subfields.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1477_custom_interpretation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1492_rntuple_hidden_keys.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1496_rntuple_write_index_arrays.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1503_rntuple_virtual_arrays.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1510_rntuple_v1010.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1556_default_rntuple_writing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1573_out_of_bounds_slicing.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1589_rntuple_inheritance.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1591_rntuple_read_to_numpy.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1599_mktree_mkrntuple_with_subdir.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1601_freesegments_stale_allocation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1603_num_entries.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1604_write_tuple_dtypes.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests/test_1610_read_TMatrixTSym_from_ttree.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_0630_rntuple_basics.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_0662_rntuple_stl_containers.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_0962_rntuple_update.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1159_rntuple_cluster_groups.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1191_rntuple_fixes.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1223_more_rntuple_types.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1250_rntuple_improvements.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1285_rntuple_multicluster_concatenation.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1347_rntuple_floats_suppressed_cols.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-cuda/test_1411_rntuple_physlite_ATLAS.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-wasm/__init__.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-wasm/test_1272_basic_functionality.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-wasm/test_1365_awkwardforth_reading.py +0 -0
- {uproot-5.7.3 → uproot-5.7.4}/tests-wasm/utils.py +0 -0
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
fail-fast: false
|
|
17
17
|
matrix:
|
|
18
18
|
platform: [windows-latest, macos-latest, ubuntu-latest]
|
|
19
|
-
python-version: ['3.10', '3.
|
|
19
|
+
python-version: ['3.10', '3.14', 3.14 python-freethreading]
|
|
20
20
|
|
|
21
21
|
runs-on: ${{ matrix.platform }}
|
|
22
22
|
timeout-minutes: 30
|
|
@@ -39,10 +39,14 @@ jobs:
|
|
|
39
39
|
conda-forge/label/python_rc::_python_rc
|
|
40
40
|
python=${{ matrix.python-version }}
|
|
41
41
|
|
|
42
|
-
-
|
|
42
|
+
- name: Set PYTHON_GIL=0 for free-threaded builds
|
|
43
|
+
if: contains(matrix.python-version, 'python-freethreading')
|
|
44
|
+
run: echo "PYTHON_GIL=0" >> $GITHUB_ENV
|
|
45
|
+
|
|
46
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
43
47
|
|
|
44
48
|
- name: Check active Python version
|
|
45
|
-
run: python -c "import sys; assert '.'.join(str(s) for s in sys.version_info[:2]) == '${{ matrix.python-version }}', f'{version} incorrect!'"
|
|
49
|
+
run: python -c "import sys; assert '.'.join(str(s) for s in sys.version_info[:2]) == '${{ matrix.python-version }}'.split()[0], f'{version} incorrect!'"
|
|
46
50
|
|
|
47
51
|
- name: Install ROOT
|
|
48
52
|
if: matrix.python-version == 3.10 && runner.os == 'Linux'
|
|
@@ -94,7 +98,7 @@ jobs:
|
|
|
94
98
|
python-version: ${{ matrix.python-version }}
|
|
95
99
|
allow-prereleases: true
|
|
96
100
|
|
|
97
|
-
- uses: astral-sh/setup-uv@
|
|
101
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
98
102
|
|
|
99
103
|
- name: Pip install the package
|
|
100
104
|
run: uv pip install --system -e. --group=dev
|
|
@@ -120,7 +124,7 @@ jobs:
|
|
|
120
124
|
with:
|
|
121
125
|
python-version: ${{ matrix.python-version }}
|
|
122
126
|
|
|
123
|
-
- uses: astral-sh/setup-uv@
|
|
127
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
124
128
|
|
|
125
129
|
- name: Pip install the package
|
|
126
130
|
run: |
|
|
@@ -148,7 +152,7 @@ jobs:
|
|
|
148
152
|
with:
|
|
149
153
|
python-version: '3.13'
|
|
150
154
|
|
|
151
|
-
- uses: astral-sh/setup-uv@
|
|
155
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
152
156
|
|
|
153
157
|
- name: Install pyodide-build
|
|
154
158
|
run: python3 -m pip install pyodide-build==$PYODIDE_BUILD_VERSION
|
|
@@ -162,7 +166,7 @@ jobs:
|
|
|
162
166
|
echo "emsdk-version=$EMSCRIPTEN_VERSION" >> $GITHUB_OUTPUT
|
|
163
167
|
|
|
164
168
|
- name: Install EMSDK
|
|
165
|
-
uses: mymindstorm/setup-emsdk@
|
|
169
|
+
uses: mymindstorm/setup-emsdk@v16
|
|
166
170
|
with:
|
|
167
171
|
version: ${{ steps.compute-emsdk-version.outputs.emsdk-version }}
|
|
168
172
|
|
|
@@ -229,7 +233,6 @@ jobs:
|
|
|
229
233
|
init-shell: bash
|
|
230
234
|
create-args: >-
|
|
231
235
|
-c rapidsai
|
|
232
|
-
-c nvidia
|
|
233
236
|
python=3.13
|
|
234
237
|
cuda-version=${{ matrix.cuda-version }}
|
|
235
238
|
cuda-toolkit
|
|
@@ -263,9 +266,10 @@ jobs:
|
|
|
263
266
|
|
|
264
267
|
- name: Upload test results to Codecov
|
|
265
268
|
if: ${{ !cancelled() && matrix.cuda-version == 13 }}
|
|
266
|
-
uses: codecov/
|
|
269
|
+
uses: codecov/codecov-action@v6
|
|
267
270
|
with:
|
|
268
271
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
272
|
+
report_type: test_results
|
|
269
273
|
|
|
270
274
|
pass:
|
|
271
275
|
if: always()
|
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
run: ls -lha dist/*.whl
|
|
34
34
|
|
|
35
35
|
- name: Upload wheel to Anaconda Cloud as nightly
|
|
36
|
-
uses: scientific-python/upload-nightly-action@
|
|
36
|
+
uses: scientific-python/upload-nightly-action@e76cfec8a4611fd02808a801b0ff5a7d7c1b2d99 # 0.6.4
|
|
37
37
|
with:
|
|
38
38
|
artifacts_path: dist
|
|
39
39
|
anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }}
|
|
@@ -19,12 +19,12 @@ repos:
|
|
|
19
19
|
- id: trailing-whitespace
|
|
20
20
|
|
|
21
21
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
|
22
|
-
rev: 26.1
|
|
22
|
+
rev: 26.3.1
|
|
23
23
|
hooks:
|
|
24
24
|
- id: black
|
|
25
25
|
|
|
26
26
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
27
|
-
rev: v0.15.
|
|
27
|
+
rev: v0.15.9
|
|
28
28
|
hooks:
|
|
29
29
|
- id: ruff-check
|
|
30
30
|
args: [--fix, --show-fixes]
|
|
@@ -924,6 +924,8 @@ Reading RNTuples
|
|
|
924
924
|
|
|
925
925
|
TTree has been the default format to store large datasets in ROOT files for decades. However, it has slowly become outdated and is not optimized for modern systems. This is where the RNTuple format comes in. It is a modern serialization format that is designed with modern systems in mind and is planned to replace TTree in the coming years. `Version 1.0.0.0 <https://cds.cern.ch/record/2923186>`__ is out and will be supported "forever".
|
|
926
926
|
|
|
927
|
+
Starting in Uproot v5.7.0, RNTuple is the default format for writing. When you use the dict-like syntax to write data to a file, Uproot will create an RNTuple instead of a TTree.
|
|
928
|
+
|
|
927
929
|
RNTuples are deliberately simpler than TTrees by design. For the first time, there’s an official specification, making it much easier for third-party I/O tools like Uproot to support it. Uproot already supports reading the full RNTuple specification, meaning that you can read any RNTuple you find in the wild. It also already supports writing a large part of the specification, and intends to support as much as it makes sense for data analysis.
|
|
928
930
|
|
|
929
931
|
To ease the transition into RNTuples, we are designing the interface to closely match the existing TTree interface. Many of the functionality explained in the previous subsections works in the same way. However, there the terminology is slightly different (e.g. "branch" becomes "field") and arguments may vary slightly, accordingly.
|
|
@@ -1145,8 +1147,10 @@ Writing TTrees to a file
|
|
|
1145
1147
|
TTrees are a special type of object, just as TDirectories are special: data can be cumulatively added to them.
|
|
1146
1148
|
|
|
1147
1149
|
:doc:`uproot.writing.writable.WritableTree` objects can be created using the :ref:`uproot.writing.writable.WritableDirectory.mktree` method that Uproot provides for TDirectories.
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
+
|
|
1151
|
+
.. note::
|
|
1152
|
+
|
|
1153
|
+
Starting in v5.7.0, Uproot uses RNTuples as the default format for writing data when using the dict-like assignment syntax (e.g., ``file["my_data"] = {"my_array": np.arange(1000)}``). If you specifically want to write a TTree, you should use the :ref:`uproot.writing.writable.WritableDirectory.mktree` method.
|
|
1150
1154
|
|
|
1151
1155
|
.. code-block:: python
|
|
1152
1156
|
|
|
@@ -1327,14 +1331,21 @@ Writing RNTuples
|
|
|
1327
1331
|
|
|
1328
1332
|
Just like with reading, writing RNTuples is similar to writing TTree objects. Since RNTuples are much simpler, we aim to be able to write almost any RNTuple that you might want.
|
|
1329
1333
|
|
|
1330
|
-
|
|
1334
|
+
RNTuples are the default format for writing data starting in Uproot v5.7.0. You can write an RNTuple by using a dict-like syntax:
|
|
1331
1335
|
|
|
1332
1336
|
.. code-block:: python
|
|
1333
1337
|
|
|
1334
1338
|
>>> file = uproot.recreate("example.root")
|
|
1335
1339
|
>>> data = {"my_int": [1,2], "my_vector": [[1,2], [3,4,5]]}
|
|
1336
|
-
>>>
|
|
1337
|
-
>>>
|
|
1340
|
+
>>> file["my_rntuple"] = data
|
|
1341
|
+
>>> file["my_rntuple"].extend(data) # Can be extended, just like TTrees
|
|
1342
|
+
|
|
1343
|
+
You can also use the :ref:`uproot.writing.writable.WritableDirectory.mkrntuple` method for more explicit RNTuple creation, and to have the ability to initialize an empty RNTuple from a type specification dictionary or an Awkward form.
|
|
1344
|
+
|
|
1345
|
+
.. code-block:: python
|
|
1346
|
+
|
|
1347
|
+
>>> file.mkrntuple("ntuple", {"x": "f4", "y": "var * int64"})
|
|
1348
|
+
<WritableNTuple '/ntuple' at 0x000131ff30e0>
|
|
1338
1349
|
|
|
1339
1350
|
Using your own interpretation
|
|
1340
1351
|
--------------------------------
|
|
@@ -103,11 +103,11 @@ def _values_errors_1d(error_mode, fBinEntries, root_cont, fSumw2, fNcells, fBinS
|
|
|
103
103
|
|
|
104
104
|
root_neff = _effective_counts_1d(fBinEntries, fBinSumw2, fNcells)
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
root_eprisum_sq_dev = numpy.zeros(len(root_cont), dtype=numpy.float64)
|
|
107
|
+
root_eprisum_sq_dev[nonzero] = abs(
|
|
108
108
|
root_err2[nonzero] / root_sum[nonzero] - root_contsum[nonzero] ** 2
|
|
109
109
|
)
|
|
110
|
-
root_eprim = numpy.sqrt(
|
|
110
|
+
root_eprim = numpy.sqrt(root_eprisum_sq_dev)
|
|
111
111
|
|
|
112
112
|
if error_mode == _kERRORSPREADI:
|
|
113
113
|
numer = numpy.ones(len(root_cont), dtype=numpy.float64)
|
|
@@ -237,7 +237,7 @@ class TProfile(Profile):
|
|
|
237
237
|
@property
|
|
238
238
|
def weighted(self):
|
|
239
239
|
fBinSumw2 = self.member("fBinSumw2", none_if_missing=True)
|
|
240
|
-
return fBinSumw2 is None
|
|
240
|
+
return fBinSumw2 is not None and len(fBinSumw2) == self.member("fNcells")
|
|
241
241
|
|
|
242
242
|
def counts(self, flow=True):
|
|
243
243
|
out = _effective_counts_1d(
|
|
@@ -298,40 +298,76 @@ class TProfile(Profile):
|
|
|
298
298
|
boost_histogram = uproot.extras.boost_histogram()
|
|
299
299
|
|
|
300
300
|
effective_counts = self.counts(flow=True)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
301
|
+
sum_of_bin_weights = numpy.asarray(
|
|
302
|
+
self.member("fBinEntries"), dtype=numpy.float64
|
|
303
|
+
)
|
|
304
|
+
raw_values = numpy.asarray(self._bases[0]._bases[-1], dtype=numpy.float64)
|
|
305
|
+
fSumw2_member = self.member("fSumw2", none_if_missing=True)
|
|
306
|
+
fNcells = self.member("fNcells")
|
|
307
|
+
|
|
308
|
+
# Compute mean = sum(y) / count (ROOT TProfile stores sum(y) in the TArray)
|
|
309
|
+
nonzero = sum_of_bin_weights != 0
|
|
310
|
+
mean_values = numpy.zeros(len(raw_values), dtype=numpy.float64)
|
|
311
|
+
mean_values[nonzero] = raw_values[nonzero] / sum_of_bin_weights[nonzero]
|
|
312
|
+
|
|
313
|
+
# Compute sum_sq_dev = sum(y^2) - count * mean^2 directly from fSumw2.
|
|
314
|
+
# fErrorMode is intentionally ignored here: it controls how ROOT displays
|
|
315
|
+
# bin errors but does not change the underlying data. boost-hostogram's
|
|
316
|
+
# storage has a fixed meaning for _sum_of_weighted_deltas_squared,
|
|
317
|
+
# so we can't change it based on fErrorMode.
|
|
318
|
+
if fSumw2_member is not None:
|
|
319
|
+
fSumw2 = numpy.asarray(fSumw2_member, dtype=numpy.float64)
|
|
320
|
+
else:
|
|
321
|
+
fSumw2 = numpy.array([], dtype=numpy.float64)
|
|
322
|
+
if len(fSumw2) == fNcells:
|
|
323
|
+
sum_sq_dev = numpy.maximum(
|
|
324
|
+
fSumw2 - sum_of_bin_weights * mean_values**2, 0.0
|
|
325
|
+
)
|
|
326
|
+
else:
|
|
327
|
+
sum_sq_dev = numpy.zeros(len(raw_values), dtype=numpy.float64)
|
|
305
328
|
|
|
306
|
-
|
|
329
|
+
if self.weighted:
|
|
330
|
+
storage = boost_histogram.storage.WeightedMean()
|
|
331
|
+
else:
|
|
332
|
+
storage = boost_histogram.storage.Mean()
|
|
307
333
|
|
|
308
334
|
xaxis = uproot.behaviors.TH1._boost_axis(self.member("fXaxis"), axis_metadata)
|
|
309
335
|
out = boost_histogram.Histogram(xaxis, storage=storage)
|
|
310
336
|
for k, v in metadata.items():
|
|
311
337
|
setattr(out, k, self.member(v))
|
|
312
338
|
|
|
313
|
-
if
|
|
339
|
+
if self.member("fXaxis").member("fLabels") is not None:
|
|
340
|
+
# ROOT's categorical axes (with fLabels) always have an underflow bin (bin 0).
|
|
341
|
+
# boost-histogram's Category axes do not have underflow.
|
|
342
|
+
# We slice off the first ROOT bin (underflow) to align with boost-histogram.
|
|
314
343
|
effective_counts = effective_counts[1:]
|
|
315
|
-
|
|
316
|
-
|
|
344
|
+
mean_values = mean_values[1:]
|
|
345
|
+
sum_sq_dev = sum_sq_dev[1:]
|
|
317
346
|
sum_of_bin_weights = sum_of_bin_weights[1:]
|
|
318
347
|
|
|
319
|
-
|
|
348
|
+
# TODO: This should only be needed for weighted storage, but there seems to be some bug in Uproot's serialization of fBinSumw2
|
|
349
|
+
# that causes weighted TProfiles to appear unweighted when read back in.
|
|
350
|
+
out.metadata = {
|
|
351
|
+
"fEntries": self.member("fEntries"),
|
|
352
|
+
}
|
|
320
353
|
view = out.view(flow=True)
|
|
321
354
|
|
|
322
355
|
# https://github.com/root-project/root/blob/ffc7c588ac91aca30e75d356ea971129ee6a836a/hist/hist/src/TProfileHelper.h#L668-L671
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
356
|
+
if self.weighted:
|
|
357
|
+
with numpy.errstate(divide="ignore", invalid="ignore"):
|
|
358
|
+
sum_of_bin_weights_squared = (sum_of_bin_weights**2) / effective_counts
|
|
359
|
+
|
|
360
|
+
# TODO: Drop this when boost-histogram has a way to set using the constructor.
|
|
361
|
+
# New version should look something like this:
|
|
362
|
+
# view[...] = np.stack(sum_of_bin_weights, sum_of_bin_weights_squared, mean_values, sum_sq_dev)
|
|
363
|
+
# Current / classic version:
|
|
364
|
+
view["sum_of_weights"] = sum_of_bin_weights
|
|
365
|
+
view["sum_of_weights_squared"] = sum_of_bin_weights_squared
|
|
366
|
+
view["value"] = mean_values
|
|
367
|
+
view["_sum_of_weighted_deltas_squared"] = sum_sq_dev
|
|
368
|
+
else:
|
|
369
|
+
view["count"] = sum_of_bin_weights
|
|
370
|
+
view["value"] = mean_values
|
|
371
|
+
view["_sum_of_deltas_squared"] = sum_sq_dev
|
|
336
372
|
|
|
337
373
|
return out
|
|
@@ -646,11 +646,15 @@ in file {file_path}""")
|
|
|
646
646
|
:ref:`uproot.reading.ReadOnlyFile.object_cache` would still be
|
|
647
647
|
accessible.
|
|
648
648
|
"""
|
|
649
|
-
self._source
|
|
649
|
+
if hasattr(self, "_source") and hasattr(self._source, "close"):
|
|
650
|
+
self._source.close()
|
|
650
651
|
if hasattr(self._decompression_executor, "shutdown"):
|
|
651
|
-
|
|
652
|
+
self._decompression_executor.shutdown()
|
|
652
653
|
if hasattr(self._interpretation_executor, "shutdown"):
|
|
653
|
-
|
|
654
|
+
self._interpretation_executor.shutdown()
|
|
655
|
+
|
|
656
|
+
def __del__(self):
|
|
657
|
+
self.close()
|
|
654
658
|
|
|
655
659
|
@property
|
|
656
660
|
def closed(self):
|
|
@@ -674,11 +678,12 @@ in file {file_path}""")
|
|
|
674
678
|
return self
|
|
675
679
|
|
|
676
680
|
def __exit__(self, exception_type, exception_value, traceback):
|
|
677
|
-
self._source
|
|
681
|
+
if hasattr(self, "_source") and hasattr(self._source, "__exit__"):
|
|
682
|
+
self._source.__exit__(exception_type, exception_value, traceback)
|
|
678
683
|
if hasattr(self._decompression_executor, "shutdown"):
|
|
679
|
-
|
|
684
|
+
self._decompression_executor.shutdown()
|
|
680
685
|
if hasattr(self._interpretation_executor, "shutdown"):
|
|
681
|
-
|
|
686
|
+
self._interpretation_executor.shutdown()
|
|
682
687
|
|
|
683
688
|
@property
|
|
684
689
|
def source(self):
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import concurrent.futures
|
|
7
|
+
import contextlib
|
|
7
8
|
import queue
|
|
8
9
|
import re
|
|
9
10
|
|
|
@@ -55,20 +56,20 @@ class FSSpecSource(uproot.source.chunk.Source):
|
|
|
55
56
|
|
|
56
57
|
file_path = _maybe_wrap_remote_url(file_path)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
self._fsspec_options = {
|
|
59
60
|
k: v for k, v in options.items() if k not in uproot.reading.open.defaults
|
|
60
61
|
}
|
|
61
|
-
self.
|
|
62
|
-
|
|
63
|
-
# What should we do when there is a chain of filesystems?
|
|
64
|
-
self._async_impl = self._fs.async_impl
|
|
65
|
-
|
|
62
|
+
self._file_path_orig = file_path
|
|
66
63
|
self._open()
|
|
67
64
|
|
|
68
|
-
self.__enter__()
|
|
69
|
-
|
|
70
65
|
def _open(self):
|
|
71
66
|
self._executor = FSSpecLoopExecutor()
|
|
67
|
+
self._open_file = fsspec.open(self._file_path_orig, **self._fsspec_options)
|
|
68
|
+
self._fs = self._open_file.fs
|
|
69
|
+
self._file_path = self._open_file.path
|
|
70
|
+
self._fo = self._open_file.__enter__()
|
|
71
|
+
self._async_impl = self._fs.async_impl
|
|
72
|
+
self._closed = False
|
|
72
73
|
|
|
73
74
|
def __repr__(self):
|
|
74
75
|
path = repr(self._file_path)
|
|
@@ -79,6 +80,9 @@ class FSSpecSource(uproot.source.chunk.Source):
|
|
|
79
80
|
def __getstate__(self):
|
|
80
81
|
state = dict(self.__dict__)
|
|
81
82
|
state.pop("_executor")
|
|
83
|
+
state.pop("_open_file")
|
|
84
|
+
state.pop("_fo")
|
|
85
|
+
state.pop("_fs")
|
|
82
86
|
return state
|
|
83
87
|
|
|
84
88
|
def __setstate__(self, state):
|
|
@@ -90,6 +94,19 @@ class FSSpecSource(uproot.source.chunk.Source):
|
|
|
90
94
|
|
|
91
95
|
def __exit__(self, exception_type, exception_value, traceback):
|
|
92
96
|
self._executor.shutdown()
|
|
97
|
+
if not self._closed:
|
|
98
|
+
self._open_file.__exit__(exception_type, exception_value, traceback)
|
|
99
|
+
|
|
100
|
+
# Workaround for leaking fsspec filesystems (like ZipFileSystem/TarFileSystem)
|
|
101
|
+
# that don't correctly close their underlying file objects.
|
|
102
|
+
if hasattr(self._fs, "close"):
|
|
103
|
+
with contextlib.suppress(Exception):
|
|
104
|
+
self._fs.close()
|
|
105
|
+
if hasattr(self._fs, "of") and hasattr(self._fs.of, "__exit__"):
|
|
106
|
+
with contextlib.suppress(Exception):
|
|
107
|
+
self._fs.of.__exit__(None, None, None)
|
|
108
|
+
|
|
109
|
+
self._closed = True
|
|
93
110
|
|
|
94
111
|
def chunk(self, start: int, stop: int) -> uproot.source.chunk.Chunk:
|
|
95
112
|
"""
|
|
@@ -199,8 +216,7 @@ class FSSpecSource(uproot.source.chunk.Source):
|
|
|
199
216
|
True if the associated file/connection/thread pool is closed; False
|
|
200
217
|
otherwise.
|
|
201
218
|
"""
|
|
202
|
-
|
|
203
|
-
return False
|
|
219
|
+
return self._closed
|
|
204
220
|
|
|
205
221
|
|
|
206
222
|
class FSSpecLoopExecutor(uproot.source.futures.Executor):
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '5.7.
|
|
22
|
-
__version_tuple__ = version_tuple = (5, 7,
|
|
21
|
+
__version__ = version = '5.7.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (5, 7, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -451,6 +451,28 @@ _free_format_small = struct.Struct(">HII")
|
|
|
451
451
|
_free_format_big = struct.Struct(">HQQ")
|
|
452
452
|
|
|
453
453
|
|
|
454
|
+
def _slices_bytes(slices):
|
|
455
|
+
total = 0
|
|
456
|
+
for _, stop in slices:
|
|
457
|
+
if stop - 1 >= uproot.const.kStartBigFile:
|
|
458
|
+
total += _free_format_big.size
|
|
459
|
+
else:
|
|
460
|
+
total += _free_format_small.size
|
|
461
|
+
return total
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def _free_segments_num_bytes(slices, file_end, data_location=0):
|
|
465
|
+
total = _slices_bytes(slices)
|
|
466
|
+
|
|
467
|
+
if file_end is None:
|
|
468
|
+
file_end = (data_location or 0) + total + _free_format_small.size
|
|
469
|
+
|
|
470
|
+
if file_end >= uproot.const.kStartBigFile:
|
|
471
|
+
return total + _free_format_big.size
|
|
472
|
+
else:
|
|
473
|
+
return total + _free_format_small.size
|
|
474
|
+
|
|
475
|
+
|
|
454
476
|
class FreeSegmentsData(CascadeLeaf):
|
|
455
477
|
"""
|
|
456
478
|
A :doc:`uproot.writing._cascade.CascadeLeaf` for the FreeSegments record
|
|
@@ -502,24 +524,12 @@ class FreeSegmentsData(CascadeLeaf):
|
|
|
502
524
|
|
|
503
525
|
@property
|
|
504
526
|
def num_bytes(self):
|
|
505
|
-
|
|
506
|
-
for _, stop in self._slices:
|
|
507
|
-
if stop - 1 >= uproot.const.kStartBigFile:
|
|
508
|
-
total += _free_format_big.size
|
|
509
|
-
else:
|
|
510
|
-
total += _free_format_small.size
|
|
511
|
-
|
|
512
|
-
if self._end is None:
|
|
513
|
-
if total + _free_format_small.size >= uproot.const.kStartBigFile:
|
|
514
|
-
total += _free_format_big.size
|
|
515
|
-
else:
|
|
516
|
-
total += _free_format_small.size
|
|
517
|
-
elif self._end >= uproot.const.kStartBigFile:
|
|
518
|
-
total += _free_format_big.size
|
|
519
|
-
else:
|
|
520
|
-
total += _free_format_small.size
|
|
527
|
+
return _free_segments_num_bytes(self._slices, self._end, self._location)
|
|
521
528
|
|
|
522
|
-
|
|
529
|
+
def required_end(self, data_location):
|
|
530
|
+
return data_location + _free_segments_num_bytes(
|
|
531
|
+
self._slices, None, data_location
|
|
532
|
+
)
|
|
523
533
|
|
|
524
534
|
def serialize(self):
|
|
525
535
|
pairs = []
|
|
@@ -660,8 +670,8 @@ class FreeSegments(CascadeNode):
|
|
|
660
670
|
out = self._key.location
|
|
661
671
|
if not dry_run:
|
|
662
672
|
self._key.location = self._key.location + num_bytes
|
|
663
|
-
self._data.end = (
|
|
664
|
-
self._key.location + self._key.
|
|
673
|
+
self._data.end = self._data.required_end(
|
|
674
|
+
self._key.location + self._key.num_bytes
|
|
665
675
|
)
|
|
666
676
|
return out
|
|
667
677
|
|
|
@@ -707,25 +717,18 @@ class FreeSegments(CascadeNode):
|
|
|
707
717
|
|
|
708
718
|
@staticmethod
|
|
709
719
|
def _slices_bytes(slices):
|
|
710
|
-
|
|
711
|
-
for _, stop in slices:
|
|
712
|
-
if stop - 1 >= uproot.const.kStartBigFile:
|
|
713
|
-
total += _free_format_big.size
|
|
714
|
-
else:
|
|
715
|
-
total += _free_format_small.size
|
|
716
|
-
return total
|
|
720
|
+
return _slices_bytes(slices)
|
|
717
721
|
|
|
718
722
|
def release(self, start, stop):
|
|
719
723
|
new_slices = self._another_slice(self._data.slices, start, stop)
|
|
720
724
|
|
|
721
725
|
if self.at_end:
|
|
722
726
|
self._data.slices = new_slices
|
|
723
|
-
self._data.
|
|
727
|
+
self._data.end = self._data.required_end(
|
|
728
|
+
self._key.location + self._key.num_bytes
|
|
729
|
+
)
|
|
724
730
|
self._key.uncompressed_bytes = self._data.allocation
|
|
725
731
|
self._key.compressed_bytes = self._key.uncompressed_bytes
|
|
726
|
-
self._data.end = (
|
|
727
|
-
self._key.location + self._key.allocation + self._key.uncompressed_bytes
|
|
728
|
-
)
|
|
729
732
|
|
|
730
733
|
elif self._slices_bytes(new_slices) <= self._slices_bytes(self._data.slices):
|
|
731
734
|
# Wherever the FreeSegments record is, it's not getting bigger.
|
|
@@ -744,12 +747,12 @@ class FreeSegments(CascadeNode):
|
|
|
744
747
|
self._key.location,
|
|
745
748
|
self._key.location + self._key.allocation + self._data.allocation,
|
|
746
749
|
)
|
|
747
|
-
self.
|
|
750
|
+
self._key.location = self._data.end
|
|
751
|
+
self._data.end = self._data.required_end(
|
|
752
|
+
self._key.location + self._key.num_bytes
|
|
753
|
+
)
|
|
748
754
|
self._key.uncompressed_bytes = self._data.allocation
|
|
749
755
|
self._key.compressed_bytes = self._key.uncompressed_bytes
|
|
750
|
-
self._key.location = self._data.end
|
|
751
|
-
self._data.location = self._key.location + self._key.allocation
|
|
752
|
-
self._data.end = self._data.location + self._key.uncompressed_bytes
|
|
753
756
|
|
|
754
757
|
def write(self, sink):
|
|
755
758
|
self._key.uncompressed_bytes = self._data.allocation
|
|
@@ -176,19 +176,22 @@ def ak_to_root(
|
|
|
176
176
|
**(storage_options or {}),
|
|
177
177
|
)
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
179
|
+
try:
|
|
180
|
+
branch_types = {name: array[name].type for name in array.fields}
|
|
181
|
+
|
|
182
|
+
out_file.mktree(
|
|
183
|
+
tree_name,
|
|
184
|
+
branch_types,
|
|
185
|
+
title=title,
|
|
186
|
+
counter_name=counter_name,
|
|
187
|
+
field_name=field_name,
|
|
188
|
+
initial_basket_capacity=initial_basket_capacity,
|
|
189
|
+
resize_factor=resize_factor,
|
|
190
|
+
)
|
|
190
191
|
|
|
191
|
-
|
|
192
|
+
out_file[tree_name].extend({name: array[name] for name in array.fields})
|
|
193
|
+
finally:
|
|
194
|
+
out_file.close()
|
|
192
195
|
|
|
193
196
|
|
|
194
197
|
def none_to_none(*_):
|