Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-20 10:33:48

0001 
0002 #include "JANA/Components/JOmniFactory.h"
0003 #include "JANA/Components/JWiredFactoryGeneratorT.h"
0004 #include "JANA/JEventProcessor.h"
0005 #include "JANA/JException.h"
0006 #include "JANA/Utils/JEventLevel.h"
0007 #include <JANA/Services/JWiringService.h>
0008 #include <catch.hpp>
0009 #include <memory>
0010 #include <toml.hpp>
0011 #include <iostream>
0012 
0013 
0014 static constexpr std::string_view some_wiring = R"(
0015     include = ["asdf.toml"]
0016 
0017     [[wiring]]
0018     action = "add"
0019     plugin_name = "BCAL"
0020     type_name = "MyFac"
0021     prefix = "myfac"
0022     input_names = ["input_coll_1", "input_coll_2"]
0023     input_levels = ["Run", "Subrun"]
0024     output_names = ["output_coll_1", "output_coll_2"]
0025 
0026         [wiring.configs]
0027         x = "22"
0028         y = "verbose"
0029 
0030     [[wiring]]
0031     action = "add"
0032     plugin_name = "BCAL"
0033     type_name = "MyFac"
0034     prefix = "myfac_modified"
0035     input_names = ["input_coll_1", "input_coll_3"]
0036     output_names = ["output_coll_1_modified", "output_coll_2_modified"]
0037 
0038         [wiring.configs]
0039         x = "100"
0040         y = "verbose"
0041 
0042 )";
0043 
0044 TEST_CASE("WiringTests") {
0045 
0046     jana::services::JWiringService sut;
0047     toml::table table = toml::parse(some_wiring);
0048     sut.ApplyWiringSet(sut.ParseWiringSet(table));
0049 
0050     const auto& wirings = sut.GetAllWirings();
0051     REQUIRE(wirings.size() == 2);
0052     auto& w0 = wirings.at("myfac");
0053     auto& w1 = wirings.at("myfac_modified");
0054 
0055     REQUIRE(w0->prefix == "myfac");
0056     REQUIRE(w1->prefix == "myfac_modified");
0057     REQUIRE(w0->plugin_name == "BCAL");
0058     REQUIRE(w0->input_names[1] == "input_coll_2");
0059     REQUIRE(w1->input_names[1] == "input_coll_3");
0060     REQUIRE(w0->input_levels.size() == 2);
0061     REQUIRE(w0->input_levels[0] == JEventLevel::Run);
0062     REQUIRE(w0->input_levels[1] == JEventLevel::Subrun);
0063     REQUIRE(w1->input_levels.size() == 0);
0064     REQUIRE(w0->configs.size() == 2);
0065     REQUIRE(w0->configs["x"] == "22");
0066     REQUIRE(w0->configs["y"] == "verbose");
0067 
0068 }
0069 
0070 static constexpr std::string_view duplicate_prefixes = R"(
0071     [[wiring]]
0072     action = "add"
0073     plugin_name = "BCAL"
0074     type_name = "MyFac"
0075     prefix = "myfac"
0076 
0077     [[wiring]]
0078     action = "add"
0079     plugin_name = "BCAL"
0080     type_name = "MyFac"
0081     prefix = "myfac"
0082 )";
0083 
0084 TEST_CASE("WiringTests_DuplicatePrefixes") {
0085 
0086     jana::services::JWiringService sut;
0087     toml::table table = toml::parse(duplicate_prefixes);
0088     try {
0089         sut.ApplyWiringSet(sut.ParseWiringSet(table));
0090         REQUIRE(1 == 0);
0091     }
0092     catch (const JException& e) {
0093         std::cout << e << std::endl;
0094     }
0095 }
0096 
0097 TEST_CASE("WiringTests_Overlay") {
0098     using Wiring = jana::services::JWiringService::Wiring;
0099     auto above = std::make_unique<Wiring>();
0100     above->prefix = "myfac";
0101     above->type_name = "ClusteringFac";
0102     above->plugin_name = "FCAL";
0103     above->input_names = {"this", "should", "make", "it"};
0104     above->configs["x"] = "6.18";
0105 
0106     auto below = std::make_unique<Wiring>();
0107     below->prefix = "myfac";
0108     below->type_name = "ClusteringFac";
0109     below->plugin_name = "FCAL";
0110     below->input_names = {"this", "should", "NOT", "make", "it"};
0111     below->input_levels = {JEventLevel::Run, JEventLevel::PhysicsEvent};
0112     below->configs["x"] = "7.6";
0113     below->configs["y"] = "42";
0114 
0115     auto sut = jana::services::JWiringService();
0116     sut.Overlay(*above, *below);
0117     REQUIRE(above->input_names[2] == "make");
0118     REQUIRE(above->input_levels[1] == JEventLevel::PhysicsEvent);
0119     REQUIRE(above->configs["x"] == "6.18");
0120     REQUIRE(above->configs["y"] == "42");
0121 }
0122 
0123 static constexpr std::string_view fake_wiring_file = R"(
0124     [[wiring]]
0125     action = "add"
0126     plugin_name = "ECAL"
0127     type_name = "ClusteringFac"
0128     prefix = "myfac"
0129 
0130         [wiring.configs]
0131         x = "22"
0132         y = "verbose"
0133 
0134     [[wiring]]
0135     action = "update"
0136     plugin_name = "ECAL"
0137     type_name = "ClusteringFac"
0138     prefix = "variantfac"
0139 
0140         [wiring.configs]
0141         x = "49"
0142         y = "silent"
0143 
0144     [[wiring]]
0145     action = "add"
0146     plugin_name = "BCAL"
0147     type_name = "ClusteringFac"
0148     prefix = "sillyfac"
0149 
0150         [wiring.configs]
0151         x = "618"
0152         y = "mediocre"
0153 )";
0154 
0155 
0156 TEST_CASE("WiringTests_FakeFacGen") {
0157     jana::services::JWiringService sut;
0158     toml::table table = toml::parse(fake_wiring_file);
0159     auto wiring_set_file = sut.ParseWiringSet(table);
0160 
0161     using Wiring = jana::services::JWiringService::Wiring;
0162     using WiringSet = jana::services::JWiringService::WiringSet;
0163     WiringSet wiring_set_facgen;
0164 
0165     // One gets overlaid with an existing wiring
0166     auto a = std::make_unique<Wiring>();
0167     a->plugin_name = "ECAL";
0168     a->type_name = "ClusteringFac";
0169     a->prefix = "variantfac";
0170     a->configs["x"] = "42";
0171     wiring_set_facgen.wirings["variantfac"] = std::move(a);
0172 
0173     // The other is brand new
0174     auto b = std::make_unique<Wiring>();
0175     b->plugin_name = "ECAL";
0176     b->type_name = "ClusteringFac";
0177     b->prefix = "exuberantfac";
0178     b->configs["x"] = "27";
0179     wiring_set_facgen.wirings["exuberantfac"] = std::move(b);
0180 
0181     sut.OverlayWiringSet(wiring_set_file, wiring_set_facgen);
0182     sut.ApplyWiringSet(std::move(wiring_set_file));
0183 
0184     auto myfac = sut.GetWiring("myfac");
0185     auto variantfac = sut.GetWiring("variantfac");
0186     auto exuberantfac = sut.GetWiring("exuberantfac");
0187 
0188     REQUIRE(myfac != nullptr);
0189     REQUIRE(variantfac != nullptr);
0190     REQUIRE(exuberantfac != nullptr);
0191 
0192     REQUIRE(myfac->configs["x"] == "22"); // from file only
0193     REQUIRE(variantfac->configs["x"] == "49"); // file overrides facgen
0194     REQUIRE(exuberantfac->configs["x"] == "27"); // from facgen only
0195 }
0196 
0197 struct Cluster { double x,y,E; };
0198 
0199 struct WiredOmniFac : jana::components::JOmniFactory<WiredOmniFac> {
0200     Input<Cluster> m_protoclusters_in {this};
0201     Output<Cluster> m_clusters_out {this};
0202 
0203     Parameter<int> m_x {this, "x", 1, "x"};
0204     Parameter<std::string> m_y {this, "y", "silent", "y" };
0205 
0206     void Configure() {
0207     }
0208 
0209     void ChangeRun(int32_t /*run_nr*/) {
0210     }
0211 
0212     void Execute(int32_t /*run_nr*/, uint64_t /*evt_nr*/) {
0213 
0214         for (auto protocluster : *m_protoclusters_in) {
0215             m_clusters_out().push_back(new Cluster {protocluster->x, protocluster->y, protocluster->E + 1});
0216         }
0217     }
0218 };
0219 
0220 static constexpr std::string_view realfacgen_wiring = R"(
0221     [[wiring]]
0222     action = "add"
0223     type_name = "WiredOmniFac"
0224     prefix = "myfac"
0225     input_names = ["usual_input"]
0226     output_names = ["usual_output"]
0227 
0228         [wiring.configs]
0229         x = "22"
0230         y = "verbose"
0231 
0232     [[wiring]]
0233     action = "add"
0234     type_name = "WiredOmniFac"
0235     prefix = "myfac_modified"
0236     input_names = ["different_input"]
0237     output_names = ["different_output"]
0238 
0239         [wiring.configs]
0240         x = "100"
0241         y = "silent"
0242 
0243 )";
0244 
0245 TEST_CASE("WiringTests_RealFacGen") {
0246 
0247     JApplication app;
0248 
0249     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0250     toml::table table = toml::parse(realfacgen_wiring);
0251     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0252 
0253     auto gen = new jana::components::JWiredFactoryGeneratorT<WiredOmniFac>;
0254     app.Add(gen);
0255     app.Initialize();
0256 
0257     auto& summary = app.GetComponentSummary();
0258     jout << summary;
0259     auto vf = summary.FindComponents("myfac");
0260     REQUIRE(vf.size() == 1);
0261     REQUIRE(vf.at(0)->GetOutputs().at(0)->GetName() == "usual_output");
0262 
0263     auto ef = summary.FindComponents("myfac_modified");
0264     REQUIRE(ef.size() == 1);
0265     REQUIRE(ef.at(0)->GetOutputs().at(0)->GetName() == "different_output");
0266 
0267     // Check that parameter values propagated from wiring file to parameter manager
0268     REQUIRE(app.GetParameterValue<int>("myfac:x") == 22);
0269     REQUIRE(app.GetParameterValue<std::string>("myfac:y") == "verbose");
0270     REQUIRE(app.GetParameterValue<int>("myfac_modified:x") == 100);
0271     REQUIRE(app.GetParameterValue<std::string>("myfac_modified:y") == "silent");
0272 
0273     //app.GetJParameterManager()->PrintParameters(2, 0);
0274     //auto event = std::make_shared<JEvent>(&app);
0275     //auto facs = event->GetFactorySet()->GetAllMultifactories();
0276 
0277 }
0278 
0279 struct WiredOmniFacConfig {
0280     int shared = 0;
0281     int isolated = 2;
0282 };
0283 
0284 struct WiredOmniFacWithShared : jana::components::JOmniFactory<WiredOmniFacWithShared, WiredOmniFacConfig> {
0285     Input<Cluster> m_protoclusters_in {this};
0286     Output<Cluster> m_clusters_out {this};
0287 
0288     ParameterRef<int> m_shared {this, "shared", config().shared, "shared", true};
0289     ParameterRef<int> m_isolated {this, "isolated", config().isolated, "isolated" };
0290 
0291     void Configure() {
0292     }
0293 
0294     void ChangeRun(int32_t /*run_nr*/) {
0295     }
0296 
0297     void Execute(int32_t /*run_nr*/, uint64_t /*evt_nr*/) {
0298 
0299         for (auto protocluster : *m_protoclusters_in) {
0300             m_clusters_out().push_back(new Cluster {protocluster->x, protocluster->y, protocluster->E + 1});
0301         }
0302     }
0303 };
0304 
0305 static constexpr std::string_view sharedparam_wiring = R"(
0306     [configs]
0307     shared = "28"
0308 
0309     [[wiring]]
0310     action = "add"
0311     type_name = "WiredOmniFacWithShared"
0312     prefix = "myfac"
0313     input_names = ["usual_input"]
0314     output_names = ["usual_output"]
0315 
0316         [wiring.configs]
0317         isolated = "22"
0318 
0319     [[wiring]]
0320     action = "add"
0321     type_name = "WiredOmniFacWithShared"
0322     prefix = "myfac_modified"
0323     input_names = ["different_input"]
0324     output_names = ["different_output"]
0325 
0326         [wiring.configs]
0327         isolated = "100"
0328 )";
0329 
0330 TEST_CASE("WiringTests_SharedParam") {
0331 
0332     JApplication app;
0333 
0334     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0335     toml::table table = toml::parse(sharedparam_wiring);
0336     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0337 
0338     auto gen = new jana::components::JWiredFactoryGeneratorT<WiredOmniFacWithShared>;
0339     app.Add(gen);
0340     app.Initialize();
0341 
0342     auto& summary = app.GetComponentSummary();
0343     //jout << summary;
0344     auto vf = summary.FindComponents("myfac");
0345     REQUIRE(vf.size() == 1);
0346     REQUIRE(vf.at(0)->GetOutputs().at(0)->GetName() == "usual_output");
0347 
0348     auto ef = summary.FindComponents("myfac_modified");
0349     REQUIRE(ef.size() == 1);
0350     REQUIRE(ef.at(0)->GetOutputs().at(0)->GetName() == "different_output");
0351 
0352     // Check that parameter values propagated from wiring file to parameter manager
0353     REQUIRE(app.GetParameterValue<int>("shared") == 28);
0354     REQUIRE(app.GetParameterValue<int>("myfac:isolated") == 22);
0355     REQUIRE(app.GetParameterValue<int>("myfac_modified:isolated") == 100);
0356 
0357     //app.GetJParameterManager()->PrintParameters(2, 0);
0358     //auto event = std::make_shared<JEvent>(&app);
0359     //auto facs = event->GetFactorySet()->GetAllMultifactories();
0360 
0361 }
0362 
0363 
0364 class WiredEvtProc : public JEventProcessor {
0365 
0366     Parameter<int> m_x {this, "x", 22};
0367     Input<Cluster> m_cluster_in {this};
0368     //Input<Cluster> m_different_cluster_in {this};
0369     //VariadicInput<Cluster> m_even_more_in {this};
0370 
0371 public:
0372 
0373     WiredEvtProc() {
0374         SetTypeName("WiredEvtProc");
0375         SetPrefix("myproc");
0376         SetCallbackStyle(CallbackStyle::ExpertMode);
0377     }
0378 
0379     void Init() override {
0380         REQUIRE(*m_x == 99); // Set by wiring file
0381     }
0382 
0383     void ProcessSequential(const JEvent&) override {
0384 
0385         // Set by wiring file
0386         REQUIRE(GetPrefix() == "myproc");
0387         REQUIRE(m_cluster_in.GetDatabundleName() == "myclusters");
0388 
0389         // Data is reachable
0390         REQUIRE(m_cluster_in->size() == 1); 
0391     }
0392 };
0393 
0394 static constexpr std::string_view evtproc_wiring = R"(
0395     [[wiring]]
0396     action = "update"
0397     type_name = "WiredEvtProc"
0398     prefix = "myproc"
0399     input_names = ["myclusters"]
0400 
0401         [wiring.configs]
0402         x = "99"
0403 )";
0404 
0405 TEST_CASE("WiringTests_Proc") {
0406 
0407     JApplication app;
0408 
0409     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0410     toml::table table = toml::parse(evtproc_wiring);
0411     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0412 
0413     auto proc = new WiredEvtProc;
0414     app.Add(proc);
0415 
0416     app.Initialize();
0417     auto event = std::make_shared<JEvent>(&app);
0418     std::vector<Cluster*> test_data;
0419     test_data.push_back(new Cluster{0, 0, 22.2});
0420     event->Insert<Cluster>(test_data, "myclusters");
0421 
0422     proc->DoInit();
0423     proc->DoMap(*event);
0424     proc->DoTap(*event);
0425 }
0426 
0427 
0428 struct WiredFac : public JFactory {
0429     Input<Cluster> m_protoclusters_in {this};
0430     Output<Cluster> m_clusters_out {this};
0431 
0432     Parameter<int> m_x {this, "x", 1, "x"};
0433 
0434     WiredFac() {
0435         SetPrefix("wiredfac");
0436         m_protoclusters_in.SetDatabundleName("default_protos");
0437         m_clusters_out.SetUniqueName("default_clusters");
0438     }
0439     void Process(const JEvent&) {
0440         for (auto protocluster : *m_protoclusters_in) {
0441             m_clusters_out().push_back(new Cluster {protocluster->x, protocluster->y, protocluster->E + *m_x});
0442         }
0443     }
0444 };
0445 
0446 static constexpr std::string_view facgen_wiring = R"(
0447     [[wiring]]
0448     action = "update"
0449     type_name = "WiredFac"
0450     prefix = "wiredfac"
0451     input_names = ["usual_input"]
0452     output_names = ["usual_output"]
0453 
0454         [wiring.configs]
0455         x = "22"
0456 )";
0457 
0458 TEST_CASE("WiringTests_FacGen") {
0459 
0460     JApplication app;
0461 
0462     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0463     toml::table table = toml::parse(facgen_wiring);
0464     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0465 
0466     auto gen = new JFactoryGeneratorT<WiredFac>;
0467     app.Add(gen);
0468     app.Initialize();
0469 
0470     auto& summary = app.GetComponentSummary();
0471     jout << summary;
0472     auto vf = summary.FindComponents("wiredfac");
0473     REQUIRE(vf.size() == 1);
0474     REQUIRE(vf.at(0)->GetOutputs().at(0)->GetName() == "usual_output");
0475 
0476     REQUIRE(app.GetParameterValue<int>("wiredfac:x") == 22);
0477 
0478     auto event = std::make_shared<JEvent>(&app);
0479     std::vector<Cluster*> test_data;
0480     test_data.push_back(new Cluster{0, 0, 22.2});
0481     event->Insert<Cluster>(test_data, "usual_input");
0482 
0483     auto results = event->Get<Cluster>("usual_output");
0484     REQUIRE(results.size() == 1);
0485     REQUIRE(results.at(0)->E == 44.2);
0486 
0487 }
0488 
0489 
0490 static constexpr std::string_view facgen_shortnames_true = R"(
0491     use_short_names = true
0492 
0493     [[wiring]]
0494     action = "update"
0495     type_name = "WiredFac"
0496     prefix = "wiredfac"
0497     input_names = ["usual_input"]
0498     output_names = ["usual_output"]
0499 
0500         [wiring.configs]
0501         x = "22"
0502 )";
0503 
0504 TEST_CASE("WiringTests_FacGenShortnames") {
0505 
0506     JApplication app;
0507 
0508     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0509     toml::table table = toml::parse(facgen_shortnames_true);
0510     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0511 
0512     REQUIRE(wiring_svc->AreShortNamesUsed() == true);
0513 
0514     auto gen = new JFactoryGeneratorT<WiredFac>;
0515     app.Add(gen);
0516     app.Initialize();
0517 
0518     auto event = std::make_shared<JEvent>(&app);
0519     std::vector<Cluster*> test_data;
0520     test_data.push_back(new Cluster{0, 0, 22.2});
0521     event->Insert<Cluster>(test_data, "usual_input");
0522 
0523     auto results = event->Get<Cluster>("usual_output");
0524     REQUIRE(results.size() == 1);
0525     REQUIRE(results.at(0)->E == 44.2);
0526 
0527 }
0528 
0529 
0530 static constexpr std::string_view facgen_partial_input_names_only = R"(
0531     [[wiring]]
0532     action = "update"
0533     type_name = "WiredFac"
0534     prefix = "wiredfac"
0535     input_names = ["overridden_input"]
0536 )";
0537 
0538 TEST_CASE("WiringTests_Partial_InputNamesOnly") {
0539 
0540     JApplication app;
0541 
0542     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0543     toml::table table = toml::parse(facgen_partial_input_names_only);
0544     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0545 
0546     auto gen = new JFactoryGeneratorT<WiredFac>;
0547     app.Add(gen);
0548     app.Initialize();
0549 
0550     auto event = std::make_shared<JEvent>(&app);
0551     std::vector<Cluster*> test_data;
0552     test_data.push_back(new Cluster{0, 0, 22.2});
0553     event->Insert<Cluster>(test_data, "overridden_input");
0554 
0555     auto results = event->Get<Cluster>("default_clusters");
0556     REQUIRE(results.size() == 1);
0557     REQUIRE(results.at(0)->E == 23.2);
0558 
0559 }
0560 
0561 static constexpr std::string_view facgen_partial_output_names_only = R"(
0562     [[wiring]]
0563     action = "update"
0564     type_name = "WiredFac"
0565     prefix = "wiredfac"
0566     output_names = ["overridden_output"]
0567 )";
0568 
0569 TEST_CASE("WiringTests_Partial_OutputNamesOnly") {
0570 
0571     JApplication app;
0572 
0573     auto wiring_svc = app.GetService<jana::services::JWiringService>();
0574     toml::table table = toml::parse(facgen_partial_output_names_only);
0575     wiring_svc->ApplyWiringSet(wiring_svc->ParseWiringSet(table));
0576 
0577     auto gen = new JFactoryGeneratorT<WiredFac>;
0578     app.Add(gen);
0579     app.Initialize();
0580 
0581     auto event = std::make_shared<JEvent>(&app);
0582     std::vector<Cluster*> test_data;
0583     test_data.push_back(new Cluster{0, 0, 22.2});
0584     event->Insert<Cluster>(test_data, "default_protos");
0585 
0586     auto results = event->Get<Cluster>("overridden_output");
0587     REQUIRE(results.size() == 1);
0588     REQUIRE(results.at(0)->E == 23.2);
0589 
0590 }