uproot-custom 1.2.0__tar.gz → 2.0.0.dev0__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 (82) hide show
  1. uproot_custom-2.0.0.dev0/.github/workflows/deploy-docs.yml +34 -0
  2. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/.github/workflows/python-publish.yml +6 -1
  3. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/.github/workflows/run-pytest.yml +1 -1
  4. uproot_custom-2.0.0.dev0/PKG-INFO +79 -0
  5. uproot_custom-2.0.0.dev0/README.md +26 -0
  6. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/cpp/include/uproot-custom/uproot-custom.hh +74 -4
  7. uproot_custom-2.0.0.dev0/cpp/src/uproot-custom.cc +871 -0
  8. uproot_custom-2.0.0.dev0/docs/architecture/binary-data.md +144 -0
  9. uproot_custom-2.0.0.dev0/docs/architecture/bootstrap.md +312 -0
  10. uproot_custom-2.0.0.dev0/docs/architecture/reader-and-factory.md +396 -0
  11. uproot_custom-2.0.0.dev0/docs/architecture/streamer-info.md +275 -0
  12. uproot_custom-2.0.0.dev0/docs/binary-format.md +166 -0
  13. uproot_custom-2.0.0.dev0/docs/conf.py +65 -0
  14. uproot_custom-2.0.0.dev0/docs/examples/override-streamer.md +305 -0
  15. uproot_custom-2.0.0.dev0/docs/examples/read-tobjarray.md +421 -0
  16. uproot_custom-2.0.0.dev0/docs/get-started.md +175 -0
  17. uproot_custom-2.0.0.dev0/docs/index.md +63 -0
  18. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/README.md +51 -14
  19. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/cpp/my_reader.cc +34 -2
  20. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/gen-demo-data/CMakeLists.txt +13 -1
  21. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/LinkDef.h +22 -0
  22. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TBasicTypes.hh +62 -0
  23. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TCStyleArray.hh +62 -0
  24. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/gen-demo-data/include/TComplicatedSTL.hh +45 -18
  25. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TNestedSTL.hh +47 -0
  26. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TObjInObjArray.hh +114 -0
  27. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TRootObjects.hh +43 -0
  28. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLArray.hh +49 -0
  29. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLMap.hh +21 -0
  30. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLMapWithObj.hh +45 -0
  31. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLSeqWithObj.hh +44 -0
  32. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLSequence.hh +27 -0
  33. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSTLString.hh +14 -0
  34. uproot_custom-2.0.0.dev0/example/gen-demo-data/include/TSimpleObject.hh +43 -0
  35. uproot_custom-2.0.0.dev0/example/gen-demo-data/src/main.cc +88 -0
  36. uproot_custom-2.0.0.dev0/example/my_reader/OverrideStreamerFactory.py +46 -0
  37. uproot_custom-2.0.0.dev0/example/my_reader/TObjArrayFactory.py +76 -0
  38. uproot_custom-2.0.0.dev0/example/my_reader/__init__.py +12 -0
  39. uproot_custom-2.0.0.dev0/example/my_reader/my_reader_cpp.pyi +11 -0
  40. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/pyproject.toml +2 -2
  41. uproot_custom-2.0.0.dev0/example/read-dask.py +19 -0
  42. uproot_custom-2.0.0.dev0/example/read-data.py +26 -0
  43. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/pyproject.toml +25 -1
  44. uproot_custom-2.0.0.dev0/tests/conftest.py +19 -0
  45. uproot_custom-2.0.0.dev0/tests/test-data.root +0 -0
  46. uproot_custom-2.0.0.dev0/tests/test_AsCustom.py +299 -0
  47. uproot_custom-2.0.0.dev0/tests/test_AsGroupedMap.py +35 -0
  48. uproot_custom-2.0.0.dev0/tests/test_docs.py +15 -0
  49. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/tests/test_downstream_build.py +0 -3
  50. uproot_custom-2.0.0.dev0/uproot_custom/AsBinary.py +94 -0
  51. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/uproot_custom/AsCustom.py +57 -46
  52. uproot_custom-2.0.0.dev0/uproot_custom/AsGroupedMap.py +44 -0
  53. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/uproot_custom/__init__.py +23 -19
  54. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/uproot_custom/_version.py +3 -3
  55. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/uproot_custom/cpp.pyi +19 -5
  56. uproot_custom-2.0.0.dev0/uproot_custom/factories.py +1116 -0
  57. uproot_custom-2.0.0.dev0/uproot_custom/utils.py +116 -0
  58. uproot_custom-1.2.0/PKG-INFO +0 -343
  59. uproot_custom-1.2.0/README.md +0 -306
  60. uproot_custom-1.2.0/cpp/src/uproot-custom.cc +0 -488
  61. uproot_custom-1.2.0/example/gen-demo-data/include/LinkDef.h +0 -9
  62. uproot_custom-1.2.0/example/gen-demo-data/src/main.cc +0 -27
  63. uproot_custom-1.2.0/example/my_reader/OverrideStreamerReader.py +0 -46
  64. uproot_custom-1.2.0/example/my_reader/__init__.py +0 -13
  65. uproot_custom-1.2.0/example/read-data.py +0 -13
  66. uproot_custom-1.2.0/tests/test-data-1.root +0 -0
  67. uproot_custom-1.2.0/tests/test-data-2.root +0 -0
  68. uproot_custom-1.2.0/tests/test_AsCustom.py +0 -32
  69. uproot_custom-1.2.0/uproot_custom/AsBinary.py +0 -62
  70. uproot_custom-1.2.0/uproot_custom/readers.py +0 -946
  71. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/.clang-format +0 -0
  72. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/.github/workflows/build-wheels.yml +0 -0
  73. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/.gitignore +0 -0
  74. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/CHANGELOG.md +0 -0
  75. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/LICENSE +0 -0
  76. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/cpp/CMakeLists.txt +0 -0
  77. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/cpp/share/cmake/uproot-customConfig.cmake +0 -0
  78. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/cpp/CMakeLists.txt +0 -0
  79. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/gen-demo-data/include/TOverrideStreamer.hh +0 -0
  80. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/example/gen-demo-data/src/TOverrideStreamer.cc +0 -0
  81. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/tests/test_downstream_build_pyproject.toml +0 -0
  82. {uproot_custom-1.2.0 → uproot_custom-2.0.0.dev0}/uproot_custom/share/cmake/__init__.py +0 -0
