Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix one to one relations for cloned objects #632

Merged
merged 2 commits into from
Jun 23, 2024
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
2 changes: 1 addition & 1 deletion python/templates/Object.cc.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

{{ utils.namespace_open(class.namespace) }}

{{ macros.constructors_destructors(class.bare_type, Members, OneToManyRelations + VectorMembers) }}
{{ macros.constructors_destructors(class.bare_type, Members, one_to_one_relations=OneToOneRelations, multi_relations=OneToManyRelations + VectorMembers) }}

{{ class.bare_type }}::{{ class.bare_type }}(const Mutable{{ class.bare_type }}& other): {{ class.bare_type }}(other.m_obj) {}

Expand Down
7 changes: 6 additions & 1 deletion python/templates/macros/implementations.jinja2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% macro constructors_destructors(type, members, multi_relations=[], prefix='') %}
{% macro constructors_destructors(type, members, one_to_one_relations=[], multi_relations=[], prefix='') %}
{% set full_type = prefix + type %}

{{ full_type }}::{{ full_type }}() :
Expand Down Expand Up @@ -36,6 +36,11 @@ Mutable{{ type }} {{ full_type }}::clone(bool cloneRelations) const {
tmp->m_{{ relation.name }} = new std::vector<{{ relation.full_type }}>();
{% endfor %}
if (cloneRelations) {
{% for relation in one_to_one_relations %}
if (m_obj->m_{{ relation.name }}) {
tmp->m_{{ relation.name }} = new {{ relation.full_type }}(*m_obj->m_{{ relation.name }});
}
{% endfor %}
{% for relation in multi_relations %}
// If the current object has been read from a file, then the object may only have a slice of the relation vector
// so this slice has to be copied in case we want to modify it
Expand Down
20 changes: 17 additions & 3 deletions tests/unittests/unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ auto createCollections(const size_t nElements = 3u) {
auto cluster = clusterColl.create();
// create a few relations as well
cluster.addHits(hit);
cluster.energy(150.f * i);

auto vecMem = vecMemColl.create();
vecMem.addcount(i);
Expand Down Expand Up @@ -1245,14 +1246,21 @@ template <typename ReaderT, typename WriterT>
void runRelationAfterCloneCheck(const std::string& filename = "unittest_relations_after_cloning.root") {
auto [hitColl, clusterColl, vecMemColl, userDataColl] = createCollections();
auto frame = podio::Frame();
frame.put(std::move(hitColl), "hits");
frame.put(std::move(clusterColl), "clusters");
frame.put(std::move(vecMemColl), "vectors");
// Empty relations
auto emptyColl = ExampleClusterCollection();
emptyColl.create();
emptyColl.create();
frame.put(std::move(emptyColl), "emptyClusters");
// OneToOne relations
auto oneToOneColl = ExampleWithOneRelationCollection();
auto obj = oneToOneColl.create();
obj.cluster(clusterColl[1]);

frame.put(std::move(oneToOneColl), "oneToOne");
frame.put(std::move(hitColl), "hits");
frame.put(std::move(clusterColl), "clusters");
frame.put(std::move(vecMemColl), "vectors");

auto writer = WriterT(filename);
writer.writeFrame(frame, podio::Category::Event);
writer.finish();
Expand Down Expand Up @@ -1299,6 +1307,12 @@ void runRelationAfterCloneCheck(const std::string& filename = "unittest_relation
newHitCollection.push_back(hit);
newHitCollection.push_back(anotherHit);

auto& collWithOneRelation = readFrame.get<ExampleWithOneRelationCollection>("oneToOne");
REQUIRE(collWithOneRelation.size() == 1);
auto nObj = collWithOneRelation[0].clone();
REQUIRE(collWithOneRelation[0].cluster().energy() == 150.);
REQUIRE(nObj.cluster().energy() == 150.);

// Test cloned objects after writing and reading
auto newName = std::filesystem::path(filename)
.replace_extension("_cloned" + std::filesystem::path(filename).extension().string())
Expand Down
Loading