Skip to content
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
8 changes: 8 additions & 0 deletions form/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ include_directories(${PROJECT_SOURCE_DIR}/form)
option(FORM_USE_ROOT_STORAGE "Enable ROOT Storage" ON)
option(FORM_USE_RNTUPLE_STORAGE "Enable RNTuple Storage" OFF)

# RNTuple is a ROOT sub-technology and cannot be built without ROOT.
if(FORM_USE_RNTUPLE_STORAGE AND NOT FORM_USE_ROOT_STORAGE)
message(
FATAL_ERROR
"FORM_USE_RNTUPLE_STORAGE requires FORM_USE_ROOT_STORAGE=ON (RNTuple is part of ROOT)."
)
endif()

# Add sub directories
add_subdirectory(form)
add_subdirectory(core)
Expand Down
4 changes: 2 additions & 2 deletions form/core/placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using namespace form::detail::experimental;

/// Constructor with initialization
Placement::Placement(std::string fileName, std::string containerName, int technology) :
Placement::Placement(std::string fileName, std::string containerName, technology::Id technology) :
m_technology(technology),
m_fileName(std::move(fileName)),
m_containerName(std::move(containerName))
Expand All @@ -19,4 +19,4 @@ std::string const& Placement::fileName() const { return m_fileName; }
/// Access container name
std::string const& Placement::containerName() const { return m_containerName; }
/// Access technology type
int Placement::technology() const { return m_technology; }
form::technology::Id Placement::technology() const { return m_technology; }
8 changes: 5 additions & 3 deletions form/core/placement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef FORM_CORE_PLACEMENT_HPP
#define FORM_CORE_PLACEMENT_HPP

#include "core/technology.hpp"

#include <string>

/* @class Placement
Expand All @@ -16,18 +18,18 @@ namespace form::detail::experimental {
Placement() = default;

/// Constructor with initialization
Placement(std::string fileName, std::string containerName, int technology);
Placement(std::string fileName, std::string containerName, technology::Id technology);

/// Access file name
std::string const& fileName() const;
/// Access container name
std::string const& containerName() const;
/// Access technology type
int technology() const;
technology::Id technology() const;

private:
/// Technology identifier
int m_technology{};
technology::Id m_technology{};
/// File name
std::string m_fileName;
/// Container name
Expand Down
67 changes: 67 additions & 0 deletions form/core/technology.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef FORM_CORE_TECHNOLOGY_HPP
#define FORM_CORE_TECHNOLOGY_HPP

#include <compare>
#include <stdexcept>
#include <string>
#include <string_view>

/* A storage technology, identified by a (major, minor) pair */

namespace form::technology {

// Major storage type (ROOT, HDF5, ...)
enum class Major {
generic = 0, // no specific technology requested
root = 1,
hdf5 = 2,
};

// Minor variant within a Major (e.g. TTree vs RNTuple within ROOT)
struct Id {
Major major{Major::generic};
int minor{0};

// Exact ordering over (major, minor): lets an Id be a std::map key and drives backend dispatch
constexpr auto operator<=>(Id const&) const = default;
};

// Backends: valid (major, minor) pairs, stable numeric values as a future Token may persist them
Comment thread
aolivier23 marked this conversation as resolved.
inline constexpr Id ROOT_TTREE{Major::root, 1};
inline constexpr Id ROOT_RNTUPLE{Major::root, 2};
inline constexpr Id HDF5{Major::hdf5, 1};
Comment thread
wwuoneway marked this conversation as resolved.

// Canonical string -> technology mapping: the single place a technology string is parsed, replacing the copies that used to live in each module/source/test
inline Id from_string(std::string_view name)
{
if (name == "ROOT_TTREE") {
return ROOT_TTREE;
}
if (name == "ROOT_RNTUPLE") {
return ROOT_RNTUPLE;
}
if (name == "HDF5") {
// HDF5 is a reserved technology but has no backend yet: reject it at parse time
throw std::runtime_error("Technology 'HDF5' is recognized but not yet implemented");
}
throw std::runtime_error("Unknown technology: " + std::string(name));
}

// Canonical technology -> string mapping
inline std::string to_string(Id tech)
{
if (tech == ROOT_TTREE) {
return "ROOT_TTREE";
}
if (tech == ROOT_RNTUPLE) {
return "ROOT_RNTUPLE";
}
if (tech == HDF5) {
return "HDF5";
}
return "UNKNOWN";
}

} // namespace form::technology