@@ -0,0 +1,34 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ workflow_call:
6
+
7
+ permissions:
8
+ contents: write
9
+
10
+ jobs:
11
+ deploy-docs:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v4
18
+ with:
19
+ python-version: '3.13'
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install .[docs]
25
+
26
+ - name: Build docs
27
+ run: |
28
+ sphinx-build -b html docs/ build/html
29
+
30
+ - name: Deploy to GitHub Pages
31
+ uses: peaceiris/actions-gh-pages@v3
32
+ with:
33
+ github_token: ${{ secrets.GITHUB_TOKEN }}
34
+ publish_dir: ./build/html
@@ -13,12 +13,17 @@ on:
13
13
  types: [published]
14
14
 
15
15
  permissions:
16
- contents: read
16
+ contents: write
17
17
 
18
18
  jobs:
19
19
  build-wheels:
20
20
  uses: ./.github/workflows/build-wheels.yml
21
21
 
22
+ deploy-docs:
23
+ uses: ./.github/workflows/deploy-docs.yml
24
+ needs:
25
+ - pypi-publish
26
+
22
27
  pypi-publish:
23
28
  runs-on: ubuntu-latest
24
29
  needs:
@@ -34,4 +34,4 @@ jobs:
34
34
  - name: Run pytest
35
35
  run: |
36
36
  pytest --version
