Writing a TString into a TTree

Hi everyone!

I have a problem filling a TString into a TTree. My code compiles, however, when I open my root file, I get the following:

where some weird C++ information is filled into the TTree. Do you happen to know what the issue could be? I have gone through the ROOT forum and tried filling a TTstring as std::string etc. but it did not work out.

PS: would be happy to share my code, if needed.

Thanks!

Best,
Vasily

Hi,

@pcanal could help you on this, but you should share the code first, so we can understand better the issue

Best regards

Lorenzo

Hi Lorenzo, thanks so much for the prompt reply!

So, in my HistoManager.hh header file (Geant4), I define a structure:

struct TreeInfo{
	TTree*                  tree;
	G4String                Label;
	G4String                Title;
	G4bool                  exist;
	double                  rndmSeed;
	double                  evtNumber;
	TString           particleName;
	double                  x;
	double                  y;
	double                  z;
	double                  px;
	double                  py;
	double                  pz;
	double                  trackID;
	double                  parentID;
	bool                    isIncident;
	bool                    isExit;
	double                  kineticEnergy;
	double                  edep;
	double                  niel;
	double                  pdgid;
	double                  charge;
	double                  processType;
};

Also ,I define

void SetHisto (const G4String& label, const G4String& title, G4int,G4double,G4double,const G4String& unit="none");
void FillHisto(const G4String& label, G4double e, G4double weight = 1.0);

functions as well as a a vector

std::vector<TreeInfo>    treeInfo;

In my HistoManager.cc source file, the order is the following: first, trees/histograms are set, then booked, and finally filled.

SetTree method:

void HistoManager::SetTree(const G4String& label, const G4String& title)
{
	for(unsigned i=0; i<treeInfo.size(); i++)
	{
		if( label == treeInfo[i].Label )
		{
			G4cout << "---> warning from HistoManager::SetTree() : tree " << treeInfo[i].Label
           << "already exists" << G4endl;
			return;
		}
	}
	
	TreeInfo ti;
	ti.Label = label;
	ti.Title = title;
	ti.exist = true;
	treeInfo.push_back(ti);
}

Book method:

void HistoManager::book()
{
...
for(G4int k=0; k<int(treeInfo.size()); k++) {
		if(treeInfo[k].exist) {
			treeInfo[k].tree = new TTree(treeInfo[k].Label, treeInfo[k].Title);
			treeInfo[k].tree -> Branch( "rndmSeed", &treeInfo[k].rndmSeed);
			treeInfo[k].tree -> Branch( "evtNumber" , &treeInfo[k].evtNumber );
			treeInfo[k].tree -> Branch( "particleName", &treeInfo[k].particleName);
			treeInfo[k].tree -> Branch( "x", &treeInfo[k].x);
			treeInfo[k].tree -> Branch( "y", &treeInfo[k].y);
			treeInfo[k].tree -> Branch( "z", &treeInfo[k].z);
			treeInfo[k].tree -> Branch( "px", &treeInfo[k].px);
			treeInfo[k].tree -> Branch( "py", &treeInfo[k].py);
			treeInfo[k].tree -> Branch( "pz", &treeInfo[k].pz);
			treeInfo[k].tree -> Branch( "trackID", &treeInfo[k].trackID);
			treeInfo[k].tree -> Branch( "parentID", &treeInfo[k].parentID);
			treeInfo[k].tree -> Branch( "isIncident", &treeInfo[k].isIncident);
			treeInfo[k].tree -> Branch( "isExit", &treeInfo[k].isExit);
			treeInfo[k].tree -> Branch( "kineticEnergy", &treeInfo[k].kineticEnergy);
			treeInfo[k].tree -> Branch( "edep", &treeInfo[k].edep );
			treeInfo[k].tree -> Branch( "niel", &treeInfo[k].niel);
			treeInfo[k].tree -> Branch( "pdgid", &treeInfo[k].pdgid);
			treeInfo[k].tree -> Branch( "charge", &treeInfo[k].charge);
			treeInfo[k].tree -> Branch( "processSubType", &treeInfo[k].processType);
		}
	}
...
}

And FillTree method:

