forked from Framework-R-D/phlex
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathform_module.cpp
More file actions
141 lines (109 loc) · 5.03 KB
/
Copy pathform_module.cpp
File metadata and controls
141 lines (109 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "phlex/model/product_store.hpp"
#include "phlex/model/products.hpp"
#include "phlex/module.hpp"
// FORM headers - these need to be available via CMake configuration
// need to set up the build system to find these headers
#include "form/config.hpp"
#include "form/form.hpp"
#include "form/technology.hpp"
#include <iostream>
namespace {
class FormOutputModule {
public:
FormOutputModule(std::string output_file,
int technology,
std::vector<std::string> const& products_to_save) :
m_output_file(std::move(output_file)), m_technology(technology)
{
std::cout << "FormOutputModule initialized\n";
std::cout << " Output file: " << m_output_file << "\n";
std::cout << " Technology: " << m_technology << "\n";
// Build FORM configuration
form::experimental::config::output_item_config output_cfg;
form::experimental::config::tech_setting_config tech_cfg;
// FIXME: Temporary solution to accommodate Phlex limitation.
// Eventually, Phlex will communicate to FORM which products will be written
// before executing any algorithms
// Temp. Sol for Phlex Prototype 0.1
// Register products from config
for (auto const& product : products_to_save) {
output_cfg.addItem(product, m_output_file, m_technology);
}
// Initialize FORM interface
m_form_interface =
std::make_unique<form::experimental::form_interface>(output_cfg, tech_cfg);
}
// This method is called by Phlex - signature must be: void(product_store const&)
void save_data_products(phlex::experimental::product_store const& store)
{
// Check if store is empty - smart way, check store not products vector
if (store.empty()) {
return;
}
// STEP 1: Extract metadata from Phlex's product_store
// Extract creator (algorithm name)
std::string creator = store.source();
// Extract segment ID (partition) - extract once for entire store
std::string segment_id = store.id()->to_string();
std::cout << "\n=== FormOutputModule::save_data_products ===\n";
std::cout << "Creator: " << creator << "\n";
std::cout << "Segment ID: " << segment_id << "\n";
std::cout << "Number of products: " << store.size() << "\n";
// STEP 2: Convert each Phlex product to FORM format
// Collect all products for writing
std::vector<form::experimental::product_with_name> products;
// Reserve space for efficiency - avoid reallocations
products.reserve(store.size());
// Iterate through all products in the store
for (auto const& [product_name, product_ptr] : store) {
// product_name: "tracks" (from the map key)
// product_ptr: pointer to the actual product data
std::cout << " Product: " << product_name << "\n";
// Create FORM product with metadata
products.emplace_back(product_name, // label, from map key
product_ptr->address(), // data, from phlex product_base
&product_ptr->type() // type, from phlex product_base
);
}
// STEP 3: Send everything to FORM for persistence
// Write all products to FORM
// Pass segment_id once for entire collection (not duplicated in each product)
// No need to check if products is empty - already checked store.empty() above
m_form_interface->write(creator, segment_id, products);
std::cout << "Wrote " << products.size() << " products to FORM\n";
}
private:
std::string m_output_file;
int m_technology;
std::unique_ptr<form::experimental::form_interface> m_form_interface;
};
}
PHLEX_REGISTER_ALGORITHMS(m, config)
{
std::cout << "Registering FORM output module...\n";
// Extract configuration from Phlex config
std::string output_file = config.get<std::string>("output_file", "output.root");
std::string tech_string = config.get<std::string>("technology", "ROOT_TTREE");
std::cout << "Configuration:\n";
std::cout << " output_file: " << output_file << "\n";
std::cout << " technology: " << tech_string << "\n";
// Map Phlex config string to FORM technology constant
int technology = form::technology::ROOT_TTREE; // default
if (tech_string == "ROOT_TTREE") {
technology = form::technology::ROOT_TTREE;
} else if (tech_string == "ROOT_RNTUPLE") {
technology = form::technology::ROOT_RNTUPLE;
} else if (tech_string == "HDF5") {
technology = form::technology::HDF5;
} else {
throw std::runtime_error("Unknown technology: " + tech_string);
}
auto products_to_save = config.get<std::vector<std::string>>("products");
// Phlex needs an OBJECT
// Create the FORM output module
auto form_output = m.make<FormOutputModule>(output_file, technology, products_to_save);
// Phlex needs a MEMBER FUNCTION to call
// Register the callback that Phlex will invoke
form_output.output("save_data_products", &FormOutputModule::save_data_products);
std::cout << "FORM output module registered successfully\n";
}