Chain¶
The chain class provides multi-file processing with sequential iteration and parallel processing support.
hipo::chain¶
Construction¶
explicit chain(int threads = 0, bool progress = true, bool verbose = false);
threads: Number of worker threads (0 = auto-detect hardware concurrency)progress: Show progress bar during processingverbose: Enable verbose output
File Management¶
int add(std::string_view filename); // add a single file
int add(std::vector<std::string>& filenames); // add multiple files
int add_pattern(std::string_view pattern); // add files matching glob pattern
void clear(); // remove all files
// Glob patterns
ch.add_pattern("data/*.hipo");
ch.add_pattern("run_???.hipo");
File Information¶
std::size_t size() const; // number of files
bool empty() const;
const FileInfo& operator[](std::size_t idx); // file info by index
std::vector<FileInfo>& files(); // all file infos
Configuration¶
void set_tags(const std::vector<long>& tags);
void set_threads(int n);
void set_progress(bool show);
void set_verbose(bool verbose);
Validation¶
void open(bool validate_all = true);
Validates files and optionally loads metadata (event counts, record counts).
Sequential Iteration¶
iterator begin();
iterator end();
Enables range-based for loops:
hipo::chain ch;
ch.add("file1.hipo");
ch.add("file2.hipo");
for (auto& [event, file_idx, event_idx] : ch) {
auto particles = event.getBank("REC::Particle");
// process...
}
Parallel Processing¶
template<typename ProcessFunc>
void process(ProcessFunc&& func, double percentage = 100.0);
Uses record-level parallelism: each thread grabs entire records and processes all events within them sequentially.
ch.process([](auto& event, int file_idx, long event_idx) {
auto particles = event.getBank("REC::Particle");
// thread-safe processing...
});
Filtered Processing¶
template<typename ProcessFunc>
void process_filtered(ProcessFunc&& func,
const std::vector<std::string>& required_banks,
double percentage = 100.0);
Only processes events containing all specified banks:
ch.process_filtered([](auto& event, int file_idx, long event_idx) {
auto parts = event.getBank("REC::Particle");
auto calos = event.getBank("REC::Calorimeter");
// both banks guaranteed to have data
}, {"REC::Particle", "REC::Calorimeter"});
File-Level Operations¶
template<typename FileFunc>
void for_each_file(FileFunc&& func);
ch.for_each_file([](hipo::reader& r, const hipo::FileInfo& info) {
printf("File %d: %s (%ld events)\n",
info.index, info.filename.c_str(), info.total_events);
});
Scanning & Display¶
void scan(); // scan and display file info with progress
void list() const; // print file list
void show_all_info(); // detailed info for all files
void print_statistics(); // processing statistics
Statistics¶
const ChainStatistics& statistics() const;
long total_events();
Configuration Access¶
bool any_has_config(std::string_view name);
std::optional<std::string> get_config(std::string_view name);
hipo::FileInfo¶
struct FileInfo {
std::string filename;
int index{0};
long total_events{-1}; // -1 = not yet loaded
int num_records{-1};
std::uintmax_t file_size{0};
bool is_valid{true};
std::string error_message;
bool metadata_loaded() const;
std::string size_string() const; // human-readable size
};
hipo::ChainStatistics¶
struct ChainStatistics {
std::atomic<long> total_events{0};
std::atomic<long> events_processed{0};
std::atomic<long> events_skipped{0};
double elapsed_seconds() const;
double throughput() const; // events/sec
};
hipo::chain_event¶
Event wrapper providing bank access via dictionary:
bank getBank(const std::string& name);
bank get_bank(const std::string& name); // snake_case alias
event* raw();
explicit operator bool() const;