Wrong Special Characters in ROOT file

Hello,

I am creating a root file using Geant4 (10.04) and ROOT 6.14. The histograms of volume name (name of the shape of the detector model) and ptype (particle type, e.g., electron, neutron, etc.) show weird Special Characters (instead of the real volume name provided in geant4). The volume name looks fine on terminal window when the code executes, it is just the generated root file that displays weird special characters.

Other histogram which have numeric characters instead of alphabets are fine in the root file. These codes worked fine when I was using Mac but I see the special characters in Ubuntu. I would appreciate any suggestions as I am just a beginner.

Thanks,
Manish


ROOT Version: 6.14
Platform: Ubuntu 18.04
Compiler: Not Provided


Can it be that you use non-ASCII characters in these names?

Show some examples here (what you set and what you get).

Hi Wile,

Thanks for your reply. Here is what I have set in Geant4:
G4Tubs* scint_shape = new G4Tubs("NaI_Scint", 0*cm,radius*cm, radius*cm, 0.0*deg, 360.*deg);

Where “NaI_Scint” is volume name, which is displayed correctly on terminal window with notification: “Checking overlaps for volume NaI_Scint … OK!”

However, it s shown as x^3 in the simulated root file (attached, see volname). Of course I tried changing NaI_Scint to just NaI, but the name was displayed wrong here as well. These codes were working fine on Mac, just giving me hard time on Ubuntu!

build.root (8.5 KB)

This hinders me in analyzing the root file. Please let me know if you have any suggestions.

You need to inspect how you define the “MC_out” tree, in particular its “ptype” and “volumeName” branches.

Try to run “MC_out->MakeClass();” and then see the “MC_out.h” file. You will find "Char_t ptype[5]; and Char_t volumeName[5];, which means that your names can be 4 characters long at most (plus the null character which ends the string, of course, hence at most 5 characters in total).

Moreover, you should also inspect the place where you fill these branches as it seems to me that they use uninitialized variables.

Note also that the “NaI_Scint” in the “G4Tubs” call is actually converted into a “G4String” which is basically a “std:string” (NOT a “char *”).

So, I inspected the way volumeName is filled in my code:
// ================
G4String VolName=aStep->GetPreStepPoint()->GetTouchableHandle()
->GetVolume()->GetName();

myRunAction->SetVolumeName(VolName);
// ============

Just now I used: “G4cout<<VolName<<G4endl;” right after above steps and the VolName is displayed fine on terminal window.

Your “VolName” is a “G4String” (so basically a “C++ std::string”). It is NOT a C character string / sequence / array.

Note: you need to check how you define and fill the branches of your tree, not how you feed geant4.

Thanks! I looked into what you mentioned and here it is:

fData->Branch(“volumeName”,&fvname,“volumeName/C”);

So it’s maybe because of “/C”

Do you recommend any way of handling this when something is expressed in G4 string and we are interested in creating a tree-branch?

And surprisingly this was not the issue on MAC OS!

And “fvname” is what?

Here:

G4String fvname;

Try: fData->Branch("volumeName", &fvname);

After I include what you mentioned, I do not see any branch with name “volumeName”

When I do MC_out->Scan(“ptype:volumeName”), I just see an empty volumeName column!

And how do you set the “fvname” value (before you fill the tree)?

inline void SetVolumeName(G4String daname){fvname=daname;}

Try to use: std::string fvname;
And if after this change your compiler complains, use: {fvname=daname.data();} (or: {fvname=daname.c_str();}).

Here are two things I tried, both gave special characters in the end.:

std::string  fvname;
inline void SetVolumeName(std::string daname){fvname=daname;}

OR
std::string fvname;
inline void SetVolumeName(std::string daname){fvname=daname.c_str();}

Both of these runs gave my special characters! Am i doing something wrong with compilation process or something?

Attach a new small root file.

I assume you use:

std::string fvname;
fData->Branch("volumeName", &fvname);
inline void SetVolumeName(const G4String &daname) { fvname = daname.c_str(); }

It worked actually ; I was messing up somewhere.

Thanks, I appreciate it a lot.

One of the things I noticed, however, is the way volumeName branch is different from the other branches. The data is visible in data() under volumeName.

My goal now is to analyze this root file and determine which events were in that volume (NaI). For example, in my earlier analysis code that worked on MAC OS, I was setting:

#include "string"

Char_t   volumeName[15]; 
TBranch   *b_volumeName;   

fChain->SetBranchAddress("volumeName", volumeName, &b_volumeName);

if(volumeName[3]== 'I'){   // desired events happening in NaI
        // then execute this loop...     
 }  // if loop ends

I now tried updating Char_t volumeName[15] to string *volumeName; volumeName=0; and fChain->SetBranchAddress("volumeName", &volumeName, &b_volumeName); based on what I have seen in MC_out.h but what I should be using to execute something like the if loop above.

Do you have any suggestions?

build.root (9.1 KB)

std::string *volumeName = 0;
MC_out->SetBranchAddress("volumeName", &volumeName);

BTW. For an event loop example, see “MC_out.C”.

Thanks. I tried analyzing my root file and I am able to analyze other branches. For example:

if(pdgNum == 22){
… // Do this
}

The above works fine. However I am not able to access the data of volumeName. In theory I want to implement:

if(volumeName[3] == ‘I’ ){ // Events happening in NaI only
… // Do this
}

When I have two volumes (e.g., NaI, and EJ230), I am interested in events happenign in NaI only by using something like the above if loop.build.root (9.1 KB)

Indices in C / C++ start from 0, not 1 (at least “usually”).