BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
create_rootgeom_ECAL_v3.C
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * File: create_rootgeom_ECAL_v3.C
4 * Last modified: 23-10-2019 by Petr Alekseev <pnaleks@gmail.com>
5 *
6 * Example of use:
7 * root -l '$VMCWORKDIR/macro/geometry/create_rootgeom_ECAL_v2.C(7,4)'
8 * This will generate root geometry file
9 * $VMCWORKDIR/geometry/ECAL_v2_run7_pos4.root
10 *
11 * v3:
12 * 1. Two shoulders (run 8)
13 * 2. Order of ECAL modules has been changed to be same as in the map
14 ******************************************************************************/
15
16#include "../run/bmnloadlibs.C"
17#include "TFile.h"
18#include "TGeoManager.h"
19#include "TGeoMedium.h"
20#include "TGeoVolume.h"
21
22//________________________________________________________________________________
23// ECAL = 8x7x9x215
24// ECAL = 8 SuperModules
25// SuperModule = 7 Modules
26// Module = 9 ADCmodules
27// ADCmodule = X:4cm x Y:4cm x Z:215 layers * (0.045 Pb + 0.15 Sci)
28// front steel cover ---PIPEC FIXME
29// ADCmodules == modules in the code
30
31//________________________________________________________________________________
32// ECAL Position and rotation in BM@N
33struct
34{
37 void Set(Double_t _x, Double_t _y, Double_t _z, Double_t _rotation)
38 {
39 use = kTRUE;
40 x = _x;
41 y = _y;
42 z = _z;
43 rotation = _rotation;
44 }
45 TGeoCombiTrans* GetTGeoCombiTrans(const char* name)
46 {
47 if (!use)
48 return 0;
49 TGeoRotation* rot = new TGeoRotation(name, 0., 0., 0.);
50 rot->Print();
51 rot->RotateY(rotation);
52 return new TGeoCombiTrans(x, y, z, rot);
53 }
55
56// int disabled[] = {510,511,512,531,532,533,552,553,554,0};
57int disabled[] = {0};
58int IsMod(int n)
59{
60 int i = 0;
61 while (disabled[i]) {
62 if (disabled[i] == n) {
63 printf("\n------------------------\nMOD %d - DISABLED!\n------------------------\n", n);
64 return 0;
65 }
66 i++;
67 }
68 return 1;
69}
70
72{
73 if (run == 7) {
74 switch (pos) {
75 case 1:
76 ecalLeft.Set(-44, 12.4, 843.1, 0);
77 return;
78 case 2:
79 ecalLeft.Set(-175, 12.4, 883.1, -10);
80 return;
81 case 3:
82 ecalLeft.Set(-175, 12.4, 283.1, -10);
83 return;
84 case 4:
85 ecalLeft.Set(-55, 12.4, 283.1, -10);
86 return;
87 case 5:
88 ecalLeft.Set(-175, 12.4, 283.1, -20);
89 return;
90 }
91 }
92 if (run == 8) { // Two shoulders
93 switch (pos) {
94 case 1:
95 // Single arm on the beam!!!
96 // ecalLeft.Set(0., 0., 283.1, 0.);
97 // ecalRight.Set(44,12.4,843.1,0);
98 ecalLeft.Set(-48 - 4, 12.4, 283.1, -10);
99 ecalRight.Set(48 + 20, 12.4, 283.1, 10);
100 return;
101 case 2:
102 // Two arms close to the axis, no rotation, 3x3 module will be removed to provide beam hole
103 ecalLeft.Set(-48, 12.4, 283.1, 0);
104 ecalRight.Set(48, 12.4, 283.1, 0);
105 // disabled = (int[]){510,511,512,531,532,533,552,553,554,0};
106 return;
107 case 3:
108 ecalLeft.Set(-175, 12.4, 283.1, -10);
109 ecalRight.Set(175, 12.4, 283.1, 10);
110 return;
111 case 4:
112 ecalLeft.Set(-55, 12.4, 283.1, -10);
113 ecalRight.Set(55, 12.4, 283.1, 10);
114 return;
115 case 5:
116 ecalLeft.Set(-175, 12.4, 283.1, -20);
117 ecalRight.Set(175, 12.4, 283.1, 20);
118 return;
119 }
120 }
121 Fatal("Main", "ECAL run %d position %d is not defined in " __FILE__, run, pos);
122}
123
124//________________________________________________________________________________
125// ECAL Parameters
126int Xmodules = 24; // X modules = ADCmodules
127int Ymodules = 21;
128int Zlayers = 215;
129Double_t thickPb = 0.030; // lead
130Double_t thickSci = 0.15; // scintilator
131Double_t thickSteel = 0.2; // front cover FIXME
132Double_t thickPaint = 0.0075; // paint
137
138// media ============================================
139struct
140{
151
152TGeoMedium* DefineMedia(FairGeoMedia* geoMedia, FairGeoBuilder* geoBuild, const char* name)
153{
154 FairGeoMedium* pFairGeoMedium = geoMedia->getMedium(name);
155 if (!pFairGeoMedium)
156 Fatal("Main", "FairMedium %s not found", name);
157 geoBuild->createMedium(pFairGeoMedium);
158 TGeoMedium* pTGeoMedium = gGeoManager->GetMedium(name);
159 if (!pTGeoMedium)
160 Fatal("Main", "Medium %s not found", name);
161 return pTGeoMedium;
162}
163
164void DefineRequiredMedia(FairGeoMedia* geoMedia, FairGeoBuilder* geoBuild)
165{
166
167 mMed.vacuum = DefineMedia(geoMedia, geoBuild, "vacuum");
168 mMed.air = DefineMedia(geoMedia, geoBuild, "air");
169 // mMed.iron = DefineMedia(geoMedia, geoBuild, "iron");
170 // mMed.tyvec = DefineMedia(geoMedia, geoBuild, "tyvec_ZDC");
171 mMed.lead = DefineMedia(geoMedia, geoBuild, "lead");
172 // mMed.scint = DefineMedia(geoMedia, geoBuild, "polystyrene"); // medium polystyrene (Scint.)
173 mMed.scint = DefineMedia(geoMedia, geoBuild, "FscScint"); // medium FscScint (Scint.)
174 // mMed.slot = DefineMedia(geoMedia, geoBuild, "plasticWLS_ZDC"); // medium plastic (slot)
175 // mMed.steel = DefineMedia(geoMedia, geoBuild, "steel");
176 mMed.steel = DefineMedia(geoMedia, geoBuild, "steel");
177 mMed.TiO2 = DefineMedia(geoMedia, geoBuild, "TiO2");
178
179} // DefineRequiredMedia
180
181///
182/// \param[in] run BMN run number (only run 7 is currently supported)
183/// \param[in] pos ECAL position in the run (five positions for run 7 are defined)
184///
186{
187
188 bmnloadlibs(); // load libraries
189
190 // ---- set working directory --------------------------------------------
191 TString gPath = gSystem->Getenv("VMCWORKDIR");
192
193 // ---- Geometry file name (output) ----------------------------------------
194 const TString geoDetectorName = "ECAL";
195 const TString geoDetectorVersion = "v3";
196 TString geoFileName;
197 geoFileName.Form("%s/geometry/%s_%s_run%d_pos%d.root", gPath.Data(), geoDetectorName.Data(),
198 geoDetectorVersion.Data(), run, pos);
199 cout << geoFileName << endl;
200
201 SetEcalPosition(run, pos);
202
203 TGeoCombiTrans* combi1 = ecalLeft.GetTGeoCombiTrans("rot1");
204 TGeoCombiTrans* combi2 = ecalRight.GetTGeoCombiTrans("rot2");
205
206 // ---- global geometry parameters ---------------------------------------
207 FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
208 FairGeoInterface* geoFace = geoLoad->getGeoInterface();
209
210 // ------- Load media from media file ----------------------------------
211 TString medFile = gPath + "/geometry/media.geo";
212 geoFace->setMediaFile(medFile);
213 geoFace->readMedia();
214 FairGeoMedia* geoMedia = geoFace->getMedia();
215 FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
216 geoMedia->list();
217 geoMedia->print();
218 DefineRequiredMedia(geoMedia, geoBuild);
219
220 // ------------------------ VOLUMES ----------------------------------------
221
222 // -------------- Create geometry and global top volume -----------------
223
224 TGeoVolume* top = new TGeoVolumeAssembly("TOP");
225 top->SetMedium(mMed.air); // ??? it was vacuum ???
226 // top->SetLineColor(kBlue);
227 // top->SetVisibility(kTRUE);
228 // top->SetTransparency(100);
229
230 gGeoManager = (TGeoManager*)gROOT->FindObject("FAIRGeom");
231 gGeoManager->SetName(geoDetectorName + "_geom");
232 gGeoManager->SetTopVolume(top);
233 // gGeoManager->SetTopVisible(1);
234
235 TGeoVolume* ecal = new TGeoVolumeAssembly("ecal");
236 ecal->SetMedium(mMed.air); // ??? it was vacuum ???
237 top->AddNode(ecal, 0);
238
239 TGeoVolume* ecal1 = 0;
240 TGeoVolume* ecal2 = 0;
241 // ecal->SetVisibility(kTRUE);
242 // ecal->SetTransparency(100);
243 if (combi1) {
244 ecal1 = gGeoManager->MakeBox("ecal1", mMed.vacuum, Xmodules * modwidth / 2, Ymodules * modheight / 2,
245 modlength / 2);
246 ecal->AddNode(ecal1, 0, combi1);
247 }
248 if (combi2) {
249 ecal2 = gGeoManager->MakeBox("ecal2", mMed.vacuum, Xmodules * modwidth / 2, Ymodules * modheight / 2,
250 modlength / 2);
251 ecal->AddNode(ecal2, 1, combi2);
252 }
253
254 TGeoVolume* module = gGeoManager->MakeBox("mod", mMed.vacuum, modwidth / 2, modheight / 2, modlength / 2);
255 // module->SetVisibility(kTRUE);
256 // module->SetTransparency(100);
257 // module->SetLineColor(kRed);
258 // module->SetLineWidth(0);
259
260 TGeoVolume* layerPb = gGeoManager->MakeBox("layPb", mMed.lead, modwidth / 2, modheight / 2, thickPb / 2);
261 // layerPb->SetVisibility(kTRUE);
262 // layerPb->SetLineColor(kBlue);
263 // layerPb->SetLineWidth(0);
264 // layerPb->SetTransparency(100);
265
266 TGeoVolume* layerPaint = gGeoManager->MakeBox("layPaint", mMed.TiO2, modwidth / 2, modheight / 2, thickPaint / 2);
267 // layerPaint->SetVisibility(kTRUE);
268 // layerPaint->SetLineColor(kWhite);
269 // layerPaint->SetLineWidth(0);
270 // layerPaint->SetTransparency(100);
271
272 TGeoVolume* layerSci = gGeoManager->MakeBox("laySci", mMed.scint, modwidth / 2, modheight / 2, thickSci / 2);
273 // layerSci->SetLineColor(kWhite+1);
274 // layerSci->SetTransparency(100);
275
276 TGeoVolume* covSteel = gGeoManager->MakeBox("covSteel", mMed.air, modwidth / 2, modheight / 2,
277 thickSteel / 2); // ??? should be steel ???
278 // covSteel->SetVisibility(kTRUE);
279 // covSteel->SetLineColor(kWhite);
280 // covSteel->SetTransparency(100);
281
282 // ------------------ STRUCTURE -------------------------------------------
283 module->AddNode(covSteel, 0, new TGeoTranslation(0, 0, thickSteel / 2 - modlength / 2));
284 Double_t z;
285 // Zlayers = 1;
286 Int_t nlay = 0;
287 for (int zlayer = 0; zlayer < Zlayers; zlayer++) {
288 z = thickSteel + thickPbSciPaint * zlayer;
289 module->AddNode(layerPaint, nlay, new TGeoTranslation(0, 0, z + thickPaint / 2 - modlength / 2));
290 module->AddNode(layerPb, nlay, new TGeoTranslation(0, 0, z + thickPaint + thickPb / 2 - modlength / 2));
291 module->AddNode(layerPaint, nlay,
292 new TGeoTranslation(0, 0, z + thickPaint + thickPb + thickPaint / 2 - modlength / 2));
293 module->AddNode(
294 layerSci, zlayer,
295 new TGeoTranslation(0, 0, z + thickPaint + thickPb + thickPaint + thickSci / 2 - modlength / 2));
296 }
297
298 int nmod = 1;
299 // Xmodules = 1;
300 // Ymodules = 1;
301 Double_t x0 = modwidth * Xmodules / 2 - modwidth / 2;
302 Double_t y0 = modheight * Ymodules / 2 - modheight / 2;
303 struct
304 {
305 Double_t x, y, z;
306 Double_t* Ptr() { return &x; }
307 void Set(Double_t _x, Double_t _y, Double_t _z)
308 {
309 x = _x;
310 y = _y;
311 z = _z;
312 }
313 } MC, TC;
314 Double_t mCoords[3];
315 Double_t tCoords[3];
316 if (ecal1) {
317 for (int xmod = 0; xmod < Xmodules; xmod++) {
318 for (int ymod = 0; ymod < Ymodules; ymod++) {
319 if (IsMod(nmod)) {
320 ecal1->AddNode(module, nmod, new TGeoTranslation(-x0 + modwidth * xmod, -y0 + modheight * ymod, 0));
321 MC.Set(-x0 + modwidth * xmod, -y0 + modheight * ymod, 0);
322 combi1->LocalToMaster(MC.Ptr(), TC.Ptr());
323 // printf("----------> Ch %d (%f, %f, %f)\n",nmod,TC.x,TC.y,TC.z);
324 }
325 nmod++;
326 } // ymod
327 } // xmod
328 }
329 if (ecal2) {
330 for (int xmod = 0; xmod < Xmodules; xmod++) {
331 for (int ymod = 0; ymod < Ymodules; ymod++) {
332 if (IsMod(nmod)) {
333 ecal2->AddNode(module, nmod, new TGeoTranslation(-x0 + modwidth * xmod, -y0 + modheight * ymod, 0));
334 MC.Set(-x0 + modwidth * xmod, -y0 + modheight * ymod, 0);
335 combi2->LocalToMaster(MC.Ptr(), TC.Ptr());
336 // printf("----------> Ch %d (%f, %f, %f)\n",nmod,TC.x,TC.y,TC.z);
337 }
338 nmod++;
339 } // ymod
340 } // xmod
341 }
342
344 gGeoManager->CloseGeometry();
345 gGeoManager->CheckOverlaps(0.001);
346 gGeoManager->PrintOverlaps();
347 gGeoManager->Test();
348 // gGeoMan->SetVisLevel(3);
349 // gGeoMan->SetVisOption(1);
350 TFile* geoFile = new TFile(geoFileName, "RECREATE");
351 top->Write();
352 geoFile->Close();
353 // top->Draw("ogl");
354}
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
void Fatal(const char *location, const char *msgfmt,...)
R__EXTERN TGeoManager * gGeoManager
#define gROOT
R__EXTERN TSystem * gSystem
void Close(Option_t *option="") override
void Print(Option_t *option="") const override
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
void RotateY(Double_t angle) override
void SetVisContainers(Bool_t flag=kTRUE) override
virtual TGeoNode * AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=nullptr, Option_t *option="")
virtual void SetMedium(TGeoMedium *medium)
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
const char * Data() const
void Form(const char *fmt,...)
Double_t thickPaint
Double_t modheight
Double_t thickPb
Double_t thickSci
Double_t modwidth
Double_t thickPbSciPaint
Double_t modlength
Double_t thickSteel
TGeoMedium * iron
TGeoMedium * tyvec
TGeoMedium * lead
TGeoMedium * steel
TGeoMedium * TiO2
TGeoMedium * air
TGeoMedium * vacuum
TGeoMedium * scint
TGeoMedium * DefineMedia(FairGeoMedia *geoMedia, FairGeoBuilder *geoBuild, const char *name)
struct @256052224050125122253227204044117137277002135076 ecalRight
Double_t z
struct @256052224050125122253227204044117137277002135076 ecalLeft
Double_t rotation
void SetEcalPosition(Int_t run, Int_t pos)
int IsMod(int n)
Bool_t use
void create_rootgeom_ECAL_v3(Int_t run, Int_t pos)
int disabled[]
Double_t y
void DefineRequiredMedia(FairGeoMedia *geoMedia, FairGeoBuilder *geoBuild)
Double_t x
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:20362