From 3a3a57435c6c128938e56843122b25dcb432a677 Mon Sep 17 00:00:00 2001 From: Jacob Davis Date: Tue, 25 Aug 2026 15:26:33 -0400 Subject: [PATCH] Initial commit --- Makefile | 27 +++++++++++++++ root2mat.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 Makefile create mode 100644 root2mat.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50e50ab --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +# Compiler +CXX := g++ + +# ROOT flags +ROOTCFLAGS := $(shell root-config --cflags) +ROOTLIBS := $(shell root-config --libs) + +# Compilation flags +CXXFLAGS := -O2 -Wall -Wextra -std=c++17 $(ROOTCFLAGS) + +# Target executable +TARGET := root2mat + +# Source files +SOURCES := root2mat.cpp + +# Default rule +all: $(TARGET) + +$(TARGET): $(SOURCES) + $(CXX) $(CXXFLAGS) $^ -o $@ $(ROOTLIBS) + +# Clean rule +clean: + rm -f $(TARGET) + +.PHONY: all clean diff --git a/root2mat.cpp b/root2mat.cpp new file mode 100644 index 0000000..79f841b --- /dev/null +++ b/root2mat.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +// ROOT Headers +#include +#include + +void root2mat(const std::string& inputRoot, const std::string& histName, const std::string& outputMat) { + constexpr int X_SIZE = 4096; + constexpr int Y_SIZE = 4096; + constexpr size_t TOTAL_BINS = static_cast(X_SIZE) * Y_SIZE; + + // Open ROOT file + TFile* inFile = TFile::Open(inputRoot.c_str(), "READ"); + if (!inFile || inFile->IsZombie()) { + std::cerr << "Error: Could not open input ROOT file " << inputRoot << std::endl; + return; + } + + // Get 2D histogram + TH2* h2 = dynamic_cast(inFile->Get(histName.c_str())); + if (!h2) { + std::cerr << "Error: Could not find TH2 histogram named '" << histName << "' in file." << std::endl; + inFile->Close(); + delete inFile; + return; + } + + // Determine target format and integer depth based on output extension + bool is32Bit = false; + if (outputMat.length() >= 4 && outputMat.substr(outputMat.length() - 4) == ".spn") { + is32Bit = true; + } else if (outputMat.length() >= 4 && outputMat.substr(outputMat.length() - 4) == ".mat") { + is32Bit = false; + } else { + std::cerr << "Error: Unsupported output file extension. Must be .mat or .spn" << std::endl; + inFile->Close(); + delete inFile; + return; + } + + std::cout << "Extracting '" << histName << "' into " << X_SIZE << " x " << Y_SIZE + << " binary matrix (" << (is32Bit ? "32-bit .spn" : "16-bit .mat") << ")..." << std::endl; + + // Open output binary file + std::ofstream outFile(outputMat, std::ios::binary); + if (!outFile.is_open()) { + std::cerr << "Error: Could not create output file " << outputMat << std::endl; + inFile->Close(); + delete inFile; + return; + } + + // Extract bin contents row-by-row matching column-major order (x * Y_SIZE + y) + if (is32Bit) { + std::vector buffer(TOTAL_BINS); + for (int x = 0; x < X_SIZE; ++x) { + for (int y = 0; y < Y_SIZE; ++y) { + // ROOT bins are 1-indexed + buffer[x * Y_SIZE + y] = static_cast(h2->GetBinContent(x + 1, y + 1)); + } + } + outFile.write(reinterpret_cast(buffer.data()), TOTAL_BINS * sizeof(int32_t)); + } else { + std::vector buffer(TOTAL_BINS); + for (int x = 0; x < X_SIZE; ++x) { + for (int y = 0; y < Y_SIZE; ++y) { + // ROOT bins are 1-indexed[cite: 1] + buffer[x * Y_SIZE + y] = static_cast(h2->GetBinContent(x + 1, y + 1)); + } + } + outFile.write(reinterpret_cast(buffer.data()), TOTAL_BINS * sizeof(int16_t)); + } + + outFile.close(); + inFile->Close(); + delete inFile; + + std::cout << "Successfully written matrix to " << outputMat << std::endl; +} + +int main(int argc, char* argv[]) { + if (argc < 4) { + std::cout << "Usage: " << argv[0] << " \n"; + return 1; + } + + root2mat(argv[1], argv[2], argv[3]); + return 0; +} \ No newline at end of file