Saving Tree branches as doubles

Greetings Root’rs

All of my macros save branches of the type Float_t. I would like to change this to Double_t.
When I perform this change and analyze the data I get values of 0. For instance changing

  Float_t P_p;
  t4->Branch("P_p",&P_p,"P_p/F");   
...
...
<Calcualtion of P_p>
t4->Fill();
t4->Write();

to

  Double_t P_p;
  t4->Branch("P_p",&P_p,"P_p/D");   
...
...
<Calcualtion of P_p>
t4->Fill();
t4->Write();

Get values of 0 for the Tree with Double_t and non-zero values for the Tree of Float_t.

Why is this?

Thanks
Michael

Hi,

This should have worked … However the indentation in the post leads me to believe that the lifetime of the variable might not be right. I.e. the lifetime/scope of ‘P_p’ must be such that )P_p is still defined when t4->Fill is called. If this is not the problem, we would need a complete running example showing the problem in order to determine what the issue is.

Philippe.

Greetings,

Here is a sample of my code:

[code]#include “TROOT.h”
#include “TRint.h”
#include “TH1F.h”
#include “TCanvas.h”
#include “TChain.h”

#include “TVector3.h”
#include “TMath.h”
#include “TFile.h”
#include “TSystem.h”
#include “TGStatusBar.h”
#include “TSystem.h”
#include “TXMLEngine.h”
#include “TTree.h”
#include “TLorentzVector.h”
#include “TNtuple.h”
#include
#include
#include
#include
#include
#include

void shortest_check(){

TChain *chain = new TChain(“Lep”);

chain->Add("/Volumes/Mac_Storage/Work_Data/ANALYSIS_DATA/Lepton_Gamcor.root");

Int_t nEvent = chain->GetEntries();

std::cout <<"Number of events " <<nEvent <<std::endl;

TFile f("/Volumes/Mac_Storage/Work_Data/ANALYSIS_DATA/shortest.root",“recreate”);
//########################################### BEGIN INCOMING DATA ###############################################################
//----------------------------------------------------For Proton-------------------------------------------------------------------
Double_t P_Ptot, P_Px, P_Py, P_Pz, P_vx, P_vy, P_vz;
Int_t NProton;

chain->SetBranchAddress(“NProton”,&NProton);
chain->SetBranchAddress(“P_Ptot”,&P_Ptot);
chain->SetBranchAddress(“P_Px”, &P_Px);
chain->SetBranchAddress(“P_Py”, &P_Py);
chain->SetBranchAddress(“P_Pz”, &P_Pz);

chain->SetBranchAddress(“P_vx”, &P_vx);
chain->SetBranchAddress(“P_vy”, &P_vy);
chain->SetBranchAddress(“P_vz”, &P_vz);

//########################################### BEGIN OUTGOING DATA ###############################################################

TTree *t4 = new TTree(“Lep_Tree”,“Lep_Tree”);

//----------------------------------------------------For Proton -------------------------------------------------------------------

Int_t NProt;
Double_t P_px, P_py, P_pz, P_p;
Double_t P_pxfloat, P_pyfloat, P_pzfloat, P_pfloat;

t4->Branch(“NProt”,&NProt,“NProt/I”);

t4->Branch(“P_p”,&P_p,“P_p/D”);
t4->Branch(“P_px”,&P_px,“P_px/D”);
t4->Branch(“P_py”,&P_py,“P_py/D”);
t4->Branch(“P_pz”,&P_pz,“P_pz/D”);

t4->Branch(“P_pfloat”,&P_pfloat,“P_pfloat/F”);
t4->Branch(“P_pxfloat”,&P_pxfloat,“P_pxfloat/F”);
t4->Branch(“P_pyfloat”,&P_pyfloat,“P_pyfloat/F”);
t4->Branch(“P_pzfloat”,&P_pzfloat,“P_pzfloat/F”);

for( Int_t i = 0; i < nEvent ; i++){

chain->GetEntry(i); 

if(!(i%100000)) std::cout << "done " << i << " out of " << nEvent << " ==> " << double(i)*100.0/double(nEvent) << "%" << std::endl;


P_p = P_Ptot;
P_px = P_Px;
P_py = P_Py;
P_pz = P_Pz;

P_pfloat = P_Ptot;
P_pxfloat = P_Px;
P_pyfloat = P_Py;
P_pzfloat = P_Pz;
	
    
NProt = NProton;
	
t4 ->Fill();

}
//########################################### END OUTGOING DATA ###############################################################

t4->Write();
f.Close();
}

