Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions roottest/root/ntuple/evolution/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ROOTTEST_GENERATE_DICTIONARY(
ntplevolv_v2_dict
${CMAKE_CURRENT_SOURCE_DIR}/NtplEvolv_v2.hxx
LINKDEF ${CMAKE_CURRENT_SOURCE_DIR}/NtplEvolv_v2_LinkDef.h
NO_ROOTMAP NO_CXXMODULE
FIXTURES_SETUP generated_ntplevolv_v2_dictionary
)

ROOTTEST_GENERATE_EXECUTABLE(
write_ntplevolv
write_ntplevolv.cxx ntplevolv_v2_dict.cxx
LIBRARIES Core RIO ROOTNTuple
FIXTURES_REQUIRED generated_ntplevolv_v2_dictionary
FIXTURES_SETUP write_ntplevolv_excutable)

ROOTTEST_ADD_TEST(write_ntplevolv
EXEC ./write_ntplevolv
FIXTURES_REQUIRED write_ntplevolv_excutable
FIXTURES_SETUP write_ntplevolv_done)

ROOTTEST_GENERATE_DICTIONARY(
ntplevolv_v3_dict
${CMAKE_CURRENT_SOURCE_DIR}/NtplEvolv_v3.hxx
LINKDEF ${CMAKE_CURRENT_SOURCE_DIR}/NtplEvolv_v3_LinkDef.h
NO_ROOTMAP NO_CXXMODULE
FIXTURES_SETUP generated_ntplevolv_v3_dictionary
)

ROOTTEST_GENERATE_EXECUTABLE(
read_ntplevolv
read_ntplevolv.cxx ntplevolv_v3_dict.cxx
LIBRARIES Core RIO ROOTNTuple
FIXTURES_REQUIRED generated_ntplevolv_v3_dictionary
FIXTURES_SETUP read_ntplevolv_excutable)

ROOTTEST_ADD_TEST(read_ntplevolv
EXEC ./read_ntplevolv
FIXTURES_REQUIRED read_ntplevolv_excutable write_ntplevolv_done)
12 changes: 12 additions & 0 deletions roottest/root/ntuple/evolution/NtplEvolv_v2.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef NTPL_EVOLV_V2_H
#define NTPL_EVOLV_V2_H

#include <RtypesCore.h>

struct NtplEvolv {
int fA = 0;

ClassDefNV(NtplEvolv, 2)
};

#endif // NTPL_EVOLV_V2_H
5 changes: 5 additions & 0 deletions roottest/root/ntuple/evolution/NtplEvolv_v2_LinkDef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#ifdef __ROOTCLING__

#pragma link C++ class NtplEvolv+;

#endif
13 changes: 13 additions & 0 deletions roottest/root/ntuple/evolution/NtplEvolv_v3.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef NTPL_EVOLV_V3_H
#define NTPL_EVOLV_V3_H

#include <RtypesCore.h>

struct NtplEvolv {
int fA = 0;
int fB = 0;

ClassDefNV(NtplEvolv, 3)
};

#endif // NTPL_EVOLV_V3_H
7 changes: 7 additions & 0 deletions roottest/root/ntuple/evolution/NtplEvolv_v3_LinkDef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifdef __ROOTCLING__

#pragma link C++ class NtplEvolv+;

#pragma read sourceClass="NtplEvolv" version="[1-]" source="" targetClass="NtplEvolv" target="fA" code = "{ fA = 13; }"

#endif
17 changes: 17 additions & 0 deletions roottest/root/ntuple/evolution/read_ntplevolv.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <ROOT/RNTupleReader.hxx>

#include "NtplEvolv_v3.hxx"

#include <iostream>

int main()
{
auto reader = ROOT::RNTupleReader::Open("ntpl", "root_test_ntpl_evolution.root");

reader->LoadEntry(0);

auto a = reader->GetModel().GetDefaultEntry().GetPtr<NtplEvolv>("event")->fA;
std::cout << "Result of event.fA: " << a << std::endl;

return a != 13;
}
18 changes: 18 additions & 0 deletions roottest/root/ntuple/evolution/write_ntplevolv.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <ROOT/RNTupleModel.hxx>
#include <ROOT/RNTupleWriter.hxx>

#include "NtplEvolv_v2.hxx"

#include <memory>

