1

我之前在官方根(CERN)论坛上问过这个问题,但到目前为止问题仍未解决。也许这里的任何人都可以通过指出我的错误或提出替代方法来提供帮助?

我有一个带有事件的 TTree;TTree 有一个分支,其中包含每个事件的 UNIX 时间和一些其他分支。我想根据时间间隔选择事件的子集,以便我可以单独分析这些事件。为了进行选择,我创建了另一棵树并在正确的时间间隔内复制所有条目。

以下代码运行良好,并将所有事件从树复制到子树:

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
     *subtree = tree->CloneTree(0);
     Int_t t;
     tree->SetBranchAddress("UNIX time", &t);
     for(Long64_t i = 0; i<tree->GetEntries(); i++){
        tree->GetEntry(i);
        if (true)
        {
            (*subtree)->Fill();
        }
     }
     cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
     return;
}

当我用实际条件替换 if(true) 时会出现问题:

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
     *subtree = tree->CloneTree(0);
     Int_t t;
     tree->SetBranchAddress("UNIX time", &t);
     for(Long64_t i = 0; i<tree->GetEntries(); i++){
        tree->GetEntry(i);
        if (t > time_i && t < time_f) //-> the condition
        {
            (*subtree)->Fill(); //-> this line now gives an error
        }
     }
     cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
     return;
}

我收到错误:“错误:指向类对象子树的非法指针 0x0 3084 c:/.... * 已恢复解释器错误 *

错误行指的是 (*subtree) -> Fill(),与第一个示例中运行良好的代码相同。对于不涉及 t 或任何不涉及子树的 if-body 的任何条件,该代码都有效。谁能解释这里出了什么问题?

谢谢!

(作为参考,原始问题的链接:http ://root.cern.ch/phpBB3/posting.php?mode=edit&f=3&p=79722 )

4

2 回答 2

2

我认为这是解释器的问题,在我看来是一个错误。

当宏第一次经过时,我可以重现您的错误,(*subtree)->Fill();它没有填充任何内容。这很奇怪,因为它没有进入那里,但是......

我能够通过制作两个循环来解决它:第一个循环循环直到找到第一个通过剪切的事件然后停止。第二个(*subtree)->Fill();是从这个事件开始的地方,确保第一个处理的事件通过剪切并被填充。

于 2014-10-13T09:27:26.650 回答
0

感谢 Asen Christov,这是该功能的工作版本。我将两个 for 循环放在一个 while 循环中,以防事件不按时间顺序排列;这应该可以工作,但没有经过广泛的测试。我真的不敢相信这是完成如此常见任务的最佳方式,因此任何“标准”方式仍然受到欢迎。

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
     *subtree = tree->CloneTree(0);
     Int_t t;
     tree->SetBranchAddress("UNIX time", &t);
     Long64_t i = 0;
     while (i < tree->GetEntries())
     {
         for(i; i<tree->GetEntries(); i++){
            tree->GetEntry(i);
            if (t > time_i && t < time_f) break;
         }
         for (i; i<tree->GetEntries(); i++){
            tree->GetEntry(i);
            (*subtree)->Fill();
            if (!(t > time_i && t < time_f)) break;
         }
     }
     cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
     return;
}
于 2014-10-13T12:51:47.557 回答