FairRoot/PandaRoot
createRootGeoFile.C
Go to the documentation of this file.
1 
7 {
8  gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C");
9  basiclibs();
10 
11  gSystem->Load("libGeoBase");
12  gSystem->Load("libParBase");
13  gSystem->Load("libBase");
14  gSystem->Load("libPassive");
15 
16  FairGeoLoader* geoLoad = new FairGeoLoader("TGeo","FairGeoLoader");
17  FairGeoInterface* geoFace = geoLoad->getGeoInterface();
18  geoFace->setMediaFile("../../geometry/media_pnd.geo");
19  geoFace->readMedia();
20  geoFace->print();
21 
22  FairGeoMedia* geoMedia = geoFace->getMedia();
23  FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
24 
25  // Parameters
26  TString fGeoFile= "../../geometry/dsk.root";
27 
28 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
29 
30  // Units
31  Double_t const cm = 1.;
32  Double_t const mm = cm/10.;
33  Int_t const colBlack = 1;
34  Int_t const colYellow = 5;
35  Int_t const colRed = 2;
36  Int_t const colBlue = 4;
37  Int_t const colGreen = 3;
38  Int_t const colGray = 15;
39 
40  // number of edges of the disk
41  Int_t const fEdges = 8;
42  // how many mirror types do we use?
43  Int_t const fDetectorTypes = 2;
44  Int_t const fDetectorColor[fDetectorTypes] = {colRed,colBlue};
45  Int_t const fMirrorColor[fDetectorTypes] = {colRed,colBlue};
46  Int_t const fDetectorsPerEdge = 120;
47  // center angle in each equal-sided triangle in the octagon
48  Double_t const fAlpha = 360. /fEdges; // [degree]
49  Double_t const fAlphaRad = fAlpha * TMath::DegToRad();
50  // opening angle: disk is horizontal on top)
51  Double_t const fPhi = fAlpha /2.; // [degree]
52  //coating (air surrounding for reflections)
53  Double_t const fCoatThickness = 1. *cm;
54  // disk
55  Double_t const fDiskThickness = 2. *cm;
56  Double_t const fDiskRMin = 3. *cm; // could be something like the radius of beampipe
57  Double_t const fDiskDistanceZ = 196. *cm;
58  Double_t const fDiskRMax = fDiskDistanceZ * TMath::Tan(22.*TMath::DegToRad()); // ~79.19 cm
59  // window
60  Double_t const fWindowHeightHalf = fDiskDistanceZ * TMath::Tan( 5.*TMath::DegToRad()); // ~17.15 cm
61  Double_t const fWindowWidthHalf = fDiskDistanceZ * TMath::Tan(10.*TMath::DegToRad()); // ~34.56 cm
62  Bool_t const fWindowIsBox = kTRUE;
63  // absorber in the window
64  Double_t const fAbsorberThickness = 10 *mm; // arbitary number
65  Bool_t const fAbsorberUse = kTRUE;
66  // mirror
67  Double_t const fMirrorHeight = 0.5 *mm; // arbitary value
68  // mcp
69  Double_t const fMcpHeight = 1. *cm; // arbitary value
70  // edge
71  Double_t const fEdgeWidthHalf = fDiskRMax * TMath::Tan(fPhi * TMath::DegToRad());
73  // detector
75  Double_t const fDetectorHeight = fMirrorHeight + fMcpHeight;
76 
77  // will help positioning
78  TVector3 edgeStartPos;
79  TVector3 corner;
80  TGeoRotation nullRotation;
81  TGeoRotation rotation;
84 
85  FairGeoMedium* FairMediumAir = geoMedia->getMedium("air");
86  FairGeoMedium* FairMediumVacuum = geoMedia->getMedium("vacuum");
87  FairGeoMedium* FairMediumFusedSil = geoMedia->getMedium("FusedSil");
88  FairGeoMedium* FairMediumDIRCAir = geoMedia->getMedium("DIRCair");
89  FairGeoMedium* FairMediumMirror = geoMedia->getMedium("Mirror");
90 
91  geoBuild->createMedium(FairMediumAir);
92  geoBuild->createMedium(FairMediumVacuum);
93  geoBuild->createMedium(FairMediumFusedSil);
94  geoBuild->createMedium(FairMediumDIRCAir);
95  geoBuild->createMedium(FairMediumMirror);
96 
97  TGeoManager* gGeoManager = (TGeoManager*)gROOT->FindObject("FAIRGeom");
98 
99  cout<<"-I- overall top"<<endl;
100  // a copy of cave
101  TGeoVolume* vTop;
102  TGeoBBox* lTop = new TGeoBBox(200,200,200);
103  vTop = new TGeoVolume("top", lTop, gGeoManager->GetMedium("air"));
104  gGeoManager->SetTopVolume(vTop);
105 
106 
107  cout<<"-I- calculating local mother"<<endl;
108  // now we create our local mother, that contains our detector. It has the same
109  // octagonal shape as our whole detector, so we wont produce any overlap with
110  // beampipe
111  // z = -fCoatThickness ..... fDiskThickness + fCoatThickness
112  TGeoVolume* vLocalMother;
113  TGeoPgon* lLocalMother = new TGeoPgon(fPhi, 360., fEdges, 2);
114  // DefineSection(layer, z, inner Radius, outer Radius)
115  lLocalMother->DefineSection(0, -fCoatThickness,
116  fWindowHeightHalf - fAbsorberThickness - fCoatThickness,
117  fDiskRMax + fMirrorHeight + fMcpHeight);
118  lLocalMother->DefineSection(1, fDiskThickness + fCoatThickness,
119  fWindowHeightHalf - fAbsorberThickness - fCoatThickness,
120  fDiskRMax + fMirrorHeight + fMcpHeight);
121  vLocalMother = new TGeoVolume("mother", lLocalMother, gGeoManager->GetMedium("DIRCair"));
122  vTop->AddNode(vLocalMother, 0, new TGeoCombiTrans(0, 0, fDiskDistanceZ, new TGeoRotation(0)));
123 
124  cout<<"-I- calculating radiator disk"<<endl;
125  // the glass disk. Its an octagon with a window in the center. We will use a
126  // box shape and substract it from the disk. The resulting shape should not
127  // overlap with the beampipe volume.
128  // z = 0 ..... fDiskThickness
129  TGeoPgon* lDiskGlass = new TGeoPgon("DG",fPhi,360.,fEdges, 2);
130  lDiskGlass->DefineSection(0, 0.,fDiskRMin,fDiskRMax);
131  lDiskGlass->DefineSection(1,fDiskThickness,fDiskRMin,fDiskRMax);
132  // i know, that the thickness is too high, but that doesnt matter, cause
133  // we will cmoposite the shape, but now we are sure it wont overlapp!
134  if (fWindowIsBox) {
135  TGeoBBox* lDiskWindow = new TGeoBBox("DW",fWindowWidthHalf,fWindowHeightHalf,fDiskThickness);
136  } else {
137  TGeoEltu* lDiskWindow = new TGeoEltu("DW",fWindowWidthHalf,fWindowHeightHalf,fDiskThickness);
138  }
139  // we need to shift the box along z-axis, cause center should be fDiskThickness/2 further in z
140  TGeoTranslation* trDW = new TGeoTranslation("trDW",0., 0., fDiskThickness/2.);
141  trDW->RegisterYourself(); // and to register it for TGeoCompositeShape
142  TGeoCompositeShape* lDisk = new TGeoCompositeShape("DG - DW:trDW");
143  TGeoVolume* vDisk = new TGeoVolume("radiator", lDisk, gGeoManager->GetMedium("FusedSil"));
144  vDisk->SetLineColor(colYellow);
145  // AddNode(*daughter, copynumber, TGeoMatrix)
146  vLocalMother->AddNode(vDisk,0,new TGeoCombiTrans(0., 0., 0., new TGeoRotation(0)));
147 
148 
149  if (fAbsorberUse) {
150  cout<<"-I- calculating absorber"<<endl;
151  if (fWindowIsBox) {
152  // in the window needs to be an absorber, (black colour) so the photons wont do
153  // reflections back into the disk.
154  // z = 0 ..... fDiskThickness
155  TGeoBBox* lAbsorberOuter = new TGeoBBox("AO",fWindowWidthHalf,fWindowHeightHalf,fDiskThickness/2.);
156  TGeoBBox* lAbsorberInner = new TGeoBBox("AI",fWindowWidthHalf-fAbsorberThickness,
157  fWindowHeightHalf-fAbsorberThickness,fDiskThickness);
158  } else {
159  TGeoEltu* lAbsorberOuter = new TGeoEltu("AO",fWindowWidthHalf,fWindowHeightHalf,fDiskThickness/2.);
160  TGeoEltu* lAbsorberInner = new TGeoEltu("AI",fWindowWidthHalf-fAbsorberThickness,
161  fWindowHeightHalf-fAbsorberThickness,fDiskThickness);
162  }
163  TGeoCompositeShape* lAbsorber = new TGeoCompositeShape("AO - AI");
164  TGeoVolume* vAbsorber = new TGeoVolume("absorber", lAbsorber, gGeoManager->GetMedium("vacuum"));
165  vAbsorber->SetLineColor(colBlack);
166  // again we need to shift them by the half fDiskThickness so place the center where it belongs
167  vLocalMother->AddNode(vAbsorber,0,new TGeoCombiTrans(0., 0.,fDiskThickness/2., new TGeoRotation(0)));
168  }
169 
170 
171  cout<<"-I- calculating detectors (mother for mirror/mcp)"<<endl;
172  // the detectors are container for a mirror and a mcp. We need as many types of detectors
173  // as we have diffrent mirror types (usually 2)
174  // their mother is the vArray, so we will have to use its reference frame
175  TGeoBBox* lDetector[fDetectorTypes];
176  TGeoVolume* vDetector[fDetectorTypes];
177  for (Int_t i=0; i<fDetectorTypes; i++) {
178  lDetector[i] = new TGeoBBox(fDetectorWidth/2., fDetectorHeight/2., fDiskThickness/2.);
179  name="detector"; name+=(i);
180  vDetector[i] = new TGeoVolume(name.Data(),lDetector[i],gGeoManager->GetMedium("DIRCair"));
181  vDetector[i]->SetLineColor(fDetectorColor[i]);
182  }
183 
184  cout<<"-I- calculating mirrors"<<endl;
185  // in every dectector is first a mirror.
186  // their mother is vDetector[i], so we will have to use its reference frame
187  TGeoBBox* lMirror[fDetectorTypes];
188  TGeoVolume* vMirror[fDetectorTypes];
189  for (Int_t i=0; i<fDetectorTypes; i++) {
190  lMirror[i] = new TGeoBBox(fDetectorWidth/2., fMirrorHeight/2., fDiskThickness/2.);
191  name="mirror"; name+=(i);
192  medium="Mirror";
193  vMirror[i] = new TGeoVolume(name.Data(),lMirror[i],gGeoManager->GetMedium(medium.Data()));
194  vMirror[i]->SetLineColor(fMirrorColor[i]);
195  vDetector[i]->AddNode(vMirror[i],0,
196  new TGeoCombiTrans(0.,-fDetectorHeight/2.+fMirrorHeight/2.,0.,
197  new TGeoRotation(0)));
198  }
199 
200 
201  cout<<"-I- calculating mcps"<<endl;
202  // The mcp is the actual detector. A photon that reaches the mcp will be detected.
203  TGeoBBox* lMcp = new TGeoBBox(fDetectorWidth/2.,fMcpHeight/2.,fDiskThickness/2.);
204  TGeoVolume* vMcp[fDetectorTypes];
205  for (Int_t i=0; i<fDetectorTypes; i++) {
206  name="mcp"; name+=(i);
207  vMcp[i] = new TGeoVolume(name.Data(),lMcp,gGeoManager->GetMedium("FusedSil"));
208  vMcp[i]->SetLineColor(colGray);
209  vDetector[i]->AddNode(vMcp[i],0,
210  new TGeoCombiTrans(0.,-fDetectorHeight/2.+fMirrorHeight+fMcpHeight/2.,0.,
211  new TGeoRotation(0)));
212  }
213 
214  cout<<"-I- placing detectors"<<endl;
215  edgeStartPos.SetXYZ(fEdgeWidthHalf-fDetectorWidth/2.,fDiskRMax+fDetectorHeight/2.,fDiskThickness/2.);
216  for (Int_t iEdge=0; iEdge<fEdges; iEdge++) {
217  for (Int_t iDet=0; iDet<fDetectorsPerEdge; iDet++) {
218  corner = edgeStartPos;
219  corner.SetX(corner.X()-iDet*fDetectorWidth);
220  corner.RotateZ(iEdge*fAlphaRad);
221  rotation = nullRotation;
222  rotation.RotateZ(iEdge*fAlpha);
223  vLocalMother->AddNode(vDetector[(fDetectorsPerEdge*iEdge+iDet)%fDetectorTypes],
224  fDetectorsPerEdge*iEdge + iDet,
225  new TGeoCombiTrans(corner.X(),corner.Y(),corner.Z(),
226  new TGeoRotation(rotation)));
227  }
228  }
229 
230 
231 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
232 // End of detector construction code
233 
234  // close geometry
235  gGeoManager->CloseGeometry();
236 
237  // save to file
238  TFile* fi = new TFile(fGeoFile,"RECREATE");
239  // writing the mother is sufficient, as it asks her daugthers to do the same.
240  vTop->Write();
241  fi->Close();
242 
243  cout << "Done." << endl;
244 
245  // lets see what we produced
246  vTop->Raytrace();
247 }
Int_t const colBlue
Int_t const colRed
Double_t const fAlpha
FairGeoMedium * FairMediumVacuum
Double_t const fMcpHeight
Double_t const fDiskDistanceZ
Double_t const fDetectorWidth
basiclibs()
Int_t const fEdges
TGeoCompositeShape * lDisk
FairGeoLoader * geoLoad
Int_t i
Definition: run_full.C:25
Double_t const fCoatThickness
Int_t const fDetectorsPerEdge
TGeoRotation rotation
float Tan(float x)
Definition: PndCAMath.h:165
Double_t const cm
TGeoManager * gGeoManager
TGeoVolume * vDisk
Double_t const fDiskThickness
Double_t const fEdgeWidth
TVector3 corner
Bool_t const fWindowIsBox
Double_t const fAbsorberThickness
Double_t const fAlphaRad
FairGeoMedium * FairMediumAir
FairGeoMedia * geoMedia
TFile * fi
TGeoTranslation * trDW
Double_t
TString medium
Int_t const colGreen
Int_t const fDetectorTypes
FairGeoMedium * FairMediumMirror
vLocalMother
Int_t const colGray
Int_t const colBlack
Double_t const fPhi
Double_t const fWindowHeightHalf
TString name
Int_t const colYellow
FairGeoMedium * FairMediumFusedSil
Double_t const fEdgeWidthHalf
Int_t const fMirrorColor[fDetectorTypes]
Double_t const fDiskRMax
Double_t const mm
TVector3 edgeStartPos
Double_t const fDiskRMin
FairGeoInterface * geoFace
Double_t const fWindowWidthHalf
Double_t const fDetectorHeight
Int_t const fDetectorColor[fDetectorTypes]
TString fGeoFile
Double_t const fMirrorHeight
TGeoRotation nullRotation
Bool_t const fAbsorberUse
FairGeoBuilder * geoBuild
FairGeoMedium * FairMediumDIRCAir