您的任务有几个子步骤,对于每个子步骤,您可能有多个选项。
- 读取 csv
stackoverflow has you covered here for standalone c++ 然后您可以在标准 c++ 中使用它或使用 root 工具,以及 for reading into a ttree、或 using regular data science tools with root 或 with a root tgraph constructor(但我不熟悉 tgraph 对象系列,而不仅仅是阅读文档)。
- 选择第三列值
我对 TTree 最熟悉,在这里您可以选择类似于(取决于您实际创建树的方式)your_tree->Draw("fourth_column_for_y_axis:first_column_for_x_axis","third_column==-0.7")
这里有问题:你仍然需要找出第三列的值来选择和构建选择字符串(TTree::Draw的第二个参数)。
(以及下一点的其他内容),因此我建议将第三列值实际保留在某些 c++ 数据结构中。将它们填写在unique_set 中应该可以满足您的需要。
- 绘图
在这里,我实际上认为TTree::Draw 是一个糟糕的解决方案(使用两个变量绘图y:x 你实际上制作了一个二维直方图,而二维图是一维直方图的表示,它您可以通过填充权重 TTree::Draw("first_column",Form("(third_column==%f)*fourth_column",-0.7)) 来进行欺骗,但是您仍然需要正确设置错误栏,并且其数学可能比解决方案更难,而且无法维护)。
- 找出适合您的工具组合
所以我认为使用上面的任何标准 c++ 将数据加载到 STL 容器中并使用 STL 算法来处理数据更有意义。一旦你把它做成某种形状,你就可以得到图表(这里没有好代码的要点,只是勾勒出如何用未经测试的准代码构建TGraphErrors,我希望它很容易阅读,几乎不需要先决条件):
std::unique_set<float> third_column_unique_values = …
std::vector<std::tuple<float,float,float,float> > rows_1_3_4_5 = …
// loop over all unique values in the third column
for (auto third_value : third_column_unique_values) {
std::vector<float> x, y, ey;
// now loop over all rows and skip the "currently wrong ones"
for (auto row: rows_1_3_4_5) {
// WARNING: indices of rows and tuples get confusing
// WARNING: float point comparison here, that's bad
if (std::get<1>(row) != third_value) continue;
x.push_back(std::get<0>(row));
y.push_back(std::get<2>(row));
ey.push_back(std::get<3>(row));
}
/// I didn't find a TGraphError class with only errors in y direction,
// but only searched for a few seconds, you might go more into
// detail, I just set them all to 0 here
std::vector<float> ex(0.f, x.size());
TGraphErrors* graph = new TGraphErrors(x.size(), &x[0], &y[0], &ex[0], &ey[0]);
}
然后您可能希望将graph 排除在循环之外。注意:无需担心指向x、y、...向量的开头,TGraphErrors 的构造函数会复制预期数组的内容。