See tree106_tree.C for the same example using a class with dictionary instead of a C-struct.
In this example, we are mapping a C struct to one of the Geant3 common blocks /gctrak/. In the real life, this common will be filled by Geant3 at each step and only the Tree Fill function should be called. The example emulates the Geant3 step routines.
typedef struct {
} Gctrak_t;
{
enum Evect {kX, kY, kZ, kPX, kPY, kPZ, kPP};
vout[kPP] = vect[kPP];
vout[kX] = vect[kX] + (
f1*vect[kPX] - f2*vect[kPY]);
vout[kY] = vect[kY] + (
f1*vect[kPY] + f2*vect[kPX]);
vout[kZ] = vect[kZ] + (
f1*vect[kPZ] + f3);
vout[kPX] = vect[kPX] + (f4*vect[kPX] - f5*vect[kPY]);
vout[kPY] = vect[kPY] + (f4*vect[kPY] + f5*vect[kPX]);
vout[kPZ] = vect[kPZ] + (f4*vect[kPZ] + f6);
}
void tree105_write()
{
TFile f(
"tree105.root",
"recreate");
TTree t2(
"t2",
"a Tree with data from a fake Geant3");
Gctrak_t gstep;
t2.Branch("vect", gstep.vect, "vect[7]/F");
t2.Branch("getot", &gstep.getot);
t2.Branch("gekin", &gstep.gekin);
t2.Branch("nmec", &gstep.nmec);
t2.Branch("lmec", gstep.lmec, "lmec[nmec]/I");
t2.Branch("destep", &gstep.destep);
t2.Branch("pid", &gstep.pid);
gstep.step = 0.1;
gstep.destep = 0;
gstep.nmec = 0;
gstep.pid = 0;
for (
Int_t i=0; i<10000; i++) {
if (newParticle) {
charge = 1;
charge = -1;
gstep.pid += 1;
gstep.vect[0] = 0;
gstep.vect[1] = 0;
gstep.vect[2] = 0;
gstep.vect[3] = px / p;
gstep.vect[4] = py / p;
gstep.vect[5] = pz / p;
gstep.vect[6] = p * charge;
gstep.gekin = gstep.getot - mass;
}
t2.Fill();
helixStep(gstep.step, gstep.vect, vout);
gstep.destep = gstep.step*
gRandom->Gaus(0.0002, 0.00001);
gstep.gekin -= gstep.destep;
gstep.getot = gstep.gekin + mass;
gstep.vect[6] = charge*
TMath::Sqrt(gstep.getot * gstep.getot - mass * mass);
gstep.vect[0] = vout[0];
gstep.vect[1] = vout[1];
gstep.vect[2] = vout[2];
gstep.vect[3] = vout[3];
gstep.vect[4] = vout[4];
gstep.vect[5] = vout[5];
if (gstep.gekin < 0.001)
}
t2.Write();
}
void tree105_read()
{
auto t2 =
f->Get<
TTree>(
"t2");
TBranch *b_destep = t2->GetBranch(
"destep");
auto hdestep =
new TH1F(
"hdestep",
"destep in Mev", 100, 1
e-5, 3
e-5);
hdestep->Fill(destep);
}
hdestep->SetFillColor(45);
hdestep->Fit("gaus");
t2->SetMarkerColor(
kRed);
t2->Draw("vect[0]:vect[1]:vect[2]");
t2->ResetBranchAddresses();
}
void tree105_tree()
{
tree105_write();
tree105_read();
}
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
long long Long64_t
Portable signed long integer 8 bytes.
float Float_t
Float 4 bytes (float).
A TTree is a list of TBranches.
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
virtual void SetAddress(void *add)
Set address of this branch.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
1-D histogram with a float per channel (see TH1 documentation)
A TTree represents a columnar dataset.
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.