#endif // FORM_CORE_TECHNOLOGY_HPP
4 changes: 2 additions & 2 deletions form/core/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using namespace form::detail::experimental;

/// Constructor with initialization
Token::Token(std::string fileName, std::string containerName, int technology, int id) :
Token::Token(std::string fileName, std::string containerName, technology::Id technology, int id) :
m_technology(technology),
m_fileName(std::move(fileName)),
m_containerName(std::move(containerName)),
Expand All @@ -20,7 +20,7 @@ std::string const& Token::fileName() const { return m_fileName; }
/// Access container name
std::string const& Token::containerName() const { return m_containerName; }
/// Access technology type
int Token::technology() const { return m_technology; }
form::technology::Id Token::technology() const { return m_technology; }
/// Set technology type
/// Access identifier/entry number
int Token::id() const { return m_id; }
10 changes: 6 additions & 4 deletions form/core/token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef FORM_CORE_TOKEN_HPP
#define FORM_CORE_TOKEN_HPP

#include "core/technology.hpp"

#include <string>

/* @class Token
Expand All @@ -12,24 +14,24 @@ namespace form::detail::experimental {
class Token {
public:
/// Default constructor; delegates to the named constructor so the -1 sentinel for id is defined once
Token() : Token("", "", 0) {}
Token() : Token("", "", {}) {}

/// Named constructor; id defaults to -1 as a "not set" sentinel
Token(std::string fileName, std::string containerName, int technology, int id = -1);
Token(std::string fileName, std::string containerName, technology::Id technology, int id = -1);

/// Access file name
std::string const& fileName() const;
/// Access container name
std::string const& containerName() const;
/// Access technology type
int technology() const;
technology::Id technology() const;

/// Access identifier/entry number
int id() const;

private:
/// Technology identifier
int m_technology;
technology::Id m_technology;
/// File name
std::string m_fileName;
/// Container name
Expand Down
6 changes: 3 additions & 3 deletions form/form/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace form::experimental::config {

void ItemConfig::addItem(std::string const& product_name,
std::string const& file_name,
int technology)
technology::Id technology)
{
m_items.emplace_back(product_name, file_name, technology);
}
Expand All @@ -31,15 +31,15 @@ namespace form::experimental::config {
return std::nullopt;
}

tech_setting_config::table_t tech_setting_config::getFileTable(int const technology,
tech_setting_config::table_t tech_setting_config::getFileTable(technology::Id const technology,
std::string const& fileName) const
{
auto const per_tech = ::const_lookup(file_settings, technology);
return ::const_lookup(per_tech, fileName);
}

tech_setting_config::table_t tech_setting_config::getContainerTable(
int const technology, std::string const& containerName) const
technology::Id const technology, std::string const& containerName) const
{
auto const per_tech = ::const_lookup(container_settings, technology);
return ::const_lookup(per_tech, containerName);
Expand Down
20 changes: 12 additions & 8 deletions form/form/config.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef FORM_FORM_CONFIG_HPP
#define FORM_FORM_CONFIG_HPP

#include "core/technology.hpp"

#include <map>
#include <memory>
#include <optional>
Expand All @@ -12,13 +14,13 @@
namespace form::experimental::config {

struct PersistenceItem {
std::string product_name; // e.g. "trackStart", "trackNumberHits"
std::string file_name; // e.g. "toy.root", "output.hdf5"
int technology{}; // Technology::ROOT_TTREE, Technology::ROOT_RNTUPLE, Technology::HDF5
std::string product_name; // e.g. "trackStart", "trackNumberHits"
std::string file_name; // e.g. "toy.root", "output.hdf5"
technology::Id technology{}; // technology::ROOT_TTREE, ROOT_RNTUPLE, HDF5

PersistenceItem() = default;

PersistenceItem(std::string product, std::string file, int tech) :
PersistenceItem(std::string product, std::string file, technology::Id tech) :
product_name(std::move(product)), file_name(std::move(file)), technology(tech)
{
}
Expand All @@ -30,7 +32,9 @@ namespace form::experimental::config {
~ItemConfig() = default;

// Add a configuration item
void addItem(std::string const& product_name, std::string const& file_name, int technology);
void addItem(std::string const& product_name,
std::string const& file_name,
technology::Id technology);

// Find configuration for a product+creator combination
std::optional<PersistenceItem> findItem(std::string const& product_name) const;
Expand All @@ -44,12 +48,12 @@ namespace form::experimental::config {

struct tech_setting_config {
using table_t = std::vector<std::pair<std::string, std::string>>;
using map_t = std::map<int, std::unordered_map<std::string, table_t>>;
using map_t = std::map<technology::Id, std::unordered_map<std::string, table_t>>;
map_t file_settings;
map_t container_settings;

table_t getFileTable(int technology, std::string const& fileName) const;
table_t getContainerTable(int technology, std::string const& containerName) const;
table_t getFileTable(technology::Id technology, std::string const& fileName) const;
table_t getContainerTable(technology::Id technology, std::string const& containerName) const;
};

} // namespace form::experimental::config
Expand Down
27 changes: 0 additions & 27 deletions form/form/technology.hpp

This file was deleted.

23 changes: 5 additions & 18 deletions form/form_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,27 @@

// FORM headers - these need to be available via CMake configuration
// need to set up the build system to find these headers
#include "core/technology.hpp"
#include "form/config.hpp"
#include "form/form_writer.hpp"
#include "form/technology.hpp"

#include <cassert>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <unordered_map>

namespace {

class FormOutputModule {
public:
FormOutputModule(std::string output_file,
int technology,
form::technology::Id 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";
std::cout << " Technology: " << form::technology::to_string(m_technology) << "\n";

// Build FORM configuration
form::experimental::config::ItemConfig output_cfg;
Expand Down Expand Up @@ -104,7 +102,7 @@ namespace {
// Algorithm configuration fixed at construction; intentionally immutable for object lifetime.
// NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)
std::string const m_output_file;
int const m_technology;
form::technology::Id const m_technology;
// NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)
std::unique_ptr<form::experimental::form_writer_interface> m_form_interface;
};
Expand All @@ -123,18 +121,7 @@ PHLEX_REGISTER_ALGORITHMS(m, config)
std::cout << " output_file: " << output_file << "\n";
std::cout << " technology: " << tech_string << "\n";

std::unordered_map<std::string_view, int> const tech_lookup = {
{"ROOT_TTREE", form::technology::ROOT_TTREE},
{"ROOT_RNTUPLE", form::technology::ROOT_RNTUPLE},
{"HDF5", form::technology::HDF5}};

auto it = tech_lookup.find(tech_string);

if (it == tech_lookup.end()) {
throw std::runtime_error("Unknown technology: " + tech_string);
}

int const technology = it->second;
auto const technology = form::technology::from_string(tech_string);

auto products_to_save = config.get<std::vector<std::string>>("products");

Expand Down
14 changes: 2 additions & 12 deletions form/form_source.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "phlex/source.hpp"

#include "core/technology.hpp"
#include "form/config.hpp"
#include "form/form_reader.hpp"
#include "form/form_source_type_registry.hpp"
#include "form/technology.hpp"

#include "phlex/model/data_cell_index.hpp"

Expand All @@ -13,7 +13,6 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -176,16 +175,7 @@ PHLEX_REGISTER_SOURCE(s, config)
actual_creator = *plugin + ":" + *algorithm;
}

std::unordered_map<std::string_view, int> const tech_lookup = {
{"ROOT_TTREE", form::technology::ROOT_TTREE},
{"ROOT_RNTUPLE", form::technology::ROOT_RNTUPLE},
{"HDF5", form::technology::HDF5}};

auto it = tech_lookup.find(tech_string);
if (it == tech_lookup.end()) {
throw std::runtime_error("Unknown technology: " + tech_string);
}
int const technology = it->second;
auto const technology = form::technology::from_string(tech_string);

form::experimental::config::ItemConfig input_cfg;
form::experimental::config::tech_setting_config tech_cfg;
Expand Down
Loading
Loading