[/code]

I have uploaded a plot of the P_pxfloat and P_px varible, the blue is of the float type and the red is of the double type.
Hope this clarifies my problem.

Thanks
Michael


A stupid idea … tryvolatile Double_t P_Ptot, P_Px, P_Py, P_Pz, P_vx, P_vy, P_vz; // ... volatile Double_t P_px, P_py, P_pz, P_p;

[quote=“Pepe Le Pew”]A stupid idea … tryvolatile Double_t P_Ptot, P_Px, P_Py, P_Pz, P_vx, P_vy, P_vz; // ... volatile Double_t P_px, P_py, P_pz, P_p;[/quote]

Using volatile makes the macro not compilable

Processing shortest_check.C+...
Info in <TUnixSystem::ACLiC>: creating shared library /Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check_C.so
In file included from /Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/shortest_check_C_ACLiC_dict.h:34,
                 from /Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/shortest_check_C_ACLiC_dict.cxx:17:
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C: In function 'void shortest_check()':
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:43: error: invalid conversion from 'volatile void*' to 'void*'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:43: error:   initializing argument 2 of 'virtual Int_t TChain::SetBranchAddress(const char*, void*, TBranch**)'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:44: error: invalid conversion from 'volatile void*' to 'void*'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:44: error:   initializing argument 2 of 'virtual Int_t TChain::SetBranchAddress(const char*, void*, TBranch**)'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:45: error: invalid conversion from 'volatile void*' to 'void*'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:45: error:   initializing argument 2 of 'virtual Int_t TChain::SetBranchAddress(const char*, void*, TBranch**)'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:46: error: invalid conversion from 'volatile void*' to 'void*'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:46: error:   initializing argument 2 of 'virtual Int_t TChain::SetBranchAddress(const char*, void*, TBranch**)'
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:62: error: call of overloaded 'Branch(const char [4], volatile Double_t*, const char [6])' is ambiguous
/Users/Mike/root/include/TTree.h:285: note: candidates are: virtual Int_t TTree::Branch(const char*, Int_t, Int_t) <near match>
/Users/Mike/root/include/TTree.h:286: note:                 virtual TBranch* TTree::Branch(const char*, void*, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:292: note:                 TBranch* TTree::Branch(const char*, long int, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:297: note:                 TBranch* TTree::Branch(const char*, int, const char*, Int_t) <near match>
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:63: error: call of overloaded 'Branch(const char [5], volatile Double_t*, const char [7])' is ambiguous
/Users/Mike/root/include/TTree.h:285: note: candidates are: virtual Int_t TTree::Branch(const char*, Int_t, Int_t) <near match>
/Users/Mike/root/include/TTree.h:286: note:                 virtual TBranch* TTree::Branch(const char*, void*, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:292: note:                 TBranch* TTree::Branch(const char*, long int, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:297: note:                 TBranch* TTree::Branch(const char*, int, const char*, Int_t) <near match>
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:64: error: call of overloaded 'Branch(const char [5], volatile Double_t*, const char [7])' is ambiguous
/Users/Mike/root/include/TTree.h:285: note: candidates are: virtual Int_t TTree::Branch(const char*, Int_t, Int_t) <near match>
/Users/Mike/root/include/TTree.h:286: note:                 virtual TBranch* TTree::Branch(const char*, void*, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:292: note:                 TBranch* TTree::Branch(const char*, long int, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:297: note:                 TBranch* TTree::Branch(const char*, int, const char*, Int_t) <near match>
/Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/./shortest_check.C:65: error: call of overloaded 'Branch(const char [5], volatile Double_t*, const char [7])' is ambiguous
/Users/Mike/root/include/TTree.h:285: note: candidates are: virtual Int_t TTree::Branch(const char*, Int_t, Int_t) <near match>
/Users/Mike/root/include/TTree.h:286: note:                 virtual TBranch* TTree::Branch(const char*, void*, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:292: note:                 TBranch* TTree::Branch(const char*, long int, const char*, Int_t) <near match>
/Users/Mike/root/include/TTree.h:297: note:                 TBranch* TTree::Branch(const char*, int, const char*, Int_t) <near match>
i686-apple-darwin11-llvm-g++-4.2: /Volumes/Mac_Storage/Work_Codes/Dalitz_Codes/Analysis_Codes/shortest_check_C_ACLiC_dict.o: No such file or directory
Error in <ACLiC>: Compilation failed!

An improved stupid idea … tryDouble_t P_Px, P_Py, P_Pz, P_vx, P_vy, P_vz; volatile Double_t P_Ptot; // ... chain->SetBranchAddress("P_Ptot",((Double_t*)(&P_Ptot))); // ... Double_t P_px, P_py, P_pz; volatile Double_t P_p; // ... t4->Branch("P_p",((Double_t*)(&P_p)),"P_p/D");

[quote=“Pepe Le Pew”]An improved stupid idea … tryDouble_t P_Px, P_Py, P_Pz, P_vx, P_vy, P_vz; volatile Double_t P_Ptot; // ... chain->SetBranchAddress("P_Ptot",((Double_t*)(&P_Ptot))); // ... Double_t P_px, P_py, P_pz; volatile Double_t P_p; // ... t4->Branch("P_p",((Double_t*)(&P_p)),"P_p/D");[/quote]

It compilable now, however original problem still exists.

Well, I was thinking that that might be the compiler which optimized-out that assignment “P_p = P_Ptot;” (but then you should have the same problems with “P_px”, “P_py” and “P_pz” branches).
But if it behaves the same with “volatile” then it shouldn’t be this problem, sorry.

Hi,

I see [code] Double_t P_px, P_py, P_pz, P_p;
t4->Branch(“P_p”,&P_p,“P_p/D”);
t4->Branch(“P_px”,&P_px,“P_px/D”);
t4->Branch(“P_py”,&P_py,“P_py/D”);
t4->Branch(“P_pz”,&P_pz,“P_pz/D”);

Double_t P_pxfloat, P_pyfloat, P_pzfloat, P_pfloat;
t4->Branch(“P_pfloat”,&P_pfloat,“P_pfloat/F”);
t4->Branch(“P_pxfloat”,&P_pxfloat,“P_pxfloat/F”);
t4->Branch(“P_pyfloat”,&P_pyfloat,“P_pyfloat/F”);
t4->Branch(“P_pzfloat”,&P_pzfloat,“P_pzfloat/F”);[/code]Where the TTree is request to read/use a double variable as a float and thus I would expect the float information (P_pxfloat) to be incorrect in the file and the double information to be correct.

Cheers,
Philippe.

I believe I have found the problem,
The TTree being read is actually of type float and I had assigned the variables as doubles.
If I now change to :[code]
Float_t P_Px, P_Py, P_Pz; //CHANGED TO TYPE FLOAT_T
Float_t P_Ptot; //CHANGED TO TYPE FLOAT_T
chain->SetBranchAddress(“P_Ptot”,&P_Ptot);
chain->SetBranchAddress(“P_Px”, &P_Px);
chain->SetBranchAddress(“P_Py”, &P_Py);
chain->SetBranchAddress(“P_Pz”, &P_Pz);

Double_t P_px, P_py, P_pz;
Double_t P_p;

Float_t P_pxfloat, P_pyfloat, P_pzfloat, P_pfloat;

t4->Branch(“P_p”,&P_p,“P_p/D”);
t4->Branch(“P_px”,&P_px,“P_px/D”);
t4->Branch(“P_py”,&P_py,“P_py/D”);
t4->Branch(“P_pz”,&P_pz,“P_pz/D”);

t4->Branch(“P_pfloat”,&P_pfloat,“P_pfloat/F”);
t4->Branch(“P_pxfloat”,&P_pxfloat,“P_pxfloat/F”);
t4->Branch(“P_pyfloat”,&P_pyfloat,“P_pyfloat/F”);
t4->Branch(“P_pzfloat”,&P_pzfloat,“P_pzfloat/F”);[/code]

Then both the double and the float are stored in t4 correctly.
I don’t understand the issue with calling a tree variable as a double, but it worked.