Create Setup from ROOT geometry
RecPack has a root geometry interface which allows creating a RecPack setup from a root geometry file.
This interface is located under RecPack/recpack/root folder, which contains three classes
RootSetup, RootVolume and RootVirtualVolume.
RootSetup inherits from Setup and extends it with a TGeoManager and methods to build the RecPack geometry
as a subset of volumes from the more complex geometry in the TGeoManager. Basically the user has to specify which volumes
should be considered.
Two types of volumes can be added, real volumes, which are the exact representation of a volume in the TGeoManager,
and virtual volumes, which correspond to a box enclosing a list of specified real volumes in the TGeoManager. This box is built automatically
taking into account the properties (position, size and orientation) of the child volumes.
The instructions to select specific volumes
are given with the methods AddVolume and AddVirtualVolume. However the Setup is actually built only when the BuildSetup method is called, to avoid looping
over TGeoManager volumes many times.
The first thing we should do is create a RootSetup provided the TGeoManager and the setup name
RootSetup* setup = new RootSetup(fGeoManager,"MySetup");
where, fGeoManager is a pointer to the TGeoManager. Then we should set the mother volume:
setup->SetMother("mother_name");
Now instructions to add volumes can be given. The code below tells the RootSetup class that the lowest level volume containing "vol_name" in its name
should be added (not now but when calling BuildSetup() ):
setup->AddVolume("vol_name");
A second string can be provided. The instruction below tells the RootSetup class that the lowest level volume containing "vol_name1" and "vol_name2" simultaneously
should be added
setup->AddVolume("vol_name1","vol_name2");
And similarely with a third string:
setup->AddVolume("vol_name1","vol_name2","vol_name3");
Sometimes there is no real volume in the TGeoManager that represents the volume we need for the reconstruction. A typical example is a scintillator plane, composed
of many adjacent sctillator bars. In general we don't want any individual scintillator to have its own volume in RecPack since this would slow down the propagation
process. Instead a virtual box enclosing all scintillators in a plane can be added, with the appropriate average properties.
Adding virtual volumes is more complicated since one should specify how this volume is made. This is the method that should be used:
void AddVirtualVolume(
     const std::string& father_name, const std::string& virt_name,
     const std::vector< std::string >& volumes_to_include1, bool include_exclude1,
     const std::vector< std::string >& volumes_to_include2, bool include_exclude2
);
The arguments of that method have the following meaning:
We can also exlude volumes from the setup. The instruction below tells the setup to exluclude volumes containg the string "excluded_name" in its full name:
setup->ExcludeVolume("excluded_name");
Once instruction on how to build the setup are given with the AddVolume and AddVirtualVolume methods, the method BuildSetup() can be called to actually build the setup:
setup->BuildSetup();
You can now dump on the screen the setup:
std::cout << *setup << std::endl;
A typical problem that sometime arises is the overlap between volumes due to alignment. This can be solved by calling the method solve_overlaps. The code below check and solve overlaps smaller than 10 mm and leaving a tolerance of 0.01 mm:
setup->solve_overlaps(10*mm, 0.01*mm);
The volumes created with all above instructions are empty volumes, with no properties. Particles could be propagated on them and we could even do track fitting, but assuming vacum propagation with no magnetic field. This is not in general the situation. Extracting volume properties from the ROOT geometry and adding them to the RecPack volumes is very simple. The method below returns as argument the average radiation length, energy loss rate and electron number density for a volume (real or virtual) with full name vol_name:
void GetAverageProperties(
     const std::string& vol_name,
     double& X0_avg, double& dEdx_avg, double& nel_avg
);
In the method above all subvolumes are considered when calculating the average properties. Sometimes more precise instructions are needed because some subvolumes have to be included or excluded from the properties. A typical example is when certain subvolumes are very unlikely to be crossed (i.e. because they are not distributed uniformely but are only in the borders). such that adding them would bias the average properties seen by most particles. The opposite case could also happen: some subvolumes are exluded in the creation of the virtual volume because it leads to unsolvable ovelaps, but they are needed for the properties. In both cases the following method should be used:
void GetAverageProperties(
     const std::string& vol_name,
     const std::vector< std::string >& volumes_to_include1, bool include_exclude1,
     const std::vector< std::string >& volumes_to_include2, bool include_exclude2,
     double& X0_avg, double& dEdx_avg, double& nel_avg
);
where the meaning of the different arguments is the same as in the method AddVirtualVolume. Notice however that this method can be also used for real volume properties.