|
3 | 3 | #include "TTree.h"
|
4 | 4 | #include "gtest/gtest.h"
|
5 | 5 |
|
| 6 | +#include <memory> |
| 7 | +#include <TClonesArray.h> |
| 8 | +#include <TLorentzVector.h> |
| 9 | +#include <ROOT/RVec.hxx> |
| 10 | +#include <ROOT/TestSupport.hxx> |
6 | 11 |
|
7 | 12 | using namespace ROOT::VecOps;
|
8 | 13 |
|
| 14 | +template <typename T0, typename T1> |
| 15 | +void expect_vec_float_eq(const T0 &v1, const T1 &v2) |
| 16 | +{ |
| 17 | + ASSERT_EQ(v1.size(), v2.size()) << "Vectors 'v1' and 'v2' are of unequal length"; |
| 18 | + for (std::size_t i = 0ull; i < v1.size(); ++i) { |
| 19 | + EXPECT_FLOAT_EQ(v1[i], v2[i]) << "Vectors 'v1' and 'v2' differ at index " << i; |
| 20 | + } |
| 21 | +} |
| 22 | + |
9 | 23 | struct BrVal {
|
10 | 24 | Float_t a;
|
11 | 25 | Int_t i;
|
@@ -72,3 +86,44 @@ TEST(RDFLeaves, OneLeafWithDotNameClass)
|
72 | 86 | EXPECT_EQ(*res, 40);
|
73 | 87 | }
|
74 | 88 |
|
| 89 | +TEST(RDFLeaves, LeafFromTClonesArray) |
| 90 | +{ |
| 91 | + // Regression test for https://github.com/root-project/root/issues/19104 |
| 92 | + ROOT::TestSupport::CheckDiagsRAII diagRAII; |
| 93 | + diagRAII.requiredDiag(kWarning, "TTree::Bronch", |
| 94 | + "Using split mode on a class: TLorentzVector with a custom Streamer"); |
| 95 | +#ifndef NDEBUG |
| 96 | + diagRAII.requiredDiag( |
| 97 | + kWarning, "RTreeColumnReader::Get", |
| 98 | + "Branch ca.fE hangs from a non-split branch. A copy is being performed in order to properly read the content."); |
| 99 | +#endif |
| 100 | + constexpr static auto fName{"leaffromtclonesarray.root"}; |
| 101 | + struct Dataset { |
| 102 | + Dataset() |
| 103 | + { |
| 104 | + auto f = std::make_unique<TFile>(fName, "recreate"); |
| 105 | + auto t = std::make_unique<TTree>("t", "t"); |
| 106 | + auto ca = std::make_unique<TClonesArray>("TLorentzVector"); |
| 107 | + auto branchData = ca.get(); |
| 108 | + auto &caRef = *ca; |
| 109 | + t->Branch("ca", &branchData); |
| 110 | + // Fill the array with two elements. The issue arose from the fact |
| 111 | + // we were not computing the correct size of the correction value |
| 112 | + // type, so the wrong offset was used when reading back next elements |
| 113 | + // of the array |
| 114 | + new (caRef[0]) TLorentzVector(0, 0, 0, 42.42); |
| 115 | + new (caRef[1]) TLorentzVector(0, 0, 0, 84.84); |
| 116 | + t->Fill(); |
| 117 | + f->Write(); |
| 118 | + } |
| 119 | + |
| 120 | + ~Dataset() { std::remove(fName); } |
| 121 | + } _; |
| 122 | + |
| 123 | + std::vector expected{42.42, 84.84}; |
| 124 | + |
| 125 | + ROOT::RDataFrame df("t", fName); |
| 126 | + auto resultptr = df.Take<ROOT::RVecD>("ca.fE"); |
| 127 | + ASSERT_EQ(resultptr->size(), 1); |
| 128 | + expect_vec_float_eq(expected, resultptr->at(0)); |
| 129 | +} |
0 commit comments