diff --git a/python/templates/Object.cc.jinja2 b/python/templates/Object.cc.jinja2 index 62707c79a..2037b9639 100644 --- a/python/templates/Object.cc.jinja2 +++ b/python/templates/Object.cc.jinja2 @@ -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) {} diff --git a/python/templates/macros/implementations.jinja2 b/python/templates/macros/implementations.jinja2 index 5dbf6d92a..d3f367fdf 100644 --- a/python/templates/macros/implementations.jinja2 +++ b/python/templates/macros/implementations.jinja2 @@ -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 }}() : @@ -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 diff --git a/tests/unittests/unittest.cpp b/tests/unittests/unittest.cpp index 38f95e3a8..228fd4a52 100644 --- a/tests/unittests/unittest.cpp +++ b/tests/unittests/unittest.cpp @@ -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); @@ -1245,14 +1246,21 @@ template 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(); @@ -1299,6 +1307,12 @@ void runRelationAfterCloneCheck(const std::string& filename = "unittest_relation newHitCollection.push_back(hit); newHitCollection.push_back(anotherHit); + auto& collWithOneRelation = readFrame.get("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())