void HistoManager::FillTree(const G4String& label, G4double rndmSeed, G4double evtNumber, TString particleName,
									G4double x, G4double y, G4double z, 
								  G4double px, G4double py, G4double pz, 
								  G4double trackID, G4double parentID, 
									bool isIncident, bool isExit,
								  G4double kineticEnergy, G4double edep, G4double niel,
									G4double pdgid, G4double charge, G4int processSubType)
{
	G4int ih = GetTreeAddress(label);
	
	if (ih < 0) {
    G4cout << "---> warning from HistoManager::FillTree() : tree " << ih
           << "does not exist;" << G4endl;
    return;
  }
  

  if(treeInfo[ih].exist) 
	{
		treeInfo[ih].rndmSeed = rndmSeed;
		treeInfo[ih].evtNumber = evtNumber;
		treeInfo[ih].particleName=particleName;
		treeInfo[ih].x = x;
		treeInfo[ih].y = y;
		treeInfo[ih].z = z;
		treeInfo[ih].px = px;
		treeInfo[ih].py = py;
		treeInfo[ih].pz = pz;
		treeInfo[ih].trackID = trackID;
		treeInfo[ih].parentID = parentID;
		treeInfo[ih].isIncident = isIncident;
		treeInfo[ih].isExit = isExit;
		treeInfo[ih].kineticEnergy = kineticEnergy;
		treeInfo[ih].edep = edep;
		treeInfo[ih].niel = niel;
		treeInfo[ih].pdgid = pdgid;
		treeInfo[ih].charge = charge;
		treeInfo[ih].processType = double(processSubType);
	}
 
 treeInfo[ih].tree->Fill();
	
}

Then I set a tree in my RunAction.cc file and fill in my SteppingAction.cc file. Just in case, I also convert G4String into TString:

	G4String definition     = part->GetDefinition()->GetParticleName();
	TString str_def = definition;

But after all of that I get the aforementioned strange TTree filling for my particle names…

Hope it will help!

Hi,
Thank you for sharing the code, but what is exactly the problem ? Is the string not available in the Tree ? It is not clear to me form just the snapshot of the image

Lorenzo

Hi Lorenzo,
So, yes. It is available but it doesn’t contain a list of particle names. Instead, when I click on it (for some reason it also has a different logo than other variables), it is filled by some strange function with red exclamation signs.

I am confused.

Cheers,
Vasily

Hi,
The TString is a C++ object and you see all the data members in the TBrowser. If you want to see the actual content, you should look at the Data() leaf. Is it showing the correct content ?

Hi Lorenzo,

No, unfortunately, it is empty. I just get all the data members with red exclamation marks.

Vasily

@pcanal Hi! I was told you could be aware of how I may fix the issue. Do you happen to have any ideas? Thanks!!!

{
  const char *n = "trial.root";
  TFile *f;
  TTree *t;
  TString s, *p;
  // create and fill the tree
  f = TFile::Open(n, "recreate");
  t = new TTree("t", "t");
  t->Branch("s", &s);
  for (Int_t i = 0; i < 10; i++) { s.Form("_%d_", i); t->Fill(); }
  t->Write();
  t->Print(); t->Scan(); // () or ("*") or ("s") or ("s.Data()")
  delete f; // automatically deletes t, too
  // retrieve and dump the tree
  f = TFile::Open(n, "read");
  f->GetObject("t", t);
  t->Print(); t->Scan(); // () or ("*") or ("s") or ("s.Data()")
  p = 0; // make sure it is initialized
  t->SetBranchAddress("s", &p);
  for (Int_t i = 0; i < t->GetEntries(); i++) {
    t->GetEntry(i);
	std::cout << i << " : " << *p << std::endl;
  }
  delete f; // automatically deletes t, too
  delete p; // cleanup
}

Hi @Wile_E_Coyote !
Thanks for the reply! Am I right that the data may have been written to my tree but I need to access it in the way that you’ve described?

Also, could you please tell me what the following does:

s.Form("_%d_", i); 

Thanks!
Vasily

TString::Form

1 Like

Hi Wile,
Thanks a lot for the suggestion!

I have tried to fill a TTree after formatting a TString but I still get red exclamation marks on the leaf logo when I open TBrowser. Does it mean you cannot visualize a TBranch filled by TString in the TBrowser?

Thanks!
Vasily

It works when I read it with a macro, thanks again!

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