Row Filtering¶
HIPO provides three ways to filter rows within a bank: lambda functions, expression strings, and pre-constructed parsers.
Lambda Filter¶
Filter rows using a C++ lambda or std::function:
auto& rl = particles.getMutableRowList();
rl.filter([](hipo::bank& b, int row) {
return b.getInt("charge", row) != 0;
});
// Iterate only over filtered rows
for (auto row : particles.getRowList()) {
int pid = particles.getInt("pid", row);
// only charged particles
}
Expression Filter¶
Filter using a string expression:
particles.getMutableRowList().filter("charge!=0");
Supported operators: ==, !=, <, >, <=, >=, &&, ||
// Combined conditions
particles.getMutableRowList().filter("pid==11&&charge<0");
// Numeric comparisons
particles.getMutableRowList().filter("px>0.5");
Parser Caching¶
For repeated filtering across events, pre-construct a Parser to avoid re-parsing the expression:
hipo::Parser chargedFilter("charge!=0");
while (reader.next(list)) {
list[0].getMutableRowList().filter(chargedFilter);
for (auto row : list[0].getRowList()) {
// process charged particles
}
}
Performance
Parser caching avoids string parsing on every event. Use it in hot loops for measurable speedup.
Resetting the Row List¶
After filtering, reset to get all rows back:
particles.getMutableRowList().reset();
// or reset with a specific count
particles.getMutableRowList().reset(particles.getRows());
Manual Row List¶
Set a custom list of row indices:
hipo::bank::rowlist::list_t myRows = {0, 2, 5, 7};
particles.getMutableRowList().setList(myRows);
Full Row List¶
Get all rows regardless of filtering:
auto allRows = particles.getFullRowList();
Cross-Bank Linking¶
Get rows linked to a specific row in another bank:
// Get detector hits linked to particle in row 0
auto linkedRows = detectors.getRowListLinked(0, pindexCol);
for (auto row : linkedRows) {
float energy = detectors.getFloat("energy", row);
}
Combined Filtering Example¶
hipo::reader reader;
reader.open("data.hipo");
auto list = reader.getBanks({"REC::Particle", "REC::Calorimeter"});
hipo::Parser electronFilter("pid==11&&charge<0");
auto pindexCol = list[1].getSchema().getEntryOrder("pindex");
while (reader.next(list)) {
// Filter particles to electrons only
list[0].getMutableRowList().filter(electronFilter);
for (auto row : list[0].getRowList()) {
float px = list[0].getFloat("px", row);
float py = list[0].getFloat("py", row);
float pz = list[0].getFloat("pz", row);
// Get calorimeter hits for this electron
auto caloRows = list[1].getRowListLinked(row, pindexCol);
for (auto cRow : caloRows) {
float energy = list[1].getFloat("energy", cRow);
}
}
}