Chain¶
The chain class is the recommended entry point for reading HIPO files. It processes
one or many files with sequential iteration (a range-based for loop) or parallel
processing (process()), and handles file opening and dictionary loading for you.
hipo::chain¶
Construction¶
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
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¶
Validates files and optionally loads metadata (event counts, record counts).
Sequential Iteration¶
This is the recommended default for reading files. The begin()/end() pair enables
a range-based for loop that walks every event across every file in the chain:
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...
}
The loop yields a chain_event plus the current file_idx and the running
event_idx. Use this unless you specifically need the parallel process() path below.
Parallel Processing¶
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¶
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¶
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: