Skip to content

Commit

Permalink
Re-wrote the CSV cell reading code.
Browse files Browse the repository at this point in the history
Made sure that proper comparison operators would exist for
traccc::cell and traccc::cell_module, and then just relied on
STL containers for ordering the cells and modules correctly
in memory.
  • Loading branch information
krasznaa authored and stephenswat committed Apr 22, 2024
1 parent 002bd91 commit 159c757
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 98 deletions.
13 changes: 9 additions & 4 deletions core/include/traccc/edm/cell.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** TRACCC library, part of the ACTS project (R&D line)
*
* (c) 2022 CERN for the benefit of the ACTS project
* (c) 2022-2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/
Expand Down Expand Up @@ -37,6 +37,12 @@ struct cell_module {
/// Declare all cell module collection types
using cell_module_collection_types = collection_types<cell_module>;

/// Comparison operator for cell modules
TRACCC_HOST_DEVICE
inline bool operator<(const cell_module& lhs, const cell_module& rhs) {
return lhs.surface_link < rhs.surface_link;
}

/// Equality operator for cell module
TRACCC_HOST_DEVICE
inline bool operator==(const cell_module& lhs, const cell_module& rhs) {
Expand All @@ -61,17 +67,16 @@ struct cell {
/// Declare all cell collection types
using cell_collection_types = collection_types<cell>;

/// Comparison operator for cells
TRACCC_HOST_DEVICE
inline bool operator<(const cell& lhs, const cell& rhs) {

if (lhs.module_link != rhs.module_link) {
return lhs.module_link < rhs.module_link;
} else if (lhs.channel0 != rhs.channel0) {
return (lhs.channel0 < rhs.channel0);
} else if (lhs.channel1 != rhs.channel1) {
return (lhs.channel1 < rhs.channel1);
} else {
return lhs.activation < rhs.activation;
return (lhs.channel0 < rhs.channel0);
}
}

Expand Down
133 changes: 39 additions & 94 deletions io/src/csv/read_cells.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** TRACCC library, part of the ACTS project (R&D line)
*
* (c) 2022-2023 CERN for the benefit of the ACTS project
* (c) 2022-2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/
Expand All @@ -11,30 +11,25 @@
#include "traccc/io/csv/make_cell_reader.hpp"

// System include(s).
#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <set>
#include <stdexcept>
#include <utility>
#include <vector>

namespace {

/// Comparator used for sorting cells. This sorting is one of the assumptions
/// made in the clusterization algorithm
const auto comp = [](const traccc::cell& c1, const traccc::cell& c2) {
return c1.channel1 < c2.channel1;
};

/// Helper function which finds module from csv::cell in the geometry and
/// digitization config, and initializes the modules limits with the cell's
/// properties
traccc::cell_module get_module(traccc::io::csv::cell c,
traccc::cell_module get_module(const std::uint64_t geometry_id,
const traccc::geometry* geom,
const traccc::digitization_config* dconfig,
const std::uint64_t original_geometry_id) {

traccc::cell_module result;
result.surface_link = detray::geometry::barcode{c.geometry_id};
result.surface_link = detray::geometry::barcode{geometry_id};

// Find/set the 3D position of the detector module.
if (geom != nullptr) {
Expand Down Expand Up @@ -81,106 +76,56 @@ void read_cells(
const digitization_config* dconfig,
const std::map<std::uint64_t, detray::geometry::barcode>* barcode_map) {

// Temporary storage for all the cells and modules.
std::map<std::uint64_t, std::set<traccc::cell> > cellsMap;

// Construct the cell reader object.
auto reader = make_cell_reader(filename);

// Create cell counter vector.
std::vector<unsigned int> cellCounts;
cellCounts.reserve(5000);

cell_module_collection_types::host& result_modules = out.modules;
result_modules.reserve(5000);

// Create a cell collection, which holds on to a flat list of all the cells
// and the position of their respective cell counter & module.
std::vector<std::pair<csv::cell, unsigned int>> allCells;
allCells.reserve(50000);

// Read all cells from input file.
csv::cell iocell;
unsigned int nduplicates = 0;
while (reader.read(iocell)) {

// Modify the geometry ID of the cell if a barcode map is provided.
const std::uint64_t original_geometry_id = iocell.geometry_id;
// Add the cell to the module. At this point the module link of the
// cells is not set up correctly yet.
if (cellsMap[iocell.geometry_id]
.insert({iocell.channel0, iocell.channel1, iocell.value,
iocell.timestamp, 0})
.second == false) {
++nduplicates;
}
}
if (nduplicates > 0) {
std::cout << "WARNING: @traccc::io::csv::read_cells: " << nduplicates
<< " duplicate cells found in " << filename << std::endl;
}

// Fill the output containers with the ordered cells and modules.
for (const auto& [original_geometry_id, cells] : cellsMap) {

// Modify the geometry ID of the module if a barcode map is provided.
std::uint64_t geometry_id = original_geometry_id;
if (barcode_map != nullptr) {
const auto it = barcode_map->find(iocell.geometry_id);
const auto it = barcode_map->find(geometry_id);
if (it != barcode_map->end()) {
iocell.geometry_id = it->second.value();
geometry_id = it->second.value();
} else {
throw std::runtime_error(
"Could not find barcode for geometry ID " +
std::to_string(iocell.geometry_id));
std::to_string(geometry_id));
}
}

// Look for current module in cell counter vector.
auto rit = std::find_if(result_modules.rbegin(), result_modules.rend(),
[&iocell](const cell_module& mod) {
return mod.surface_link.value() ==
iocell.geometry_id;
});
if (rit == result_modules.rend()) {
// Add new cell and new cell counter if a new module is found
const cell_module mod =
get_module(iocell, geom, dconfig, original_geometry_id);
allCells.push_back({iocell, result_modules.size()});
result_modules.push_back(mod);
cellCounts.push_back(1);
} else {
// Add a new cell and update cell counter if repeat module is found
const unsigned int pos =
std::distance(result_modules.begin(), rit.base()) - 1;
allCells.push_back({iocell, pos});
++(cellCounts[pos]);
// Add the module and its cells to the output.
out.modules.push_back(
get_module(geometry_id, geom, dconfig, original_geometry_id));
for (auto& cell : cells) {
out.cells.push_back(cell);
// Set the module link.
out.cells.back().module_link = out.modules.size() - 1;
}
}

// Transform the cellCounts vector into a prefix sum for accessing
// positions in the result vector.
std::partial_sum(cellCounts.begin(), cellCounts.end(), cellCounts.begin());

// The total number cells.
const unsigned int totalCells = allCells.size();

// Construct the result collection.
cell_collection_types::host& result_cells = out.cells;
result_cells.resize(totalCells);

// Member "-1" of the prefix sum vector
unsigned int nCellsZero = 0;
// Fill the result object with the read csv cells
for (unsigned int i = 0; i < totalCells; ++i) {
const csv::cell& c = allCells[i].first;

// The position of the cell counter this cell belongs to
const unsigned int& counterPos = allCells[i].second;

unsigned int& prefix_sum_previous =
counterPos == 0 ? nCellsZero : cellCounts[counterPos - 1];
result_cells[prefix_sum_previous++] = traccc::cell{
c.channel0, c.channel1, c.value, c.timestamp, counterPos};
}

if (cellCounts.size() == 0) {
return;
}
/* This is might look a bit overcomplicated, and could be made simpler by
* having a copy of the prefix sum vector before incrementing its value when
* filling the vector. however this seems more efficient, but requires
* manually setting the 1st & 2nd modules instead of just the 1st.
*/

// Sort the cells belonging to the first module.
std::sort(result_cells.begin(), result_cells.begin() + nCellsZero, comp);
// Sort the cells belonging to the second module.
std::sort(result_cells.begin() + nCellsZero,
result_cells.begin() + cellCounts[0], comp);

// Sort cells belonging to all other modules.
for (unsigned int i = 1; i < cellCounts.size() - 1; ++i) {
std::sort(result_cells.begin() + cellCounts[i - 1],
result_cells.begin() + cellCounts[i], comp);
}
}

} // namespace traccc::io::csv

0 comments on commit 159c757

Please sign in to comment.