Creating a 2D-vector of histograms

Hello All,
I am new to C++ and root, so please bear with me.
Question: how to create a 2D std::vector of histograms?

My requirements: I need to read a text file of n rows. Each row is a pair of numbers like this:

32 19
43 122
89 12
...
12 89

The first number is the unique identifier of a detector and the second no is the number of channels in that detector. I want to create a number of histograms Hist[rows][b] (of type TH1F) where rows is the number of rows in this text file, and b is the channels for that detector. So, Hist[32]* would have 19 TH1F histograms, Hist[43]* would have 122 TH1F histograms, and so on.

What I tried:

vector<vector<int>> DetNoArray; //I read the text file into this array
DetNoArray.push_back(std::vector<int>());


// Create the DetNoArray
for (...)
{
    ... // Read from file and fill in array
    DetNoArray.push_back(std::vector<int>());
    DetNoArray[numberofboards].push_back(value_a);
    DetNoArray[numberofboards].push_back(value_b);
}


// Print out the array to make sure I read it without erros
for (auto &value : DetNoArray)
    printf("DetNo:%-5i  Channels:%-5i\n", value[0], value[1]);


/*
DetNo:32 Channels:19
DetNo:43 Channels:122
DetNo:89 Channels:12
...
DetNo:12 Channels:89
*/

// Create the histogram vector
vector<vector<TH1F *>> Histogram;


// Create n rows of histograms
for (auto &value : DetNoArray)
    Histogram.push_back(vector<TH1F *>());

// Create columns for each row
for (auto &value : DetNoArray)
{
    for (int i = 0; i < value[1]; i++)
    {
        sprintf(histname, "B%i_C%i", vec[0], i);
        printf("Creating histogram %s\n",histname); 
        // MY CODE FAILS HERE:
        Histogram[value[0]].push_back(new TH1F(histname, histname, nobins, lower_range, higher_range));
    }
}


// Now access and fill the histogram
// My intent is to access the array like this and fill it
int board=32;
int channel=18;
Histogram[board][channel]->Fill(position);

FAILURE:

Creating histogram B43_C0
*** Break *** segmentation violation
There was a crash.
This is the entire stack trace of all threads:

ASK: How do I fix this? Ie creating this 2D array of TH1F and access it like Histogram[board][channel] ?

Thanks in advance


ROOT Version: ROOT 6.27/0
Platform: Linux
Compiler: g++


Hi and welcome to the ROOT Forum!

This question seems more related to C++ than ROOT: let’s have a look.
The std::vector<std::vector<T>> is in general a poor data structure, given the nature of the problem you describe, a std::map<unsigned int, std::vector<TH1F>> seems more adequate.
Below I provide a simple example which hopefully can get you started:

    // will be filled by parsing the file
    std::vector<std::pair<unsigned int, unsigned int>> detID_channels_map {{32,19}, {43,122}, {89,12}};

    std::map<unsigned int, std::vector<TH1F>> detID_histos_map;
    // histograms features, completely guessed 
    const auto minx = -4;
    const auto maxx = 4;
    const auto nbins = 64;
    
    for (auto& [detID, channels] : detID_channels_map) {
        auto& histos =detID_histos_map[detID];
        histos.reserve(channels);
        for (auto i : ROOT::TSeqI(channels)) {
            histos.emplace_back("","",nbins, minx, maxx);
        }
    }

    // just print for the sake of the example...
    std::cout << gInterpreter->ToString("std::map<unsigned int, std::vector<TH1F>>", &detID_histos_map) << std::endl;

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.