37
- pytest tests/
37
+ pytest -n auto tests/
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.2
2
+ Name: uproot-custom
3
+ Version: 2.0.0.dev0
4
+ Summary: uproot extension for reading custom classes
5
+ Author-Email: Mingrun Li <mrli@ihep.ac.cn>
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Intended Audience :: Information Technology
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Operating System :: Unix
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
24
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
25
+ Classifier: Topic :: Scientific/Engineering :: Physics
26
+ Classifier: Topic :: Software Development
27
+ Classifier: Topic :: Utilities
28
+ Project-URL: Homepage, https://github.com/mrzimu/uproot-custom
29
+ Requires-Python: <3.14,>=3.9
30
+ Requires-Dist: uproot>=5.0
31
+ Requires-Dist: numpy
32
+ Requires-Dist: awkward
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest; extra == "dev"
35
+ Requires-Dist: pytest-xdist; extra == "dev"
36
+ Requires-Dist: dask[complete]; extra == "dev"
37
+ Requires-Dist: dask-awkward; extra == "dev"
38
+ Requires-Dist: build; extra == "dev"
39
+ Provides-Extra: docs
40
+ Requires-Dist: sphinx>=8.2; extra == "docs"
41
+ Requires-Dist: sphinx-book-theme; extra == "docs"
42
+ Requires-Dist: myst_parser; extra == "docs"
43
+ Requires-Dist: sphinx-design; extra == "docs"
44
+ Requires-Dist: sphinx-copybutton; extra == "docs"
45
+ Requires-Dist: sphinxext-rediraffe; extra == "docs"
46
+ Requires-Dist: sphinxext-opengraph; extra == "docs"
47
+ Requires-Dist: sphinx-tippy; extra == "docs"
48
+ Requires-Dist: sphinx-togglebutton; extra == "docs"
49
+ Requires-Dist: sphinxcontrib-mermaid; extra == "docs"
50
+ Requires-Dist: sphinx-autobuild; extra == "docs"
51
+ Requires-Dist: sphinx-intl; extra == "docs"
52
+ Description-Content-Type: text/markdown
53
+
54
+ # Introduction
55
+
56
+ `uproot-custom` is an extension of [`uproot`](https://uproot.readthedocs.io/en/latest/basic.html) that provides an enhanced way to read custom classes stored in `TTree`.
57
+
58
+ ## When to use `uproot-custom`
59
+
60
+ `uproot-custom` aims to handle cases that classes are too complex for `uproot` to read, such as when their `Streamer` methods are overridden or some specific data members are not supported by `uproot`.
61
+
62
+ ## How `uproot-custom` works
63
+
64
+ `uproot-custom` uses a `reader`/`factory` mechanism to read classes:
65
+
66
+ - `reader` is a C++ class that implements the logic to read data from binary buffers.
67
+ - `factory` is a Python class that creates, combines `reader`s, and post-processes the data read by `reader`s.
68
+
69
+ This machanism is implemented as `uproot_custom.AsCustom` interpretation. `uproot-custom` wraps `uproot.interpretation.identify.interpretation_of` method to intercept the interpretation of specific branches. This makes `uproot-custom` well compatible with `uproot`.
70
+
71
+ > [!TIP]
72
+ > Users can implement their own `factory` and `reader`, register them to `uproot-custom`. An example of implementing a custom `factory`/`reader` can be found in [the repository](https://github.com/mrzimu/uproot-custom/tree/main/example).
73
+
74
+ > [!NOTE]
75
+ > `uproot-custom` does not provide a full reimplementation of `ROOT`'s I/O system. Users are expected to implement their own `factory`/`reader` for their custom classes that built-in factories cannot handle.
76
+
77
+ ## Documentation
78
+
79
+ View the [documentation](https://mrzimu.github.io/uproot-custom/) for more details about customizing your own `reader`/`factory`, and the architecture of `uproot-custom`.
@@ -0,0 +1,26 @@
1
+ # Introduction
2
+
3
+ `uproot-custom` is an extension of [`uproot`](https://uproot.readthedocs.io/en/latest/basic.html) that provides an enhanced way to read custom classes stored in `TTree`.
4
+
5
+ ## When to use `uproot-custom`
6
+
7
+ `uproot-custom` aims to handle cases that classes are too complex for `uproot` to read, such as when their `Streamer` methods are overridden or some specific data members are not supported by `uproot`.
8
+
9
+ ## How `uproot-custom` works
10
+
11
+ `uproot-custom` uses a `reader`/`factory` mechanism to read classes:
12
+
13
+ - `reader` is a C++ class that implements the logic to read data from binary buffers.
14
+ - `factory` is a Python class that creates, combines `reader`s, and post-processes the data read by `reader`s.
15
+
16
+ This machanism is implemented as `uproot_custom.AsCustom` interpretation. `uproot-custom` wraps `uproot.interpretation.identify.interpretation_of` method to intercept the interpretation of specific branches. This makes `uproot-custom` well compatible with `uproot`.
17
+
18
+ > [!TIP]
19
+ > Users can implement their own `factory` and `reader`, register them to `uproot-custom`. An example of implementing a custom `factory`/`reader` can be found in [the repository](https://github.com/mrzimu/uproot-custom/tree/main/example).
20
+
21
+ > [!NOTE]
22
+ > `uproot-custom` does not provide a full reimplementation of `ROOT`'s I/O system. Users are expected to implement their own `factory`/`reader` for their custom classes that built-in factories cannot handle.
23
+
24
+ ## Documentation
25
+
26
+ View the [documentation](https://mrzimu.github.io/uproot-custom/) for more details about customizing your own `reader`/`factory`, and the architecture of `uproot-custom`.
@@ -1,13 +1,16 @@
1
1
  #pragma once
2
2
 
3
- #include <cstdint>
4
- #include <memory>
5
3
  #include <pybind11/cast.h>
6
4
  #include <pybind11/detail/common.h>
7
5
  #include <pybind11/numpy.h>
8
6
  #include <pybind11/pybind11.h>
9
7
  #include <pybind11/pytypes.h>
10
8
  #include <pybind11/stl.h>
9
+
10
+ #include <cstdint>
11
+ #include <iostream>
12
+ #include <memory>
13
+ #include <sstream>
11
14
  #include <string>
12
15
 
13
16
  #if defined( _MSC_VER )
@@ -37,6 +40,8 @@ namespace uproot {
37
40
  const uint16_t kMaxVersion = 0x3FFF; // highest possible version number
38
41
  const int32_t kMapOffset = 2; // first 2 map entries are taken by null obj and self obj
39
42
 
43
+ const uint16_t kStreamedMemberWise = 1 << 14; // streamed member-wise mask
44
+
40
45
  class BinaryBuffer {
41
46
  public:
42
47
  enum EStatusBits {
@@ -125,6 +130,14 @@ namespace uproot {
125
130
  else return std::string();
126
131
  }
127
132
 
133
+ const std::string read_TString() {
134
+ uint32_t length = read<uint8_t>();
135
+ if ( length == 255 ) length = read<uint32_t>();
136
+ auto start = m_cursor;
137
+ m_cursor += length;
138
+ return std::string( start, m_cursor );
139
+ }
140
+
128
141
  void skip( const size_t n ) { m_cursor += n; }
129
142
 
130
143
  void skip_fNBytes() { read_fNBytes(); } // need to check the mask
@@ -148,9 +161,16 @@ namespace uproot {
148
161
  if ( fBits & ( kIsReferenced ) ) skip( 2 ); // pidf
149
162
  }
150
163
 
164
+ const uint8_t* get_data() const { return m_data; }
151
165
  const uint8_t* get_cursor() const { return m_cursor; }
166
+ const uint32_t* get_offsets() const { return m_offsets; }
152
167
  const uint64_t entries() const { return m_entries; }
153
168
 
169
+ void debug_print( const size_t n = 100 ) const {
170
+ for ( size_t i = 0; i < n; i++ ) { std::cout << (int)*( m_cursor + i ) << " "; }
171
+ std::cout << std::endl;
172
+ }
173
+
154
174
  private:
155
175
  uint8_t* m_cursor;
156
176
  const uint64_t m_entries;
@@ -176,6 +196,31 @@ namespace uproot {
176
196
 
177
197
  virtual void read( BinaryBuffer& buffer ) = 0;
178
198
  virtual py::object data() const = 0;
199
+
200
+ virtual uint32_t read_many( BinaryBuffer& buffer, const int64_t count ) {
201
+ for ( int32_t i = 0; i < count; i++ ) { read( buffer ); }
202
+ return count;
203
+ }
204
+
205
+ virtual uint32_t read_until( BinaryBuffer& buffer, const uint8_t* end_pos ) {
206
+ uint32_t cur_count = 0;
207
+ while ( buffer.get_cursor() < end_pos )
208
+ {
209
+ read( buffer );
210
+ cur_count++;
211
+ }
212
+ return cur_count;
213
+ }
214
+
215
+ virtual uint32_t read_many_memberwise( BinaryBuffer& buffer, const int64_t count ) {
216
+ if ( count < 0 )
217
+ {
218
+ std::stringstream msg;
219
+ msg << name() << "::read_many_memberwise with negative count: " << count;
220
+ throw std::runtime_error( msg.str() );
221
+ }
222
+ return read_many( buffer, count );
223
+ }
179
224
  };
180
225
 
181
226
  using SharedReader = shared_ptr<IElementReader>;
@@ -192,9 +237,9 @@ namespace uproot {
192
237
  }
193
238
 
194
239
  template <typename ReaderType, typename... Args>
195
- void register_reader( py::module& m, const char* name ) {
240
+ void declare_reader( py::module& m, const char* name ) {
196
241
  py::class_<ReaderType, shared_ptr<ReaderType>, IElementReader>( m, name ).def(
197
- py::init( &CreateReader<ReaderType, std::string, Args...> ) );
242
+ py::init( &CreateReader<ReaderType, Args...> ) );
198
243
  }
199
244
 
200
245
  /*
@@ -215,4 +260,29 @@ namespace uproot {
215
260
  return py::array_t<T>( size, data, capsule );
216
261
  }
217
262
 
263
+ /*
264
+ -----------------------------------------------------------------------------
265
+ -----------------------------------------------------------------------------
266
+ -----------------------------------------------------------------------------
267
+ */
268
+
269
+ template <typename... Args>
270
+ inline void debug_printf( const char* msg, Args... args ) {
271
+ bool do_print = getenv( "UPROOT_DEBUG" );
272
+ #ifdef UPROOT_DEBUG
273
+ do_print = true;
274
+ #endif
275
+ if ( !do_print ) return;
276
+ printf( msg, std::forward<Args>( args )... );
277
+ }
278
+
279
+ inline void debug_printf( uproot::BinaryBuffer& buffer, const size_t n = 100 ) {
280
+ bool do_print = getenv( "UPROOT_DEBUG" );
281
+ #ifdef UPROOT_DEBUG
282
+ do_print = true;
283
+ #endif
284
+ if ( !do_print ) return;
285
+ buffer.debug_print( n );
286
+ }
287
+
218
288
  } // namespace uproot