File indexing completed on 2025-09-15 09:18:14
0001
0002 #include <catch.hpp>
0003
0004 #include <memory>
0005 #include <type_traits>
0006 #include <JANA/JEvent.h>
0007 #include <JANA/JFactoryGenerator.h>
0008 #include <JANA/JMultifactory.h>
0009 #include <JANA/Components/JOmniFactory.h>
0010 #include <JANA/Components/JOmniFactoryGeneratorT.h>
0011 #include <PodioDatamodel/ExampleHitCollection.h>
0012 #include <PodioDatamodel/ExampleClusterCollection.h>
0013 #include <podio/podioVersion.h>
0014
0015 #if podio_VERSION >= PODIO_VERSION(1,2,0)
0016 #include <podio/LinkCollection.h>
0017 #endif
0018
0019 namespace podiotests {
0020
0021
0022 TEST_CASE("PodioTestsInsertAndRetrieve") {
0023 ExampleClusterCollection clusters_to_insert;
0024 clusters_to_insert.push_back(MutableExampleCluster(16.0));
0025 clusters_to_insert.push_back(MutableExampleCluster(128.0));
0026
0027 auto event = std::make_shared<JEvent>();
0028 event->InsertCollection<ExampleCluster>(std::move(clusters_to_insert), "clusters");
0029
0030 SECTION("Retrieve using JEvent::GetCollection()") {
0031 auto* collection_retrieved = event->GetCollection<ExampleCluster>("clusters");
0032 REQUIRE(collection_retrieved->size() == 2);
0033 REQUIRE((*collection_retrieved)[0].energy() == 16.0);
0034 }
0035
0036 SECTION("Retrieve using JEvent::GetCollectionBase()") {
0037 auto* collection_retrieved_untyped = event->GetCollectionBase("clusters");
0038 REQUIRE(collection_retrieved_untyped->size() == 2);
0039 auto* collection_retrieved = dynamic_cast<const ExampleClusterCollection*>(collection_retrieved_untyped);
0040 REQUIRE(collection_retrieved != nullptr);
0041 REQUIRE((*collection_retrieved)[0].energy() == 16.0);
0042 }
0043
0044 SECTION("Retrieve directly from podio::Frame") {
0045 auto frame = event->GetSingle<podio::Frame>();
0046 auto* collection_retrieved = dynamic_cast<const ExampleClusterCollection*>(frame->get("clusters"));
0047 REQUIRE(collection_retrieved->size() == 2);
0048 REQUIRE((*collection_retrieved)[0].energy() == 16.0);
0049 }
0050
0051 }
0052
0053 template <typename, typename=void>
0054 struct is_podio : std::false_type {};
0055
0056 template <typename T>
0057 struct is_podio<T, std::void_t<typename T::collection_type>> : std::true_type {};
0058
0059 template <typename T>
0060 static constexpr bool is_podio_v = is_podio<T>::value;
0061
0062 struct FakeMultifactory {
0063
0064 template <typename T, typename std::enable_if_t<is_podio_v<T>>* = nullptr>
0065 bool DeclareOutput(std::string ) {
0066 return true;
0067 }
0068
0069 template <typename T, typename std::enable_if_t<!is_podio_v<T>>* = nullptr>
0070 bool DeclareOutput(std::string ) {
0071 return false;
0072 }
0073 };
0074
0075 TEST_CASE("SFINAE for JMultifactory::SetData") {
0076 FakeMultifactory sut;
0077 REQUIRE(sut.DeclareOutput<int>("asdf") == false);
0078 REQUIRE(sut.DeclareOutput<ExampleCluster>("asdf") == true);
0079 }
0080
0081
0082 TEST_CASE("PODIO 'subset' collections handled correctly (not involving factories yet") {
0083 auto event = std::make_shared<JEvent>();
0084
0085 auto a1 = MutableExampleCluster(22.2);
0086 auto a2 = MutableExampleCluster(4.0);
0087 ExampleClusterCollection clusters_to_insert;
0088 clusters_to_insert.push_back(a1);
0089 clusters_to_insert.push_back(a2);
0090 event->InsertCollection<ExampleCluster>(std::move(clusters_to_insert), "original_clusters");
0091
0092 auto* retrieved_clusters = event->GetCollection<ExampleCluster>("original_clusters");
0093 auto b = (*retrieved_clusters)[1];
0094 REQUIRE(b.energy() == 4.0);
0095
0096 ExampleClusterCollection subset_clusters;
0097 subset_clusters.setSubsetCollection(true);
0098 subset_clusters.push_back(b);
0099 event->InsertCollection<ExampleCluster>(std::move(subset_clusters), "subset_clusters");
0100
0101
0102
0103 const ExampleClusterCollection* retrieved_subset_clusters = event->GetCollection<ExampleCluster>("subset_clusters");
0104 const ExampleCluster& c = (*retrieved_subset_clusters)[0];
0105 REQUIRE(c.energy() == 4.0);
0106 REQUIRE(c.id() == b.id());
0107
0108 }
0109 }
0110
0111
0112 #if podio_VERSION >= PODIO_VERSION(1,2,0)
0113
0114 using ClusterClusterLink = podio::LinkCollection<ExampleCluster, ExampleCluster>::value_type;
0115 struct MyOmniFac: jana::components::JOmniFactory<MyOmniFac> {
0116
0117 PodioInput<ExampleCluster> m_clusters_in {this};
0118 PodioInput<ClusterClusterLink> m_links_in {this};
0119 PodioOutput<ClusterClusterLink> m_links_out {this};
0120
0121 void Configure() {};
0122
0123 void ChangeRun(int32_t) {}
0124
0125 void Execute(int32_t, int32_t) {
0126 auto link = m_links_out()->create();
0127 link.setFrom(m_clusters_in()->at(1));
0128 link.setTo(m_clusters_in()->at(0));
0129 }
0130 };
0131
0132 TEST_CASE("PodioLink_Test") {
0133 JApplication app;
0134 app.Add(new JOmniFactoryGeneratorT<MyOmniFac>("blah", {"clusters", "simple"}, {"complex"}));
0135 auto event = std::make_shared<JEvent>(&app);
0136 ExampleClusterCollection clusters;
0137 auto c1 = clusters.create();
0138 c1.energy(22);
0139 auto c2 = clusters.create();
0140 c2.energy(33);
0141
0142 event->InsertCollection<ExampleCluster>(std::move(clusters), "clusters");
0143 event->InsertCollection<ClusterClusterLink>(ClusterClusterLink::collection_type(), "simple");
0144
0145 auto coll = event->GetCollection<ClusterClusterLink>("complex");
0146 REQUIRE(coll->size() == 1);
0147 REQUIRE(coll->at(0).getFrom().energy() == 33);
0148 REQUIRE(coll->at(0).getTo().energy() == 22);
0149 }
0150 #endif
0151
0152
0153 namespace jana2::tests::podio_cleardata {
0154
0155 struct MyFac: jana::components::JOmniFactory<MyFac> {
0156
0157 PodioInput<ExampleHit> m_hits_in {this};
0158 PodioOutput<ExampleCluster> m_clusters_out {this};
0159
0160 MyFac() { SetTypeName("MyFac");}
0161 void Configure() {};
0162 void ChangeRun(int32_t) {}
0163 void Execute(int32_t, int32_t) {
0164 auto cluster = m_clusters_out()->create();
0165 for (auto hit : *m_hits_in()) {
0166 cluster.addHits(hit);
0167 }
0168 }
0169 };
0170
0171 TEST_CASE("PodioClearData_Test") {
0172 JApplication app;
0173 app.Add(new JOmniFactoryGeneratorT<MyFac>("blah", {"hits"}, {"clusters"}));
0174 auto event = std::make_shared<JEvent>(&app);
0175
0176 SECTION("InsertCollection") {
0177 ExampleHitCollection hits;
0178 auto h1 = hits.create();
0179 h1.cellID(22);
0180
0181 event->InsertCollection<ExampleHit>(std::move(hits), "hits");
0182 auto clusters = event->GetCollection<ExampleCluster>("clusters");
0183 REQUIRE(clusters->size() == 1);
0184 REQUIRE(clusters->at(0).Hits_size() == 1);
0185 REQUIRE(clusters->at(0).Hits().at(0).cellID() == 22);
0186
0187 event->Clear(true);
0188
0189 ExampleHitCollection hits2;
0190 auto h2 = hits2.create();
0191 h2.cellID(3);
0192 auto h3 = hits2.create();
0193 h3.cellID(99);
0194 event->InsertCollection<ExampleHit>(std::move(hits2), "hits");
0195 auto clusters2 = event->GetCollection<ExampleCluster>("clusters");
0196 REQUIRE(clusters2->size() == 1);
0197 REQUIRE(clusters2->at(0).Hits_size() == 2);
0198 REQUIRE(clusters2->at(0).Hits().at(0).cellID() == 3);
0199 REQUIRE(clusters2->at(0).Hits().at(1).cellID() == 99);
0200 }
0201
0202 SECTION("InsertCollectionAlreadyInFrame") {
0203 ExampleHitCollection hits;
0204 auto h1 = hits.create();
0205 h1.cellID(22);
0206 podio::Frame* frame1 = new podio::Frame;
0207 frame1->put(std::move(hits), "hits");
0208 auto const_hits = frame1->get("hits");
0209 event->Insert(frame1, "");
0210 event->InsertCollectionAlreadyInFrame<ExampleHit>(const_hits, "hits");
0211
0212 auto clusters = event->GetCollection<ExampleCluster>("clusters");
0213
0214 REQUIRE(clusters->size() == 1);
0215 REQUIRE(clusters->at(0).Hits_size() == 1);
0216 REQUIRE(clusters->at(0).Hits().at(0).cellID() == 22);
0217
0218 event->Clear(true);
0219
0220 ExampleHitCollection hits2;
0221 auto h2 = hits2.create();
0222 h2.cellID(3);
0223 auto h3 = hits2.create();
0224 h3.cellID(99);
0225
0226 podio::Frame* frame2 = new podio::Frame;
0227 frame2->put(std::move(hits2), "hits");
0228 auto const_hits2 = frame2->get("hits");
0229 event->Insert(frame2, "");
0230 event->InsertCollectionAlreadyInFrame<ExampleHit>(const_hits2, "hits");
0231
0232 auto clusters2 = event->GetCollection<ExampleCluster>("clusters");
0233
0234 REQUIRE(clusters2->size() == 1);
0235 REQUIRE(clusters2->at(0).Hits_size() == 2);
0236 REQUIRE(clusters2->at(0).Hits().at(0).cellID() == 3);
0237 REQUIRE(clusters2->at(0).Hits().at(1).cellID() == 99);
0238 }
0239
0240
0241
0242 }
0243 }
0244
0245 namespace jana2::tests::podio_multifactory {
0246
0247 struct MyMultiFac: JMultifactory {
0248
0249
0250 MyMultiFac() {
0251 SetTypeName("MyMultiFac");
0252 DeclarePodioOutput<ExampleCluster>("clusters");
0253 DeclarePodioOutput<ExampleCluster>("other_clusters");
0254 }
0255 void Process(const std::shared_ptr<const JEvent>& event) override {
0256 auto hits = event->GetCollection<ExampleHit>("hits");
0257 ExampleClusterCollection clusters;
0258 auto cluster = clusters->create();
0259 for (auto hit : *hits) {
0260 cluster.addHits(hit);
0261 }
0262 SetCollection<ExampleCluster>("clusters", std::move(clusters));
0263
0264 ExampleClusterCollection clusters2;
0265 auto cluster2 = clusters2->create();
0266 for (auto hit : *hits) {
0267 cluster2.addHits(hit);
0268 }
0269 SetCollection<ExampleCluster>("other_clusters", std::move(clusters2));
0270 }
0271 };
0272
0273 TEST_CASE("PodioMultifactoryClearData_Test") {
0274 JApplication app;
0275 app.Add(new JFactoryGeneratorT<MyMultiFac>());
0276 auto event = std::make_shared<JEvent>(&app);
0277
0278 SECTION("InsertCollection") {
0279 ExampleHitCollection hits;
0280 auto h1 = hits.create();
0281 h1.cellID(22);
0282
0283 event->InsertCollection<ExampleHit>(std::move(hits), "hits");
0284 auto clusters = event->GetCollection<ExampleCluster>("clusters");
0285 REQUIRE(clusters->size() == 1);
0286 REQUIRE(clusters->at(0).Hits_size() == 1);
0287 REQUIRE(clusters->at(0).Hits().at(0).cellID() == 22);
0288
0289
0290
0291
0292 auto frame = event->GetSingle<podio::Frame>();
0293 const auto& other_clusters = frame->get<ExampleClusterCollection>("other_clusters");
0294 REQUIRE(other_clusters.size() == 1);
0295
0296
0297 event->Clear(true);
0298
0299 ExampleHitCollection hits2;
0300 auto h2 = hits2.create();
0301 h2.cellID(3);
0302 auto h3 = hits2.create();
0303 h3.cellID(99);
0304 event->InsertCollection<ExampleHit>(std::move(hits2), "hits");
0305 auto clusters2 = event->GetCollection<ExampleCluster>("clusters");
0306 REQUIRE(clusters2->size() == 1);
0307 REQUIRE(clusters2->at(0).Hits_size() == 2);
0308 REQUIRE(clusters2->at(0).Hits().at(0).cellID() == 3);
0309 REQUIRE(clusters2->at(0).Hits().at(1).cellID() == 99);
0310 }
0311
0312 SECTION("InsertCollectionAlreadyInFrame") {
0313 ExampleHitCollection hits;
0314 auto h1 = hits.create();
0315 h1.cellID(22);
0316 podio::Frame* frame1 = new podio::Frame;
0317 frame1->put(std::move(hits), "hits");
0318 auto const_hits = frame1->get("hits");
0319 event->InsertCollectionAlreadyInFrame<ExampleHit>(const_hits, "hits");
0320 event->Insert(frame1, "");
0321
0322 auto clusters = event->GetCollection<ExampleCluster>("clusters");
0323 auto clusters3 = event->GetCollection<ExampleCluster>("clusters");
0324
0325 REQUIRE(clusters3->size() == 1);
0326
0327 REQUIRE(clusters->size() == 1);
0328 REQUIRE(clusters->at(0).Hits_size() == 1);
0329 REQUIRE(clusters->at(0).Hits().at(0).cellID() == 22);
0330
0331 event->Clear(true);
0332
0333 ExampleHitCollection hits2;
0334 auto h2 = hits2.create();
0335 h2.cellID(3);
0336 auto h3 = hits2.create();
0337 h3.cellID(99);
0338
0339 podio::Frame* frame2 = new podio::Frame;
0340 frame2->put(std::move(hits2), "hits");
0341 auto const_hits2 = frame2->get("hits");
0342 event->Insert(frame2, "");
0343 event->InsertCollectionAlreadyInFrame<ExampleHit>(const_hits2, "hits");
0344
0345 auto clusters2 = event->GetCollection<ExampleCluster>("clusters");
0346
0347 REQUIRE(clusters2->size() == 1);
0348 REQUIRE(clusters2->at(0).Hits_size() == 2);
0349 REQUIRE(clusters2->at(0).Hits().at(0).cellID() == 3);
0350 REQUIRE(clusters2->at(0).Hits().at(1).cellID() == 99);
0351 }
0352
0353 }
0354 }
0355
0356