【问题标题】:plotting histograms in ROOT with varying variable names在 ROOT 中绘制具有不同变量名称的直方图
【发布时间】:2012-09-25 21:04:13
【问题描述】:

我不确定如何正确表达这个问题,但这就是我想要做的。

可以使用cern ROOT和以下命令绘制单个直方图,

(TH1F*)electron->Draw();

但是我有几十个按顺序命名的直方图,例如 electron1、elecron2、electron3 等,我想编写一个简单的循环来将它们全部绘制出来。我尝试使用 sprintf 和一个简单的 for 循环,但 ROOT 不喜欢它。

char name[20];
(TH1F*)electron->Draw();
for(int j=0;j<5;j++){
            sprintf(name, "%s%d","electron",j);
            (TH1F*)name->Draw("same");
 }

我做错了什么?

提前致谢。

【问题讨论】:

    标签: c++ root-framework


    【解决方案1】:

    创建一个显示“electron0”的字符串,将指向字符串开头的char * 转换为TH1F *,并取消对它的引用,就好像字符串实际上是struct TH1F *(或class TH1F *)很可能只会使程序崩溃,并且与引用名为 electron0 的变量不同。

    可能你最好的选择是,而不是命名一堆变量electron0electron1 等...,创建一个数组,如TH1F electron[NELECTRONS];,然后将它们引用为electron[0]electron[1]等(或者,如果对象是动态分配的,则使用TH1F *electron[NELECTRONS]; 并存储指针(使用适当的间接引用来引用它们(*(electron[0]).Draw(...)electron[0]-&gt;Draw(...))。

    【讨论】:

      【解决方案2】:

      您还需要一个额外的步骤。正如@twalberg 所说,你有一个字符串,而不是一个对象指针。对于 root,您可以做的只是更改您的代码,以便我添加一行。

      char name[20];
      electron->Draw();
      for(int j=0;j<5;j++){
         sprintf(name, "%s%d","electron",j);
         TH1F *h = (TH1F*)gDirectory->Get(name); // THIS IS THE MISSING LINE
         if ( h ) h->Draw("same"); // make sure the Get succeeded 
       }
      

      额外的行按名称从本地 TDirectory 获取引用的对象。强制转换是必要的,以便 gDirectory 被强制转换为正确类型的对象。

      当您以交互方式使用 root 时,这会神奇地在幕后发生。

      【讨论】:

      • 这是正确答案。虽然您完全遵循 ROOT 的风格,但同样可以使用 std::stringboost::lexical_cast 来完成,这是一个更符合概念的 C++,但可能对大多数 ROOT 用户来说更容易混淆,因为它在 CINT 宏中效果不佳。
      • 谢谢喇叭。你可能知道 Root 并不太重视 C++ :)
      • 很快所有的事情肯定会随着 root-6 的发布而改变,其中 cling 取代了 cint。每个人都会在现代 C++ 典型的高、几乎功能级别上编写程序。曾经为 20k 行创建和填充不同直方图的 ROOT 宏将在将算法映射到数据容器的几行中完成。是的,我确信一旦我们被允许在 ROOT 分析宏中编写适当的 C++,我们将能够做我们能够做的事情。
      猜你喜欢
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 2016-12-13
      • 2019-12-16
      • 1970-01-01
      • 2019-03-08
      • 2022-01-08
      • 2020-10-24
      相关资源
      最近更新 更多