Clone a tree without CloneTree

Hello, I need to copy some branches from an input tree and an output tree only for events passing my selection. I don’t think I can use the CloneTree(0) because I need to add the branches to an existing TTree which has its own branches.

I’m doing something like this:

vector<string> branch_names;
branch_names.push_back("Npv");
branch_names.push_back("jet_AntiKt4TopoEMJets_flavor_weight_JetFitterCOMBNN");
for (unsigned int i=0; i!=branch_names.size(); ++i)
    {
	const char* b = branch_names[i].c_str();
	TBranch* branch = fChain->GetBranch(b);
	if (string(branch->GetClassName()) == "")
	{
	    output_tree->Branch(b,
				fChain->GetBranch(b)->GetAddress());
	}
	else 
	{
          output_tree->Branch(b,
				branch->GetClassName(),
				(void*) fChain->GetBranch(b)->GetAddress());
	}
    }

in particular Npv is a Float_t and jet_AntiKt4TopoEMJets_flavor_weight_JetFitterCOMBNN is a vector. I’m reading the input file using the MakeClass so the variables are:

vector<float>   *jet_AntiKt4TopoEMJets_flavor_weight_JetFitterCOMBNN;
Int_t           Npv;

is it ok? Is there a better solution? It works with a single TTree, will it work with TChain?

Hi,

You can also add branches to the result of CloneTree(0).

Cheers,
Philippe.

[quote=“pcanal”]Hi,

You can also add branches to the result of CloneTree(0).

Cheers,
Philippe.[/quote]

unfortunately not in my case. I mean, I’ve a lot of sub-algorithms, and the order of execution is not predicible

Hi,

[quote] It works with a single TTree, will it work with TChain?[/quote]With a TChain the challenge is that the branch ‘address’ can and will change from TTree to TTree unless they have been fixed by a call to TChain::SetBranchAddress.

Philippe.

[quote=“pcanal”]Hi,

[quote] It works with a single TTree, will it work with TChain?[/quote]With a TChain the challenge is that the branch ‘address’ can and will change from TTree to TTree unless they have been fixed by a call to TChain::SetBranchAddress.

Philippe.[/quote]

yes, ok, but what about the code. Sometimes it works, sometimes not. The problem is that GetAddress return void* so how to distinguish between the various type? I’ve changed to

for (vector<string>::const_iterator it = m_branchnames_list.begin();
      it != m_branchnames_list.end(); ++it)
    {
	TBranch* branch = input_tree->GetBranch(it->c_str());
	assert(branch);
	if (string(branch->GetClassName()) == "") {
	    string id = input_tree->GetLeaf(it->c_str())->GetTypeName();
	    if (id == "Char_t") id = "B";
	    else if (id == "UChar_t") id = "b";
	    else if (id == "Short_t") id = "S";
	    else if (id == "UShort_t") id = "s";
	    else if (id == "Int_t") id = "I";
	    else if (id == "UInt_t") id = "i";
	    else if (id == "Float_t") id = "F";
	    else if (id == "Double_t") id = "D";
	    else if (id == "Long64_t") id = "L";
	    else if (id == "ULong64_t") id = "l";
	    else if (id == "Bool_t") id = "O";
	    else {
		cout << "cannot translate " << id << endl;
		assert(false);
	    }
	    output_tree->Branch(it->c_str(),
				branch->GetAddress(),
				(branch->GetName() + string("/") + id).c_str());
	}
	else {
	    output_tree->Branch(it->c_str(),
				branch->GetClassName(),
				(void*) branch->GetAddress());
	}
    }

it seems quite stupid/verbose.

HI,

For the leave list case, I think the branch description is store in the branch title (see branch->GetTitle()) …

Philippe.

[quote=“pcanal”]HI,

For the leave list case, I think the branch description is store in the branch title (see branch->GetTitle()) …

Philippe.[/quote]

only sometimes and I don’t understand why. For example sometime some title are: “thebranch/F”, but sometimes only “thebranch”

Hi,

The other might have been created not with a leaf list but with an object (in which case GetClassName would be returning the needed information).

Philippe.

[quote=“pcanal”]Hi,

The other might have been created not with a leaf list but with an object (in which case GetClassName would be returning the needed information).

Philippe.[/quote]

Yes, this is what I’m doing, but it seems really complicated even if what I have to do is really simple. Is there no a better solution?

Hi,

Well … You could try to Clone the Branch and add it to the list of branches … really the ‘simple’ solution is supposed to be calling CloneTree …

Philippe.