Skip to content

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);
        }
    }
}