Filling a TTree

Hello everyone,
I am trying to fill a TTree, but have not worked with this structure before. I already have a few TTree’s saved in several files and would like to combine them into new Trees. Somehow my code does fill the trees, but I get a lot of error messages like:

Error in TTree::Fill: Failed filling branch:TreeB.KaonX, nbytes=-1, entry=295297
This error is symptomatic of a Tree created as a memory-resident Tree
Instead of doing:
TTree *T = new TTree(…)
TFile *f = new TFile(…)
you should do:
TFile *f = new TFile(…)
TTree *T = new TTree(…)
which I do not understand. Therefor I am going to share my code with you, so that maybe some more experienced user sees my error when handling trees. I suppose it is a rather general problem I have with handling them.

void Creator(Int_t n,TString Filenames[n],TTree *Tr){
    Double_t KaonMass;
    Double_t KaonX;
    Double_t KaonY;
    Double_t KaonZ;
    Double_t TaggerE;
    Double_t MissingMass;

    auto KaonMBranch = Tr->Branch("KaonMass",&KaonMass,"KaonMass/F");
    auto KaonXBranch = Tr->Branch("KaonX",&KaonX,"KaonX/F");
    auto KaonYBranch = Tr->Branch("KaonY",&KaonY,"KaonY/F");
    auto KaonZBranch = Tr->Branch("KaonZ",&KaonZ,"KaonZ/F");
    auto TaggerEBranch = Tr->Branch("TaggerE",&TaggerE,"TaggerE/F");
    auto MissingMassBranch = Tr->Branch("MissingMass",&MissingMass,"MissingMass/F");

    for(int i=0;i<n;i++){
        TFile *f = TFile::Open(Filenames[i]);
        TTree *t = (TTree*) f->FindObjectAny("t");

        TClonesArray *p4Kaon = 0;
        TClonesArray *p4KaonMass = 0;
        TClonesArray *p4Tagger = 0;

        t->SetBranchAddress("lP4_FSKaonPlus",&p4Kaon);
        t->SetBranchAddress("lP4_FSKaonPlusMass",&p4KaonMass);
        t->SetBranchAddress("lP4_Tagger",&p4Tagger);

        TLorentzVector* KaonPlus;
        TLorentzVector* KaonM;
        TLorentzVector* TaggerPhoton;

        Double_t mp = 938.27208816;
        TLorentzVector Proton(0,0,0,mp);

        for(int event=0;event<t->GetEntries();event++) {
            t->GetEntry(event);
            if (p4Tagger->GetEntriesFast() == 1 && p4Kaon->GetEntriesFast() == 1 && p4KaonMass->GetEntriesFast() == 1) {
                TaggerPhoton = static_cast<TLorentzVector *>(p4Tagger->UncheckedAt(0));
                TaggerE = TaggerPhoton->E();
                KaonPlus = static_cast<TLorentzVector *>(p4Kaon->UncheckedAt(0));
                KaonX = KaonPlus->X();
                KaonY = KaonPlus->Y();
                KaonZ = KaonPlus->Z();
                KaonM = static_cast<TLorentzVector *>(p4KaonMass->UncheckedAt(0));
                KaonMass = KaonM->E();
                MissingMass = (*TaggerPhoton + Proton - *KaonPlus).M();
                Tr->Fill();
            }
        }
        f->Close();
    }
}

void TreeCreater()
{
    TTree *TreeS = new TTree("TreeS","TheTreeS");
    TTree *TreeB = new TTree("TreeB","TheTreeB");

    TString SignalName[1] = {"../Data/FV_SW_GP_KPlusLambda_bl_1520_br_0.root"};
    Creator(1,SignalName,TreeS);
    TString BackgroundName[3] = {"../Data/FV_SW_GP_KPlusLambda_bl_1405_br_0.root","../Data/FV_SW_GP_KPlusSigma0.root","../Data/FV_SW_GP_KPlusLambda0.root"};
    Creator(3,BackgroundName,TreeB);
    TreeS->Print();
    TreeB->Print();
    TFile *Output = new TFile("Output.root","RECREATE");
    TreeS->Write();
    TreeB->Write();
    Output->Close();
}

Thank you very much!

I guess @pcanal can help.

Try:

    TFile *Output = new TFile("Output.root","RECREATE");
    TreeS->SetDirectory(Output);
    TreeB->SetDirectory(Output);
    Output->Write();
    Output->Close();

or maybe

    TreeS->SetDirectory(0);
    TreeB->SetDirectory(0);

right after creating them.

Thanks, that actually seems to work! I did not know you needed to have a place to save the tree, but it does make sense. However, there seems to be another problem with the way I am filling the tree.
While it does create and save the trees just as I would imagine, the saved values seem to be simply machine precision (eg value 500, saved value 10e36). Does anyone see the problem there?
Thanks!

To clarify, I created the dummy code, which seems to be the problem:

TTree *t = new TTree("test","test");
Double_t Mass;
t->Branch("Mass",&Mass,"Mass/F");
Mass=5;
t->Fill();
t->Show(0);

The result is that Mass has the value of 0, which I do not understand.
Maybe that helps.

t->Branch("Mass",&Mass,"Mass/D");
1 Like
t->Branch("Mass",&Mass);

should also work.

1 Like

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