Detector geometry - R3BRootGroup/R3BRoot GitHub Wiki

The macro, which generates ALADIN geometry in ROOT (TGeo) format, is explained below. It should be used as an example for other detectors/systems, thus all parts except materials and volumes itself have to be preserved.

R3BRoot contains already set of macros for all sub-detectors. They are located in r3broot/macros/r3b/geo. By calling them, user has to specify a version name, where the scheme is: "v" + XX (year) + XX... (user-defined version). Output file will be automatically placed in r3broot/geometry folder. Specified version name is then to be used in r3bsim.C simulation macro.

Detector code has to implement call to ConstructRootGeometry() from ConstructGeometry() member function. This will use the value of fGeometryFileName member variable, set in the r3ball.C basic simulation macro, and automatically construct geometry in the simulation run. Sensitive volumes are to be identified by name and kTRUE return value of overridden CheckIfSensitive() member function.

NOTE: In case of complex detector geometries, one has to create a single keeping volume of type TGeoVolumeAssembly. Only one keeping volume can be added to the GeoManager top volume.

Geometry parameter values should come on top, for better overview:

Double_t Aladin_width = 156.0;
Double_t Aladin_length = 176.0;
Double_t Aladin_gap = 52.;
Double_t Aladin_angle = -7.0;
Double_t DistanceToTarget = 350.0;
Double_t Yoke_thickness = 52.;
Double_t Correction = -95.0;
Double_t DistanceFromtargetToAladinCenter = DistanceToTarget + Correction;
TGeoRotation *rot_aladin = new TGeoRotation("Aladinrot");
rot_aladin->RotateY(Aladin_angle);
TGeoRotation *rot_mirror = new TGeoRotation("mirror");
rot_mirror->RotateZ(180.0);
rot_mirror->RotateY(Aladin_angle);

Initialise interface and read media definition:

FairGeoLoader*    geoLoad = new FairGeoLoader("TGeo","FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString medFile = geoPath + "/geometry/media_r3b.geo";
geoFace->setMediaFile(medFile);
geoFace->readMedia();
gGeoMan = gGeoManager;

Define name of the geometry file:

TString geoFileName = geoPath + "/geometry/aladin_";
geoFileName = geoFileName + geoTag + ".geo.root";

Load necessary materials:

FairGeoMedia*   geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* mFe      = geoMedia->getMedium("iron");
if ( ! mFe ) Fatal("Main", "FairMedium iron not found");
geoBuild->createMedium(mFe);
TGeoMedium* pMedFe = gGeoMan->GetMedium("iron");
if ( ! pMedFe ) Fatal("Main", "Medium iron not found");
...

Create top volume:

gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom");
gGeoMan->SetName("ALADINgeom");
TGeoVolume* top = new TGeoVolumeAssembly("TOP");
gGeoMan->SetTopVolume(top);

Create keeping volume:

TGeoVolume *cell = new TGeoVolumeAssembly("ALADINCELL");

Create logical volumes:

TGeoShape *solidFeYoke_up = new TGeoBBox("FeYoke_up",
                                         Aladin_width/2.0,
                                         Yoke_thickness/2.0,
                                         Aladin_length/2.0);
TGeoTranslation *tr1 = new TGeoTranslation(0.0,
                                           Aladin_gap/2.0 + Yoke_thickness/2.0,
                                           DistanceFromtargetToAladinCenter);
TGeoCombiTrans *t1 = new TGeoCombiTrans(*tr1,*rot_aladin);
TGeoVolume* pVolFeYoke_up = new TGeoVolume("FeYokeVolup",solidFeYoke_up, pMedFe);
pVolFeYoke_up->SetVisLeaves(kTRUE);
...

Add logical volumes to the keeping volume:

cell->AddNode(pVolFeYoke_up,   1, t1);
...  

Add single keeping volume to the top:

top->AddNode(cell, 1, pMatrix0);

Finalise geometry and check for overlaps with 0.001 cm precision:

gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.001);
gGeoMan->PrintOverlaps();
gGeoMan->Test();

Save top volume and close the file:

TFile* geoFile = new TFile(geoFileName, "RECREATE");
top->Write();
geoFile->Close();