Skip to content

Commit

Permalink
Use fmt lib to for formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Jun 7, 2024
1 parent 7902ad7 commit 81e4764
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 35 deletions.
81 changes: 53 additions & 28 deletions tools/src/podio-dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@
#include "podio/podioVersion.h"
#include "podio/utilities/MiscHelpers.h"

#include <fmt/core.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>

#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <tuple>

template <>
struct fmt::formatter<podio::version::Version> : ostream_formatter {};

struct ParsedArgs {
std::string inputFile{};
std::string category{"events"};
Expand All @@ -39,7 +46,7 @@ positional arguments:
)";

void printUsageAndExit() {
std::cerr << usageMsg << std::endl;
fmt::print(stderr, "{}\n", usageMsg);
std::exit(1);
}

Expand All @@ -55,7 +62,7 @@ auto getArgumentValueOrExit(const std::vector<std::string>& argv, std::vector<st
std::vector<size_t> parseEventRange(const std::string& evtRange) {
const auto splitRange = splitString(evtRange, ',');
const auto parseError = [&evtRange]() {
std::cerr << "'" << evtRange << "' cannot be parsed into a list of entries" << std::endl;
fmt::print(stderr, "'{}' canot be parsed into a list of entries\n", evtRange);
std::exit(1);
};

Expand Down Expand Up @@ -90,9 +97,9 @@ ParsedArgs parseArgs(std::vector<std::string> argv) {
// find help or version
if (const auto it = findFlags(argv, "-h", "--help", "--version"); it != argv.end()) {
if (*it == "--version") {
std::cout << "podio " << podio::version::build_version << '\n';
fmt::print("podio {}\n", podio::version::build_version);
} else {
std::cout << usageMsg << '\n' << helpMsg << std::flush;
fmt::print("{}\n{}", usageMsg, helpMsg);
}
std::exit(0);
}
Expand Down Expand Up @@ -123,45 +130,66 @@ ParsedArgs parseArgs(std::vector<std::string> argv) {
}

template <typename T>
void printParameterOverview(const podio::Frame& frame) {
std::string getTypeString() {
if constexpr (std::is_same_v<T, int>) {
return "int";
} else if constexpr (std::is_same_v<T, float>) {
return "float";
} else if constexpr (std::is_same_v<T, double>) {
return "double";
} else if constexpr (std::is_same_v<T, std::string>) {
return "std::string";
}

return "unknown";
}

template <typename T>
void getParameterOverview(const podio::Frame& frame, std::vector<std::tuple<std::string, std::string, size_t>>& rows) {
const auto typeString = getTypeString<T>();
for (const auto& parKey : podio::utils::sortAlphabeticaly(frame.getParameterKeys<T>())) {
std::cout << parKey << "\t" << frame.getParameter<std::vector<T>>(parKey)->size() << '\n';
rows.emplace_back(parKey, typeString, frame.getParameter<std::vector<T>>(parKey)->size());
}
}

void printFrameOverview(const podio::Frame& frame) {
std::cout << "Collections\n";
std::cout << "Name\tValueType\tSize\tID\n";
for (const auto& name : frame.getAvailableCollections()) {

fmt::print("Collections:\n");
const auto collNames = frame.getAvailableCollections();

std::vector<std::tuple<std::string, std::string_view, size_t, std::string>> rows;
rows.reserve(collNames.size());

for (const auto& name : podio::utils::sortAlphabeticaly(collNames)) {
const auto coll = frame.get(name);
std::cout << name << "\t" << coll->getValueTypeName() << "\t" << coll->size() << "\t" << coll->getID() << '\n';
rows.emplace_back(name, coll->getValueTypeName(), coll->size(), fmt::format("{:0>8x}", coll->getID()));
}
printTable(rows, {"Name", "ValueType", "Size", "ID"});

fmt::print("\nParameters:\n");
std::vector<std::tuple<std::string, std::string, size_t>> paramRows{};
getParameterOverview<int>(frame, paramRows);
getParameterOverview<float>(frame, paramRows);
getParameterOverview<double>(frame, paramRows);
getParameterOverview<std::string>(frame, paramRows);

std::cout << "\nParameters\n";
printParameterOverview<int>(frame);
printParameterOverview<float>(frame);
printParameterOverview<double>(frame);
printParameterOverview<std::string>(frame);
printTable(paramRows, {"Name", "Type", "Elements"});
}

void printGeneralInfo(const podio::Reader& reader, const std::string& filename) {
std::cout << "input file: " << filename << '\n';
std::cout << "datamodel model definitions stored in this file: ";
for (const auto& model : reader.getAvailableDatamodels()) {
std::cout << model << ", ";
}
std::cout << "\n\n";

std::cout << "Frame categories in this file:\nName\tEntries\n";
fmt::print("input file: {}\n", filename);
fmt::print("datamodel model definitions stored in this file: {}\n\n", reader.getAvailableDatamodels());

std::vector<std::tuple<std::string, size_t>> rows{};
for (const auto& cat : reader.getAvailableCategories()) {
rows.emplace_back(cat, reader.getEntries(std::string(cat)));
}
fmt::print("Frame categories in this file:\nName\tEntries\n");
printTable(rows, {"Name", "Entries"});
}

void printFrame(const podio::Frame& frame, const std::string& category, size_t iEntry, bool detailed) {
std::cout << "################## " << category << ": " << iEntry << " ##################\n";
fmt::print("{:#^82}\n", fmt::format(" {}: {} ", category, iEntry));
if (detailed) {

} else {
Expand All @@ -182,13 +210,10 @@ int main(int argc, char* argv[]) {
const auto& frame = reader.readFrame(args.category, event);
printFrame(frame, args.category, event, args.detailed);
} catch (std::runtime_error& err) {
std::cerr << err.what() << std::endl;
fmt::print(stderr, "{}\n", err.what());
return 1;
}
}

// const auto event = reader.readNextEvent();
// printFrameOverview(event);

return 0;
}
50 changes: 43 additions & 7 deletions tools/src/tabulate.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,71 @@
#include <fmt/core.h>

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>

std::string rowFormatString(const std::vector<size_t>& colWidths) {
std::string rowFmt = "";
rowFmt.reserve(colWidths.size() * 6); // heuristic working for columns that are 2 digit numbers wide

for (const auto w : colWidths) {
rowFmt.append(fmt::format("{{:<{}}}", w));
}

return rowFmt;
}

template <typename... Types>
void printTable(const std::vector<std::tuple<Types...>>& rows, const std::vector<std::string>& headers) {
// Simply assume that all rows have the same widths
const auto nCols = rows[0].size();
// First figure out how large each column has to be to fit all the content
std::vector<size_t> colWidths{0, nCols};
const auto nCols = headers.size();
constexpr auto nColsFromRows = std::tuple_size_v<std::tuple<Types...>>;
if (nCols != nColsFromRows) {
throw std::invalid_argument("headers and rows have to have the same size");
}

// Transform all elements into strings first to determine column widths
std::vector<std::vector<std::string>> stringRows;
stringRows.reserve(rows.size());
std::transform(rows.begin(), rows.end(), std::back_inserter(stringRows), [&nCols](const auto& elem) {
std::vector<std::string> strs;
strs.reserve(nCols);
std::apply([&strs](auto&&... args) { (strs.emplace_back(fmt::format("{}", args)), ...); }, elem);
return strs;
});

// First figure out how large each column has to be to fit all the content
std::vector<size_t> colWidths(nCols, 0);
for (size_t i = 0; i < nCols; ++i) {
colWidths[i] = headers[i].size();
}
for (const auto& row : rows) {
for (const auto& row : stringRows) {
for (size_t iCol = 0; iCol < nCols; ++iCol) {
colWidths[iCol] = std::max(row[iCol].size(), colWidths[iCol]);
}
}

// print the table header
for (size_t iCol = 0; iCol < nCols; ++iCol) {
std::cout << std::setw(colWidths[iCol] + 1) << headers[iCol];
fmt::print("{:<{}} ", headers[iCol], colWidths[iCol]);
}
fmt::print("\n");
std::cout << '\n';
for (size_t iCol = 0; iCol < nCols; ++iCol) {
std::cout << std::setw(colWidths[iCol] + 1) << std::setfill('-') << " ";
fmt::print("{:->{}} ", "", colWidths[iCol]);
}
fmt::print("\n");

// and the contents
for (const auto& row : stringRows) {
for (size_t iCol = 0; iCol < nCols; ++iCol) {
fmt::print("{:<{}} ", row[iCol], colWidths[iCol]);
}
fmt::print("\n");
}
std::cout << '\n';
}

0 comments on commit 81e4764

Please sign in to comment.