Change content of TTree branch

Hi all,

I have a file containing a TTree with several branches. I would like to copy it to a new file and modify the content of one of the branches (a double) to a value I set. I’ve tried searching for this, but couldn’t find a way to do this. Could you let me know this this can be done?

Thanks,
Nir

Hi,

Do something like [Correction added]

   //Get old file, old tree and set top branch address
   TFile *oldfile = new TFile("$ROOTSYS/test/Event.root");
   TTree *oldtree = (TTree*)oldfile->Get("T");
   Long64_t nentries = oldtree->GetEntries();
   Event *event   = 0;
   oldtree->SetBranchAddress("event",&event);

   //Create a new file + a clone of old tree in new file
   TFile *newfile = new TFile("small.root","recreate");
   TTree *newtree = oldtree->CloneTree(0);

   for (Long64_t i=0;i<nentries; i++) {
      oldtree->GetEntry(i);
      event->SetTemperature( (event->GetTemperatue() - 32) * 5/9 ); // Change from Fahrenheit to Celsius:
      if (event->GetNtrack() > 605) newtree->Fill(); // filtering unwanted entries.
      event->Clear();
   }
   newtree->AutoSave();
   delete oldfile;
   delete newfile;

Cheers,
Philippe.

Hi Philippe,

In the example you provided, does this code change the branch event in the tree T? I cannot go through the code. What is SetTemprature()? Is it a member function in ROOT?

Thank you and cheers,
Parisa

grep -r [GS]etTemperature ${ROOTSYS}/test/ ${ROOTSYS}/tutorials/

BTW. The example source code reads the “oldtree” from the “oldfile” and writes the “newtree” (with modified and filtered “event”) to the “newfile”.

Actually no, due to a bug in my code snippet. Fill must (of course) be called after the data object has been modified. Corrected version:

//Get old file, old tree and set top branch address
   TFile *oldfile = new TFile("$ROOTSYS/test/Event.root");
   TTree *oldtree = (TTree*)oldfile->Get("T");
   Long64_t nentries = oldtree->GetEntries();
   Event *event   = 0;
   oldtree->SetBranchAddress("event",&event);
   //Create a new file + a clone of old tree in new file
   TFile *newfile = new TFile("small.root","recreate");
   TTree *newtree = oldtree->CloneTree(0);
   for (Long64_t i=0;i<nentries; i++) {
      oldtree->GetEntry(i);
      // Do some data modifications. 
      event->SetTemperature( (event->GetTemperatue() - 32) * 5/9 ); // Change from Fahrenheit to Celsius:
      if (event->GetNtrack() > 605)  // filtering unwanted entries.
      {
          newtree->Fill(); // For those entry passing the filter, store the modified version of the data (and the untouched part too).
      }
      event->Clear();
   }
   newtree->AutoSave();
   delete oldfile;
   delete newfile;

Cheers,
Philippe.

1 Like

Thank you. I checked the file including SetTemperature but still don’t understand what are:

SetTemperature
GetTemperatue()
GetNtrack()

I am sorry but I am very new to ROOT and do need to modify the content of some branches in some root files. I just need a simple modification, like adding a constant to all entries of a branch.

Those are C++ methods of the class Event. They are modifiers of the data objects.

Cheers,
Philippe.

1 Like

Thank you all for your help. I am almost there however still there’s one more problem. I use the following code to modify the branch “event_ID” in the tree “Singles” and what I get in the cloned root file is that the new evend_IDs includes both old and modified values! Please note that I am talking about the branch in the new root file which I wish to include only the modified numbers. Could you spot where the problem is?

>     void modify_event_ID()
>     {
>       Int_t last_stored_eventID = 0; //sum
>       for (int i=1; i<=20; i++)
>       {
>         std::string oldfile_name = "rootfile" + std::to_string(i) + ".root";
>         TFile *oldfile = new TFile(oldfile_name.c_str());
>         TTree *oldtree_singles = (TTree*)oldfile->Get("Singles");
> 
>         Int_t eventID = 0;
>         oldtree_singles->SetBranchAddress("eventID",&eventID);
>         oldtree_singles->SetBranchStatus("*",1); //NOTE: Only active branches are copied.
> 
>         std::string newfile_name = "rootfile" + std::to_string(i) + "_modified.root";
>         TFile *newfile = new TFile(newfile_name.c_str(),"recreate");
>         TTree *newtree_singles = oldtree_singles->CloneTree(-1, "fast");
> 
>         for (Int_t j=0;j<oldtree_singles->GetEntries(); j++)
>         {
>             oldtree_singles->GetEntry(j);
>             //modify event ID
>             eventID = eventID + last_stored_eventID;
>             newtree_singles->Fill();
>         }
>         newtree_singles->AutoSave();
> 
>         //set latest event_ID and clone sinograms
>         TH1F * oldH1_latest_eventID = (TH1F*)oldfile->Get("latest_event_ID");
>         TH1F * newH1_latest_eventID = (TH1F*)oldH1_latest_eventID->Clone();
> 
>         Int_t latest_eventID = oldH1_latest_eventID->GetMean() + last_stored_eventID;
>         newH1_latest_eventID->Fill(latest_eventID);
>         newH1_latest_eventID->Write("",TObject::kOverwrite);
>         //update he sum of event_IDs
>         last_stored_eventID = last_stored_eventID + oldH1_latest_eventID->GetMean();
> 
>         delete oldfile;
>         delete newfile;
>       }
>     }

Rather

TTree *newtree_singles = oldtree_singles->CloneTree(-1, "fast");

which ask to also clone all the entries, do

TTree *newtree_singles = oldtree_singles->CloneTree(0);

Cheers,
Philippe.

1 Like

Thank you! Now it works for the tree but it does the same thing for the histogram:

    // clone histogram
        TH1F * oldH1_latest_eventID = (TH1F*)oldfile->Get("latest_event_ID");
        TH1F * newH1_latest_eventID = (TH1F*)oldH1_latest_eventID->Clone();
        //TH1F * newH1_latest_eventID= new TH1F("latest_event_ID", "latest_event_ID", 1, 0, 1);
        //modify latest event_ID
        Int_t latest_eventID = oldH1_latest_eventID->GetMean() + last_stored_eventID;
        //fill the new histogram and save it
        newH1_latest_eventID->Fill(latest_eventID);
        newfile->cd();
        newH1_latest_eventID->Write();

The histogram is refilled while I want it to be replaced. Could you please have a look at it?

Cheers,
Parisa

Try

TH1F * newH1_latest_eventID = (TH1F*)oldH1_latest_eventID->Clone();
newH1_latest_eventID->Reset();

since (of course) Clone copies the data …

Cheers,
Philippe.