int main()
{
auto model = ROOT::RNTupleModel::Create();
auto event = model->MakeField<NtplEvolv>("event");
auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), "ntpl", "root_test_ntpl_evolution.root");

event->fA = 1;
writer->Fill();

return 0;
}
22 changes: 14 additions & 8 deletions tree/ntuple/src/RFieldMeta.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -541,22 +541,28 @@ std::unique_ptr<ROOT::RFieldBase> ROOT::RClassField::BeforeConnectPageSource(ROO
}
}

if (!rules.empty()) {
const bool hasSources = std::any_of(rules.begin(), rules.end(), [](const auto &r) {
return r->GetSource() && (r->GetSource()->GetEntries() > 0);
});

// A staging class (conversion streamer info) only exists if there is at least one rule that has an
// on disk source member defined.
if (hasSources) {
SetStagingClass(fieldDesc.GetTypeName(), fieldDesc.GetTypeVersion());
PrepareStagingArea(rules, desc, fieldDesc);
for (auto &[_, si] : fStagingItems) {
Internal::CallConnectPageSourceOnField(*si.fField, pageSource);
si.fField = std::move(static_cast<RFieldZero *>(si.fField.get())->ReleaseSubfields()[0]);
}
}

// Remove target member of read rules from the list of regular members of the underlying on-disk field
for (const auto rule : rules) {
if (!rule->GetTarget())
continue;
// Remove target member of read rules from the list of regular members of the underlying on-disk field
for (const auto rule : rules) {
if (!rule->GetTarget())
continue;

for (const auto target : ROOT::Detail::TRangeStaticCast<const TObjString>(*rule->GetTarget())) {
regularSubfields.erase(std::string(target->GetString()));
}
for (const auto target : ROOT::Detail::TRangeStaticCast<const TObjString>(*rule->GetTarget())) {
regularSubfields.erase(std::string(target->GetString()));
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tree/ntuple/test/CustomStructLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@
#pragma link C++ options = version(3) class NewName < int> + ;
#pragma link C++ options = version(3) class NewName < NewName < int>> + ;
#pragma read sourceClass = "OldName<OldName<int>>" targetClass = "NewName<OldName<int>>" version = "[3]"
#pragma link C++ options = version(4) class OldName<float>+;
#pragma link C++ options = version(5) class NewName<float>+;
#pragma read sourceClass = "OldName<float>" targetClass = "NewName<float>"

#pragma link C++ struct SourceStruct + ;
#pragma link C++ struct StructWithSourceStruct + ;
Expand Down
6 changes: 6 additions & 0 deletions tree/ntuple/test/rfield_class.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,14 @@ TEST(RNTuple, TClassReadRules)
auto ptrOldCoord = model->MakeField<OldCoordinates>("oldCoord");
auto ptrLowPrecisionFloat = model->MakeField<LowPrecisionFloatWithIORules>("lowPrecisionFloat");
auto ptrOldName = model->MakeField<OldName<OldName<int>>>("rename");
auto ptrOldNameVersionChange = model->MakeField<OldName<float>>("renameVersionChange");
auto ptrWithSource = model->MakeField<StructWithSourceStruct>("withSource");
ptrCoord->fX = ptrOldCoord->fOldX = 1.0;
ptrCoord->fY = ptrOldCoord->fOldY = 1.0;
ptrLowPrecisionFloat->fFoo = 1.0;
ptrLowPrecisionFloat->fLast8BitsZero = last8BitsZero;
ptrOldName->fValue.fValue = 42;
ptrOldNameVersionChange->fValue = 1.0;
// The following two members are transient and should not be stored.
ptrWithSource->fSource.fTransient = 1;
ptrWithSource->fTransient = 2;
Expand Down Expand Up @@ -322,6 +324,10 @@ TEST(RNTuple, TClassReadRules)

auto viewRename = reader->GetView<NewName<OldName<int>>>("rename");
EXPECT_EQ(42, viewRename(0).fValue.fValue);

EXPECT_NE(ROOT::RField<OldName<float>>("").GetTypeVersion(), ROOT::RField<NewName<float>>("").GetTypeVersion());
auto viewRenameVersionChange = reader->GetView<NewName<float>>("renameVersionChange");
EXPECT_FLOAT_EQ(1.0, viewRenameVersionChange(0).fValue);
}

// Adjusted from
Expand Down
Loading