#[derive(ReadFromTree)]
{
// Attributes available to this derive:
#[oxyroot]
}
Available on crate feature
derive
only.Expand description
Derive macro available if oxyroot is built with features = ["derive"]
.
Derive macro in order to read struct data from TTree. Branch names and types are deduced from fields.
§Basic usage
use oxyroot::{ReadFromTree, RootFile};
#[derive(ReadFromTree)]
struct MyStruct {
a: i32, // will be read from branch "a" as 32 bits integer
s: String, // will be read from branch "s" as String
}
let tree = RootFile::open("in.root").unwrap().get_tree("tree").unwrap();
MyStruct::from_tree(&tree).unwrap().map(|m: MyStruct | { /* do something with m */ });
§Nested structures
use oxyroot::{ReadFromTree, RootFile};
#[derive(ReadFromTree)]
struct NestedStruct {
a: i32, // will be read from branch "s.a" as 32 bits integer
s: String, // will be read from branch "s.s" as String
}
#[derive(ReadFromTree)]
struct MyStruct {
s: NestedStruct, // will be constructed from branch "s.a" and "s.s"
i: i32, // will be read from branch "i" as 32 bits integer
}
let tree = RootFile::open("in.root").unwrap().get_tree("tree").unwrap();
MyStruct::from_tree(&tree).unwrap().map(|m: MyStruct | { /* do something with m */ });
§Customisation
This macro can be customized with the following attributes:
- By using attribute
#[oxyroot(rename = "...")]
, it is possible to use different branch name:
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
struct MyStruct {
#[oxyroot(rename = "b")]
a: i32, // will be read from branch *"b"* as 32 bits integer
s: String, // will be read from branch "s" as String
}
- By using attribute
#[oxyroot(branch_prefix = "...")]
directly on the struct, it is possible to globally (i.e. for all fields) prefix all branch names:
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
#[oxyroot(branch_prefix = "branch_")]
struct MyStruct {
a: i32, // will be read from branch *"branch_a"* as 32 bits integer
s: String, // will be read from branch *"branch_s"* as String
}
- By using attribute
#[oxyroot(branch_prefix = "...")]
on a field, it is possible to locally prefix branch name:
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
struct MyStruct {
a: i32, // will be read from branch *"a"* as 32 bits integer
#[oxyroot(branch_prefix = "branch_")]
s: String, // will be read from branch *"branch_s"* as String
}
- By using attribute
#[oxyroot(absolute_name = "...")]
on a field, it is possible to precisely set the branch name, even in a nested struct:
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
struct MyStruct {
a: i32, // will be read from branch *"a"* as 32 bits integer
#[oxyroot(absolute_name = "branch_s")]
s: String, // will be read from branch *"branch_s"* as String
}
- In combination with
#[oxyroot(branch_prefix = "...")]
:
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
#[oxyroot(branch_prefix = "branch_")]
struct MyStruct {
a: i32, // will be read from branch *"branch_a"* as 32 bits integer
c: f64, // will be read from branch *"branch_c"* as 64 bits float
#[oxyroot(absolute_name = "zweig_s")]
s: String, // will be read from branch *"zweig_s"* as String
}
- Use
#[oxyroot(slicable)]
if the C++ class has astd::vector
as a member.
use oxyroot::ReadFromTree;
#[derive(ReadFromTree)]
#[oxyroot(slicable)]
struct Point {
x: i32, // will be read from branch "points.x" as 32 bits integer
y: i32, // will be read from branch "points.y" as 32 bits integer
}
#[derive(ReadFromTree)]
struct SeveralPoints {
#[oxyroot(slicable = "Point")]
points: Vec<Point>, // will be read from branches "points.x" and "points.y" as a vector of
// Point
}
This combinaison can be used to read TTree
created from C++ classes like:
class Point {
public:
int x = 0;
int y = 0;
};
class SeveralPoints {
public:
std::vector<Point> points;
};
TTree *myTree = new TTree("myTree", "");
SeveralPoints tp;
for (int i = 0; i < 10; ++i)
{
Point p;
p.x = i;
p.y = i*i;
tp.points.push_back(p);
myTree->Fill();
}