Project
Loading...
Searching...
No Matches
Detector.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "TGeoBBox.h"
13#include "TGeoCompositeShape.h"
14#include "TGeoManager.h" // for TGeoManager
15#include "TGeoMatrix.h"
16#include "TGeoVolume.h"
17#include "TMath.h"
18#include "TString.h"
19
20#include <fairlogger/Logger.h>
21#include "FairVolume.h"
22#include "FairRootManager.h"
23
24#include "TOFSimulation/Detector.h"
25
26#include <TVirtualMC.h> // for TVirtualMC, gMC
29#include "DetectorsBase/Stack.h"
30
31#include <algorithm>
32#include <array>
33#include <map>
34#include <utility>
35#include <vector>
36
37using namespace o2::tof;
38
40
42 : o2::base::DetImpl<Detector>("TOF", active), mEventNr(0), mTOFHoles(kTRUE), mHits(o2::utils::createSimVector<HitType>())
43{
44 for (Int_t i = 0; i < Geo::NSECTORS; i++) {
45 mTOFSectors[i] = 1;
46 }
47}
48
50 : o2::base::DetImpl<Detector>(rhs),
51 mEventNr(0),
52 mTOFHoles(rhs.mTOFHoles),
53 mHits(o2::utils::createSimVector<HitType>())
54{
55 for (Int_t i = 0; i < Geo::NSECTORS; i++) {
56 mTOFSectors[i] = rhs.mTOFSectors[i];
57 }
58}
59
64
66{
67 TGeoVolume* v = gGeoManager->GetVolume("FPAD");
68 if (v == nullptr) {
69 printf("Sensitive volume FSEN not found!!!!!!!!");
70 } else {
71 AddSensitiveVolume(v);
72 }
73}
74
75Bool_t Detector::ProcessHits(FairVolume* v)
76{
77 // This method is called from the MC stepping for the sensitive volume only
78 if (static_cast<int>(fMC->TrackCharge()) == 0) {
79 // set a very large step size for neutral particles
80 return kFALSE; // take only charged particles
81 }
82
83 float pos2x, pos2y, pos2z;
84 fMC->TrackPosition(pos2x, pos2y, pos2z);
85 Float_t radius = std::sqrt(pos2x * pos2x + pos2y * pos2y);
86 LOG(debug) << "Process hit in TOF volume ar R=" << radius << " - Z=" << pos2z;
87
88 Float_t enDep = fMC->Edep();
89 if (enDep < 1E-8) {
90 return kFALSE; // wo se need a threshold?
91 }
92
93 // ADD HIT
94 float posx, posy, posz;
95 fMC->TrackPosition(posx, posy, posz);
96 float time = fMC->TrackTime() * 1.0e09;
97 auto stack = static_cast<o2::data::Stack*>(fMC->GetStack());
98 int trackID = stack->GetCurrentTrackNumber();
99 int sensID = v->getMCid();
100 Int_t det[5];
101 Float_t pos[3] = {posx, posy, posz};
102 Float_t delta[3];
103 Geo::getPadDxDyDz(pos, det, delta);
104 auto channel = Geo::getIndex(det);
105 HitType newhit(posx, posy, posz, time, enDep, trackID, sensID);
106 // an invalid channel (getIndex returns -1 off a valid pad) never merges, and
107 // there is nothing to merge with before the first hit of the event
108 if (channel < 0 || mHits->empty() || channel != mLastChannelID || !isMergable(newhit, mHits->back())) {
109 mHits->push_back(newhit);
110 stack->addHit(GetDetId());
111 } else {
112 mHits->back().SetEnergyLoss(mHits->back().GetEnergyLoss() + newhit.GetEnergyLoss());
113 // LOG(info)<<"Merging hit "<<"\n";
114 // <<mHits->back().GetId()<<"with new hit "<<newhit.GetId()<<"\n";
115 }
116 mLastChannelID = channel;
117
118 return kTRUE;
119}
120
122{
123 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, kTRUE);
124}
125
127{
128 // TODO: move this out of here
129 if (!o2::utils::ShmManager::Instance().isOperational()) {
130 mHits->clear();
131 }
132 mLastChannelID = -1;
133}
134
136{
137 Int_t isxfld = 2;
138 Float_t sxmgmx = 10.;
140
141 //--- Quartz (SiO2) ---
142 Float_t aq[2] = {28.0855, 15.9994};
143 Float_t zq[2] = {14., 8.};
144 Float_t wq[2] = {1., 2.};
145 Float_t dq = 2.7; // (+5.9%)
146 Int_t nq = -2;
147
148 // --- Nomex (C14H22O2N2) ---
149 Float_t anox[4] = {12.011, 1.00794, 15.9994, 14.00674};
150 Float_t znox[4] = {6., 1., 8., 7.};
151 Float_t wnox[4] = {14., 22., 2., 2.};
152 // Float_t dnox = 0.048; //old value
153 Float_t dnox = 0.22; // (x 4.6)
154 Int_t nnox = -4;
155
156 // --- G10 {Si, O, C, H, O} ---
157 Float_t we[7], na[7];
158
159 Float_t ag10[5] = {28.0855, 15.9994, 12.011, 1.00794, 15.9994};
160 Float_t zg10[5] = {14., 8., 6., 1., 8.};
161 Float_t wmatg10[5];
162 Int_t nlmatg10 = 5;
163 na[0] = 1., na[1] = 2., na[2] = 0., na[3] = 0., na[4] = 0.;
164 MaterialMixer(we, ag10, na, 5);
165 wmatg10[0] = we[0] * 0.6;
166 wmatg10[1] = we[1] * 0.6;
167 na[0] = 0., na[1] = 0., na[2] = 14., na[3] = 20., na[4] = 3.;
168 MaterialMixer(we, ag10, na, 5);
169 wmatg10[2] = we[2] * 0.4;
170 wmatg10[3] = we[3] * 0.4;
171 wmatg10[4] = we[4] * 0.4;
172 // Float_t densg10 = 1.7; //old value
173 Float_t densg10 = 2.0; // (+17.8%)
174
175 // --- Water ---
176 Float_t awa[2] = {1.00794, 15.9994};
177 Float_t zwa[2] = {1., 8.};
178 Float_t wwa[2] = {2., 1.};
179 Float_t dwa = 1.0;
180 Int_t nwa = -2;
181
182 // --- Air ---
183 Float_t aAir[4] = {12.011, 14.00674, 15.9994, 39.948};
184 Float_t zAir[4] = {6., 7., 8., 18.};
185 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
186 Float_t dAir = 1.20479E-3;
187
188 // --- Fibre Glass ---
189 Float_t afg[4] = {28.0855, 15.9994, 12.011, 1.00794};
190 Float_t zfg[4] = {14., 8., 6., 1.};
191 Float_t wfg[4] = {0.12906, 0.29405, 0.51502, 0.06187};
192 // Float_t dfg = 1.111;
193 Float_t dfg = 2.05; // (x1.845)
194 Int_t nfg = 4;
195
196 // --- Freon C2F4H2 + SF6 ---
197 Float_t afre[4] = {12.011, 1.00794, 18.9984032, 32.0065};
198 Float_t zfre[4] = {6., 1., 9., 16.};
199 Float_t wfre[4] = {0.21250, 0.01787, 0.74827, 0.021355};
200 Float_t densfre = 0.00375;
201 Int_t nfre = 4;
202
203 // --- Cables and tubes {Al, Cu} ---
204 Float_t acbt[2] = {26.981539, 63.546};
205 Float_t zcbt[2] = {13., 29.};
206 Float_t wcbt[2] = {0.407, 0.593};
207 Float_t decbt = 0.68;
208
209 // --- Cable {CH2, Al, Cu} ---
210 Float_t asc[4] = {12.011, 1.00794, 26.981539, 63.546};
211 Float_t zsc[4] = {6., 1., 13., 29.};
212 Float_t wsc[4];
213 for (Int_t ii = 0; ii < 4; ii++) {
214 wsc[ii] = 0.;
215 }
216
217 Float_t wDummy[4], nDummy[4];
218 for (Int_t ii = 0; ii < 4; ii++) {
219 wDummy[ii] = 0.;
220 }
221 for (Int_t ii = 0; ii < 4; ii++) {
222 nDummy[ii] = 0.;
223 }
224 nDummy[0] = 1.;
225 nDummy[1] = 2.;
226 MaterialMixer(wDummy, asc, nDummy, 2);
227 wsc[0] = 0.4375 * wDummy[0];
228 wsc[1] = 0.4375 * wDummy[1];
229 wsc[2] = 0.3244;
230 wsc[3] = 0.2381;
231 Float_t dsc = 1.223;
232
233 // --- Crates boxes {Al, Cu, Fe, Cr, Ni} ---
234 Float_t acra[5] = {26.981539, 63.546, 55.845, 51.9961, 58.6934};
235 Float_t zcra[5] = {13., 29., 26., 24., 28.};
236 Float_t wcra[5] = {0.7, 0.2, 0.07, 0.018, 0.012};
237 Float_t dcra = 0.77;
238
239 // --- Polietilene CH2 ---
240 Float_t aPlastic[2] = {12.011, 1.00794};
241 Float_t zPlastic[2] = {6., 1.};
242 Float_t wPlastic[2] = {1., 2.};
243 // Float_t dPlastic = 0.92; // PDB value
244 Float_t dPlastic = 0.93; // (~+1.1%)
245 Int_t nwPlastic = -2;
246
247 Mixture(0, "Air$", aAir, zAir, dAir, 4, wAir);
248 Mixture(1, "Nomex$", anox, znox, dnox, nnox, wnox);
249 Mixture(2, "G10$", ag10, zg10, densg10, nlmatg10, wmatg10);
250 Mixture(3, "fibre glass$", afg, zfg, dfg, nfg, wfg);
251 Material(4, "Al $", 26.981539, 13., 2.7, -8.9, 999.);
252 Float_t factor = 0.4 / 1.5 * 2. / 3.;
253 Material(5, "Al honeycomb$", 26.981539, 13., 2.7 * factor, -8.9 / factor, 999.);
254 Mixture(6, "Freon$", afre, zfre, densfre, nfre, wfre);
255 Mixture(7, "Glass$", aq, zq, dq, nq, wq);
256 Mixture(8, "Water$", awa, zwa, dwa, nwa, wwa);
257 Mixture(9, "cables+tubes$", acbt, zcbt, decbt, 2, wcbt);
258 Material(10, "Cu $", 63.546, 29., 8.96, -1.43, 999.);
259 Mixture(11, "cable$", asc, zsc, dsc, 4, wsc);
260 Mixture(12, "Al+Cu+steel$", acra, zcra, dcra, 5, wcra);
261 Mixture(13, "plastic$", aPlastic, zPlastic, dPlastic, nwPlastic, wPlastic);
262 Float_t factorHoles = 1. / 36.5;
263 Material(14, "Al honey for holes$", 26.981539, 13., 2.7 * factorHoles, -8.9 / factorHoles, 999.);
264
265 Float_t epsil, stmin, deemax, stemax;
266
267 // STD data
268 // EPSIL = 0.1 ! Tracking precision,
269 // STEMAX = 0.1 ! Maximum displacement for multiple scattering
270 // DEEMAX = 0.1 ! Maximum fractional energy loss, DLS
271 // STMIN = 0.1
272
273 // TOF data
274 epsil = .001; // Tracking precision,
275 stemax = -1.; // Maximum displacement for multiple scattering
276 deemax = -.3; // Maximum fractional energy loss, DLS
277 stmin = -.8;
278
279 Medium(kAir, "Air$", 0, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
280 Medium(kNomex, "Nomex$", 1, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
281 Medium(kG10, "G10$", 2, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
282 Medium(kFiberGlass, "fibre glass$", 3, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
283 Medium(kAlFrame, "Al Frame$", 4, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
284 Medium(kHoneycomb, "honeycomb$", 5, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
285 Medium(kFre, "Fre$", 6, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
286 Medium(kCuS, "Cu-S$", 10, 1, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
287 Medium(kGlass, "Glass$", 7, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
288 Medium(kWater, "Water$", 8, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
289 Medium(kCable, "Cable$", 11, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
290 Medium(kCableTubes, "Cables+Tubes$", 9, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
291 Medium(kCopper, "Copper$", 10, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
292 Medium(kPlastic, "Plastic$", 13, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
293 Medium(kCrates, "Crates$", 12, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
294 Medium(kHoneyHoles, "honey_holes$", 14, 0, isxfld, sxmgmx, 10., stemax, deemax, epsil, stmin);
295}
296
297void Detector::MaterialMixer(Float_t* p, const Float_t* const a, const Float_t* const m, Int_t n) const
298{
299 // a[] atomic weights vector (in)
300 // (atoms present in more compound appear separately)
301 // m[] number of corresponding atoms in the compound (in)
302 Float_t t = 0.;
303 for (Int_t i = 0; i < n; ++i) {
304 p[i] = a[i] * m[i];
305 t += p[i];
306 }
307 for (Int_t i = 0; i < n; ++i) {
308 p[i] = p[i] / t;
309 }
310}
311
313{
315
316 /*
317 xTof = 124.5;//fTOFGeometry->StripLength()+2.*(0.3+0.03); // cm, x-dimension of FTOA volume
318 yTof = fTOFGeometry->Rmax()-fTOFGeometry->Rmin(); // cm, y-dimension of FTOA volume
319 Double_t zTof = fTOFGeometry->ZlenA(); // cm, z-dimension of FTOA volume
320 */
321
322 Double_t xTof = Geo::STRIPLENGTH + 2.5, yTof = Geo::RMAX - Geo::RMIN, zTof = Geo::ZLENA;
323 DefineGeometry(xTof, yTof, zTof);
324
325 LOG(info) << "Loaded TOF geometry";
326}
327
329void Detector::DefineGeometry(Double_t xtof, Double_t ytof, Double_t zlenA)
330{
331 //
332 // Definition of the Time Of Fligh Resistive Plate Chambers
333 //
334
335 Double_t xFLT, yFLT, zFLTA;
336 xFLT = xtof - 2. * Geo::MODULEWALLTHICKNESS;
337 yFLT = ytof * 0.5 - Geo::MODULEWALLTHICKNESS;
338 zFLTA = zlenA - 2. * Geo::MODULEWALLTHICKNESS;
339
340 createModules(xtof, ytof, zlenA, xFLT, yFLT, zFLTA);
341 makeStripsInModules(ytof, zlenA);
342
343 createModuleCovers(xtof, zlenA);
344
345 createBackZone(xtof, ytof, zlenA);
346 makeFrontEndElectronics(xtof);
347 makeFEACooling(xtof);
348 makeNinoMask(xtof);
349 makeSuperModuleCooling(xtof, ytof, zlenA);
350 makeSuperModuleServices(xtof, ytof, zlenA);
351 makeCentralFEAContainer(ytof);
352
353 makeModulesInBTOFvolumes(ytof, zlenA);
354 makeCoversInBTOFvolumes();
355 makeBackInBTOFvolumes(ytof);
356
357 makeReadoutCrates(ytof);
358}
359
360void Detector::createModules(Double_t xtof, Double_t ytof, Double_t zlenA, Double_t xFLT, Double_t yFLT, Double_t zFLTA) const
361{
362 //
363 // Create supermodule volume
364 // and wall volumes to separate 5 modules
365 //
366
367 Int_t idrotm[8];
368 for (Int_t ii = 0; ii < 8; ii++) {
369 idrotm[ii] = 0;
370 }
371
372 // Definition of the of fibre glass modules (FTOA, FTOB and FTOC)
373 Double_t par[3];
374 par[0] = xtof * 0.5;
375 par[1] = ytof * 0.25;
376 par[2] = zlenA * 0.5;
377 TVirtualMC::GetMC()->Gsvolu("FTOA", "BOX ", getMediumID(kFiberGlass), par, 3); // Fibre glass
378
379 if (mTOFHoles) {
380 par[0] = xtof * 0.5;
381 par[1] = ytof * 0.25;
382 par[2] = (zlenA * 0.5 - Geo::INTERCENTRMODBORDER1) * 0.5;
383 TVirtualMC::GetMC()->Gsvolu("FTOB", "BOX ", getMediumID(kFiberGlass), par, 3); // Fibre glass
384 TVirtualMC::GetMC()->Gsvolu("FTOC", "BOX ", getMediumID(kFiberGlass), par, 3); // Fibre glass
385 }
386
387 // Definition and positioning
388 // of the not sensitive volumes with Insensitive Freon (FLTA, FLTB and FLTC)
389 par[0] = xFLT * 0.5;
390 par[1] = yFLT * 0.5;
391 par[2] = zFLTA * 0.5;
392 TVirtualMC::GetMC()->Gsvolu("FLTA", "BOX ", getMediumID(kFre), par, 3); // Freon mix
393
394 Double_t xcoor, ycoor, zcoor;
395 xcoor = 0.;
396 ycoor = Geo::MODULEWALLTHICKNESS * 0.5;
397 zcoor = 0.;
398 TVirtualMC::GetMC()->Gspos("FLTA", 0, "FTOA", xcoor, ycoor, zcoor, 0, "ONLY");
399
400 if (mTOFHoles) {
401 par[2] = (zlenA * 0.5 - 2. * Geo::MODULEWALLTHICKNESS - Geo::INTERCENTRMODBORDER1) * 0.5;
402 TVirtualMC::GetMC()->Gsvolu("FLTB", "BOX ", getMediumID(kFre), par, 3); // Freon mix
403 TVirtualMC::GetMC()->Gsvolu("FLTC", "BOX ", getMediumID(kFre), par, 3); // Freon mix
404
405 // xcoor = 0.;
406 // ycoor = Geo::MODULEWALLTHICKNESS*0.5;
408 TVirtualMC::GetMC()->Gspos("FLTB", 0, "FTOB", xcoor, ycoor, zcoor, 0, "ONLY");
409 TVirtualMC::GetMC()->Gspos("FLTC", 0, "FTOC", xcoor, ycoor, -zcoor, 0, "ONLY");
410 }
411
412 // Definition and positioning
413 // of the fibre glass walls between central and intermediate modules (FWZ1 and FWZ2)
414 Double_t alpha, tgal, beta, tgbe, trpa[11];
415 // tgal = (yFLT - 2.*Geo::LENGTHINCEMODBORDER)/(Geo::INTERCENTRMODBORDER2 - Geo::INTERCENTRMODBORDER1);
418 alpha = TMath::ATan(tgal);
419 beta = (TMath::Pi() * 0.5 - alpha) * 0.5;
420 tgbe = TMath::Tan(beta);
421 trpa[0] = xFLT * 0.5;
422 trpa[1] = 0.;
423 trpa[2] = 0.;
424 trpa[3] = 2. * Geo::MODULEWALLTHICKNESS;
425 // trpa[4] = (Geo::LENGTHINCEMODBORDER - 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
426 // trpa[5] = (Geo::LENGTHINCEMODBORDER + 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
427 trpa[4] = (Geo::LENGTHINCEMODBORDERD - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
428 trpa[5] = (Geo::LENGTHINCEMODBORDERD + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
429 trpa[6] =
430 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
431 trpa[7] = 2. * Geo::MODULEWALLTHICKNESS;
432 trpa[8] = (Geo::LENGTHINCEMODBORDERD - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
433 trpa[9] = (Geo::LENGTHINCEMODBORDERD + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
434 // trpa[8] = (Geo::LENGTHINCEMODBORDER - 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
435 // trpa[9] = (Geo::LENGTHINCEMODBORDER + 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
436 trpa[10] =
437 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
438 TVirtualMC::GetMC()->Gsvolu("FWZ1D", "TRAP", getMediumID(kFiberGlass), trpa, 11); // Fibre glass
439
440 Matrix(idrotm[0], 90., 90., 180., 0., 90., 180.);
441 Matrix(idrotm[1], 90., 90., 0., 0., 90., 0.);
442
443 // xcoor = 0.;
444 // ycoor = -(yFLT - Geo::LENGTHINCEMODBORDER)*0.5;
445 ycoor = -(yFLT - Geo::LENGTHINCEMODBORDERD) * 0.5;
447 TVirtualMC::GetMC()->Gspos("FWZ1D", 1, "FLTA", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
448 TVirtualMC::GetMC()->Gspos("FWZ1D", 2, "FLTA", xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
449
450 Double_t y0B, ycoorB, zcoorB;
451
452 if (mTOFHoles) {
453 // y0B = Geo::LENGTHINCEMODBORDER - Geo::MODULEWALLTHICKNESS*tgbe;
455 trpa[0] = xFLT * 0.5;
456 trpa[1] = 0.;
457 trpa[2] = 0.;
458 trpa[3] = Geo::MODULEWALLTHICKNESS;
459 trpa[4] = (y0B - Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
460 trpa[5] = (y0B + Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
461 trpa[6] =
462 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
463 trpa[7] = Geo::MODULEWALLTHICKNESS;
464 trpa[8] = (y0B - Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
465 trpa[9] = (y0B + Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
466 trpa[10] =
467 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
468 // xcoor = 0.;
469 ycoorB = ycoor - Geo::MODULEWALLTHICKNESS * 0.5 * tgbe;
470 zcoorB =
472 TVirtualMC::GetMC()->Gsvolu("FWZAD", "TRAP", getMediumID(kFiberGlass), trpa, 11); // Fibre glass
473 TVirtualMC::GetMC()->Gspos("FWZAD", 1, "FLTB", xcoor, ycoorB, zcoorB, idrotm[1], "ONLY");
474 TVirtualMC::GetMC()->Gspos("FWZAD", 2, "FLTC", xcoor, ycoorB, -zcoorB, idrotm[0], "ONLY");
475 }
476
479 alpha = TMath::ATan(tgal);
480 beta = (TMath::Pi() * 0.5 - alpha) * 0.5;
481 tgbe = TMath::Tan(beta);
482 trpa[0] = xFLT * 0.5;
483 trpa[1] = 0.;
484 trpa[2] = 0.;
485 trpa[3] = 2. * Geo::MODULEWALLTHICKNESS;
486 // trpa[4] = (Geo::LENGTHINCEMODBORDER - 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
487 // trpa[5] = (Geo::LENGTHINCEMODBORDER + 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
488 trpa[4] = (Geo::LENGTHINCEMODBORDERU - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
489 trpa[5] = (Geo::LENGTHINCEMODBORDERU + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
490 trpa[6] =
491 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
492 trpa[7] = 2. * Geo::MODULEWALLTHICKNESS;
493 trpa[8] = (Geo::LENGTHINCEMODBORDERU - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
494 trpa[9] = (Geo::LENGTHINCEMODBORDERU + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
495 // trpa[8] = (Geo::LENGTHINCEMODBORDER - 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
496 // trpa[9] = (Geo::LENGTHINCEMODBORDER + 2.*Geo::MODULEWALLTHICKNESS*tgbe)*0.5;
497 trpa[10] =
498 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
499 TVirtualMC::GetMC()->Gsvolu("FWZ1U", "TRAP", getMediumID(kFiberGlass), trpa, 11); // Fibre glass
500
501 Matrix(idrotm[2], 90., 270., 0., 0., 90., 180.);
502 Matrix(idrotm[3], 90., 270., 180., 0., 90., 0.);
503
504 // xcoor = 0.;
505 // ycoor = (yFLT - Geo::LENGTHINCEMODBORDER)*0.5;
506 ycoor = (yFLT - Geo::LENGTHINCEMODBORDERU) * 0.5;
508 TVirtualMC::GetMC()->Gspos("FWZ1U", 1, "FLTA", xcoor, ycoor, zcoor, idrotm[2], "ONLY");
509 TVirtualMC::GetMC()->Gspos("FWZ1U", 2, "FLTA", xcoor, ycoor, -zcoor, idrotm[3], "ONLY");
510
511 if (mTOFHoles) {
512 // y0B = Geo::LENGTHINCEMODBORDER + Geo::MODULEWALLTHICKNESS*tgbe;
514 trpa[0] = xFLT * 0.5;
515 trpa[1] = 0.;
516 trpa[2] = 0.;
517 trpa[3] = Geo::MODULEWALLTHICKNESS;
518 trpa[4] = (y0B - Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
519 trpa[5] = (y0B + Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
520 trpa[6] =
521 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
522 trpa[7] = Geo::MODULEWALLTHICKNESS;
523 trpa[8] = (y0B - Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
524 trpa[9] = (y0B + Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
525 trpa[10] =
526 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
527 TVirtualMC::GetMC()->Gsvolu("FWZBU", "TRAP", getMediumID(kFiberGlass), trpa, 11); // Fibre glass
528 // xcoor = 0.;
529 ycoorB = ycoor - Geo::MODULEWALLTHICKNESS * 0.5 * tgbe;
530 zcoorB = (zlenA * 0.5 - 2. * Geo::MODULEWALLTHICKNESS - Geo::INTERCENTRMODBORDER1) * 0.5 -
532 TVirtualMC::GetMC()->Gspos("FWZBU", 1, "FLTB", xcoor, ycoorB, zcoorB, idrotm[3], "ONLY");
533 TVirtualMC::GetMC()->Gspos("FWZBU", 2, "FLTC", xcoor, ycoorB, -zcoorB, idrotm[2], "ONLY");
534 }
535
536 trpa[0] = 0.5 * (Geo::INTERCENTRMODBORDER2 - Geo::INTERCENTRMODBORDER1) / TMath::Cos(alpha);
537 trpa[1] = 2. * Geo::MODULEWALLTHICKNESS;
538 trpa[2] = xFLT * 0.5;
539 trpa[3] = -beta * TMath::RadToDeg();
540 trpa[4] = 0.;
541 trpa[5] = 0.;
542 TVirtualMC::GetMC()->Gsvolu("FWZ2", "PARA", getMediumID(kFiberGlass), trpa, 6); // Fibre glass
543
544 Matrix(idrotm[4], alpha * TMath::RadToDeg(), 90., 90. + alpha * TMath::RadToDeg(), 90., 90., 180.);
545 Matrix(idrotm[5], 180. - alpha * TMath::RadToDeg(), 90., 90. - alpha * TMath::RadToDeg(), 90., 90., 0.);
546
547 // xcoor = 0.;
548 // ycoor = 0.;
551 TVirtualMC::GetMC()->Gspos("FWZ2", 1, "FLTA", xcoor, ycoor, zcoor, idrotm[4], "ONLY");
552 TVirtualMC::GetMC()->Gspos("FWZ2", 2, "FLTA", xcoor, ycoor, -zcoor, idrotm[5], "ONLY");
553
554 if (mTOFHoles) {
555 trpa[0] = 0.5 * (Geo::INTERCENTRMODBORDER2 - Geo::INTERCENTRMODBORDER1) / TMath::Cos(alpha);
556 trpa[1] = Geo::MODULEWALLTHICKNESS;
557 trpa[2] = xFLT * 0.5;
558 trpa[3] = -beta * TMath::RadToDeg();
559 trpa[4] = 0.;
560 trpa[5] = 0.;
561 TVirtualMC::GetMC()->Gsvolu("FWZC", "PARA", getMediumID(kFiberGlass), trpa, 6); // Fibre glass
562 // xcoor = 0.;
563 ycoorB = ycoor - Geo::MODULEWALLTHICKNESS * tgbe;
564 zcoorB = (zlenA * 0.5 - 2. * Geo::MODULEWALLTHICKNESS - Geo::INTERCENTRMODBORDER1) * 0.5 -
566 TVirtualMC::GetMC()->Gspos("FWZC", 1, "FLTB", xcoor, ycoorB, zcoorB, idrotm[5], "ONLY");
567 TVirtualMC::GetMC()->Gspos("FWZC", 2, "FLTC", xcoor, ycoorB, -zcoorB, idrotm[4], "ONLY");
568 }
569
570 // Definition and positioning
571 // of the fibre glass walls between intermediate and lateral modules (FWZ3 and FWZ4)
573 alpha = TMath::ATan(tgal);
574 beta = (TMath::Pi() * 0.5 - alpha) * 0.5;
575 tgbe = TMath::Tan(beta);
576 trpa[0] = xFLT * 0.5;
577 trpa[1] = 0.;
578 trpa[2] = 0.;
579 trpa[3] = 2. * Geo::MODULEWALLTHICKNESS;
580 trpa[4] = (Geo::LENGTHEXINMODBORDER - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
581 trpa[5] = (Geo::LENGTHEXINMODBORDER + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
582 trpa[6] =
583 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
584 trpa[7] = 2. * Geo::MODULEWALLTHICKNESS;
585 trpa[8] = (Geo::LENGTHEXINMODBORDER - 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
586 trpa[9] = (Geo::LENGTHEXINMODBORDER + 2. * Geo::MODULEWALLTHICKNESS * tgbe) * 0.5;
587 trpa[10] =
588 TMath::ATan(tgbe * 0.5) * TMath::RadToDeg(); // TMath::ATan((trpa[5] - trpa[4])/(2.*trpa[3]))*TMath::RadToDeg();
589 TVirtualMC::GetMC()->Gsvolu("FWZ3", "TRAP", getMediumID(kFiberGlass), trpa, 11); // Fibre glass
590
591 // xcoor = 0.;
592 ycoor = (yFLT - Geo::LENGTHEXINMODBORDER) * 0.5;
594 TVirtualMC::GetMC()->Gspos("FWZ3", 1, "FLTA", xcoor, ycoor, zcoor, idrotm[3], "ONLY");
595 TVirtualMC::GetMC()->Gspos("FWZ3", 2, "FLTA", xcoor, ycoor, -zcoor, idrotm[2], "ONLY");
596
597 if (mTOFHoles) {
598 // xcoor = 0.;
599 // ycoor = (yFLT - Geo::LENGTHEXINMODBORDER)*0.5;
600 zcoor =
602 TVirtualMC::GetMC()->Gspos("FWZ3", 5, "FLTB", xcoor, ycoor, zcoor, idrotm[2], "ONLY");
603 TVirtualMC::GetMC()->Gspos("FWZ3", 6, "FLTC", xcoor, ycoor, -zcoor, idrotm[3], "ONLY");
604 }
605
606 // xcoor = 0.;
607 ycoor = -(yFLT - Geo::LENGTHEXINMODBORDER) * 0.5;
609 TVirtualMC::GetMC()->Gspos("FWZ3", 3, "FLTA", xcoor, ycoor, zcoor, idrotm[1], "ONLY");
610 TVirtualMC::GetMC()->Gspos("FWZ3", 4, "FLTA", xcoor, ycoor, -zcoor, idrotm[0], "ONLY");
611
612 if (mTOFHoles) {
613 // xcoor = 0.;
614 // ycoor = -(yFLT - Geo::LENGTHEXINMODBORDER)*0.5;
615 zcoor =
617 TVirtualMC::GetMC()->Gspos("FWZ3", 7, "FLTB", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
618 TVirtualMC::GetMC()->Gspos("FWZ3", 8, "FLTC", xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
619 }
620
621 trpa[0] = 0.5 * (Geo::EXTERINTERMODBORDER2 - Geo::EXTERINTERMODBORDER1) / TMath::Cos(alpha);
622 trpa[1] = 2. * Geo::MODULEWALLTHICKNESS;
623 trpa[2] = xFLT * 0.5;
624 trpa[3] = -beta * TMath::RadToDeg();
625 trpa[4] = 0.;
626 trpa[5] = 0.;
627 TVirtualMC::GetMC()->Gsvolu("FWZ4", "PARA", getMediumID(kFiberGlass), trpa, 6); // Fibre glass
628
629 Matrix(idrotm[6], alpha * TMath::RadToDeg(), 90., 90. + alpha * TMath::RadToDeg(), 90., 90., 180.);
630 Matrix(idrotm[7], 180. - alpha * TMath::RadToDeg(), 90., 90. - alpha * TMath::RadToDeg(), 90., 90., 0.);
631
632 // xcoor = 0.;
633 ycoor = 0.;
635 TVirtualMC::GetMC()->Gspos("FWZ4", 1, "FLTA", xcoor, ycoor, zcoor, idrotm[7], "ONLY");
636 TVirtualMC::GetMC()->Gspos("FWZ4", 2, "FLTA", xcoor, ycoor, -zcoor, idrotm[6], "ONLY");
637
638 if (mTOFHoles) {
639 // xcoor = 0.;
640 // ycoor = 0.;
642 (zlenA * 0.5 + Geo::INTERCENTRMODBORDER1 - 2. * Geo::MODULEWALLTHICKNESS) * 0.5;
643 TVirtualMC::GetMC()->Gspos("FWZ4", 3, "FLTB", xcoor, ycoor, zcoor, idrotm[6], "ONLY");
644 TVirtualMC::GetMC()->Gspos("FWZ4", 4, "FLTC", xcoor, ycoor, -zcoor, idrotm[7], "ONLY");
645 }
646}
647
648void Detector::makeStripsInModules(Double_t ytof, Double_t zlenA) const
649{
650 //
651 // Define MRPC strip volume, called FSTR
652 // Insert FSTR volume in FLTA/B/C volumes
653 //
654 Double_t yFLT = ytof * 0.5 - Geo::MODULEWALLTHICKNESS;
655
657
658 // new description for strip volume -double stack strip-
659 // -- all constants are expressed in cm
660 // height of different layers
661 constexpr Double_t HGLFY = Geo::HFILIY + 2. * Geo::HGLASSY; // height of GLASS Layer
662
663 constexpr Double_t LSENSMX = Geo::NPADX * Geo::XPAD; // length of Sensitive Layer
664 constexpr Double_t HSENSMY = Geo::HSENSMY; // height of Sensitive Layer
665 constexpr Double_t WSENSMZ = Geo::NPADZ * Geo::ZPAD; // width of Sensitive Layer
666
667 // height of the FSTR Volume (the strip volume)
668 constexpr Double_t HSTRIPY = 2. * Geo::HHONY + 2. * Geo::HPCBY + 4. * Geo::HRGLY + 2. * HGLFY + Geo::HCPCBY;
669
670 // width of the FSTR Volume (the strip volume)
671 constexpr Double_t WSTRIPZ = Geo::WCPCBZ;
672 // length of the FSTR Volume (the strip volume)
673 constexpr Double_t LSTRIPX = Geo::STRIPLENGTH;
674
675 // FSTR volume definition-filling this volume with non sensitive Gas Mixture
676 Double_t parfp[3] = {(LSTRIPX * 0.5), (HSTRIPY * 0.5),
677 (WSTRIPZ * 0.5)};
678 TVirtualMC::GetMC()->Gsvolu("FSTR", "BOX", getMediumID(kFre), parfp, 3); // Freon mix
679
680 Double_t posfp[3] = {0., 0., 0.};
681
682 // The strip is a stack of layers that fills FSTR symmetrically about y = 0. Every layer's
683 // centre used to be summed in its own order -- the outer ones from the strip's lower edge,
684 // the inner ones from the centre outwards -- so faces that are algebraically the same plane
685 // came out up to 0.34 nm apart. TGeo's navigator relocates from a point pushed far further
686 // than that and never notices; nothing else does. Build the stack from two running planes
687 // instead, one from the centre and one from the strip's edge, using the same double halves the
688 // box shapes are given, so every touching pair shares a face bit for bit. The two meet inside
689 // the glass slot, which carries a freon gap either side of the glass by design and is the one
690 // place with slack to absorb the rounding.
691 const double hStrip = (HSTRIPY * 0.5);
692 const double hHon = (Geo::HHONY * 0.5);
693 const double hPcb = (Geo::HPCBY * 0.5);
694 const double hRgl = (Geo::HRGLY * 0.5);
695 const double hCpcb = (Geo::HCPCBY * 0.5);
696 // outwards from the central PCB, which sits at y = 0
697 const double yRglIn = hCpcb + hRgl;
698 const double yGlassSlotIn = yRglIn + hRgl;
699 // inwards from the strip's outer face
700 const double yHon = hStrip - hHon;
701 const double yPcbOut = (yHon - hHon) - hPcb;
702 const double yRglOut = (yPcbOut - hPcb) - hRgl;
703 const double yGlassSlotOut = yRglOut - hRgl;
704 // the glass is centred in what remains between them
705 const double yGlf = 0.5 * (yGlassSlotIn + yGlassSlotOut);
706
707 // NOMEX (HONEYCOMB) Layer definition
708 // parfp[0] = LSTRIPX*0.5;
709 parfp[1] = Geo::HHONY * 0.5;
710 parfp[2] = Geo::WHONZ * 0.5;
711 TVirtualMC::GetMC()->Gsvolu("FHON", "BOX", getMediumID(kNomex), parfp, 3); // Nomex (Honeycomb)
712 // positioning 2 NOMEX Layers on FSTR volume
713 // posfp[0] = 0.;
714 TVirtualMC::GetMC()->Gspos("FHON", 1, "FSTR", 0., -yHon, 0., 0, "ONLY");
715 TVirtualMC::GetMC()->Gspos("FHON", 2, "FSTR", 0., yHon, 0., 0, "ONLY");
716
717 // Lower PCB Layer definition
718 // parfp[0] = LSTRIPX*0.5;
719 parfp[1] = Geo::HPCBY * 0.5;
720 parfp[2] = Geo::WPCBZ1 * 0.5;
721 TVirtualMC::GetMC()->Gsvolu("FPC1", "BOX", getMediumID(kG10), parfp, 3); // G10
722
723 // Upper PCB Layer definition
724 // parfp[0] = LSTRIPX*0.5;
725 // parfp[1] = Geo::HPCBY*0.5;
726 parfp[2] = Geo::WPCBZ2 * 0.5;
727 TVirtualMC::GetMC()->Gsvolu("FPC2", "BOX", getMediumID(kG10), parfp, 3); // G10
728
729 // positioning 2 external PCB Layers in FSTR volume
730 // posfp[0] = 0.;
731 TVirtualMC::GetMC()->Gspos("FPC1", 1, "FSTR", 0., yPcbOut, 0., 0, "ONLY");
732 TVirtualMC::GetMC()->Gspos("FPC2", 1, "FSTR", 0., -yPcbOut, 0., 0, "ONLY");
733
734 // Central PCB layer definition
735 // parfp[0] = LSTRIPX*0.5;
736 parfp[1] = Geo::HCPCBY * 0.5;
737 parfp[2] = Geo::WCPCBZ * 0.5;
738 TVirtualMC::GetMC()->Gsvolu("FPCB", "BOX", getMediumID(kG10), parfp, 3); // G10
739 gGeoManager->GetVolume("FPCB")->VisibleDaughters(kFALSE);
740
741 // positioning the central PCB layer
742 TVirtualMC::GetMC()->Gspos("FPCB", 1, "FSTR", 0., 0., 0., 0, "ONLY");
743
744 // Sensitive volume definition
745 Double_t parfs[3] = {(LSENSMX * 0.5), (HSENSMY * 0.5),
746 (WSENSMZ * 0.5)};
747 TVirtualMC::GetMC()->Gsvolu("FSEN", "BOX", getMediumID(kCuS), parfs, 3); // Cu sensitive
748
749 // printf("check material\n");
750 // printf("ID used = %i\n",getMediumID(kCuS));
751 // printf("ID needed = %i\n",gGeoManager->GetMedium("TOF_Cu-S$")->GetId());
752 // getchar();
753
754 // dividing FSEN along z in Geo::NPADZ=2 and along x in Geo::NPADX=48
755 TVirtualMC::GetMC()->Gsdvn("FSEZ", "FSEN", Geo::NPADZ, 3);
756 TVirtualMC::GetMC()->Gsdvn("FPAD", "FSEZ", Geo::NPADX, 1);
757 // positioning sensitive layer inside FPCB
758 TVirtualMC::GetMC()->Gspos("FSEN", 1, "FPCB", 0., 0., 0., 0, "ONLY");
759
760 // RED GLASS Layer definition
761 // parfp[0] = LSTRIPX*0.5;
762 parfp[1] = Geo::HRGLY * 0.5;
763 parfp[2] = Geo::WRGLZ * 0.5;
764 TVirtualMC::GetMC()->Gsvolu("FRGL", "BOX", getMediumID(kGlass), parfp, 3); // red glass
765 // positioning 4 RED GLASS Layers in FSTR volume
766 // posfp[0] = 0.;
767 TVirtualMC::GetMC()->Gspos("FRGL", 1, "FSTR", 0., -yRglOut, 0., 0, "ONLY");
768 TVirtualMC::GetMC()->Gspos("FRGL", 4, "FSTR", 0., yRglOut, 0., 0, "ONLY");
769 TVirtualMC::GetMC()->Gspos("FRGL", 2, "FSTR", 0., -yRglIn, 0., 0, "ONLY");
770 TVirtualMC::GetMC()->Gspos("FRGL", 3, "FSTR", 0., yRglIn, 0., 0, "ONLY");
771
772 // GLASS Layer definition
773 // parfp[0] = LSTRIPX*0.5;
774 parfp[1] = Geo::HGLASSY;
775 parfp[2] = Geo::WGLFZ * 0.5;
776 TVirtualMC::GetMC()->Gsvolu("FGLF", "BOX", getMediumID(kGlass), parfp, 3); // glass
777 // positioning 2 GLASS Layers in FSTR volume
778 // posfp[0] = 0.;
779 TVirtualMC::GetMC()->Gspos("FGLF", 1, "FSTR", 0., -yGlf, 0., 0, "ONLY");
780 TVirtualMC::GetMC()->Gspos("FGLF", 2, "FSTR", 0., yGlf, 0., 0, "ONLY");
781
782 // Positioning the Strips (FSTR volumes) in the FLT volumes
783 Int_t maxStripNumbers[5] = {Geo::NSTRIPC, Geo::NSTRIPB, Geo::NSTRIPA, Geo::NSTRIPB, Geo::NSTRIPC};
784
785 Int_t idrotm[Geo::NSTRIPXSECTOR];
786 for (Int_t ii = 0; ii < Geo::NSTRIPXSECTOR; ii++) {
787 idrotm[ii] = 0;
788 }
789
790 Int_t totalStrip = 0;
791 Double_t xpos, zpos, ypos, ang;
792 for (Int_t iplate = 0; iplate < Geo::NPLATES; iplate++) {
793 if (iplate > 0) {
794 totalStrip += maxStripNumbers[iplate - 1];
795 }
796 for (Int_t istrip = 0; istrip < maxStripNumbers[iplate]; istrip++) {
797 ang = Geo::getAngles(iplate, istrip);
798
799 if (ang > 0.) {
800 Matrix(idrotm[istrip + totalStrip], 90., 0., 90. + ang, 90., ang, 90.);
801 } else if (ang == 0.) {
802 Matrix(idrotm[istrip + totalStrip], 90., 0., 90., 90., 0., 0.);
803 } else if (ang < 0.) {
804 Matrix(idrotm[istrip + totalStrip], 90., 0., 90. + ang, 90., -ang, 270.);
805 }
806
807 xpos = 0.;
808 ypos = Geo::getHeights(iplate, istrip) + yFLT * 0.5;
809 zpos = Geo::getDistances(iplate, istrip);
810 TVirtualMC::GetMC()->Gspos("FSTR", istrip + totalStrip + 1, "FLTA", xpos, ypos, -zpos,
811 idrotm[istrip + totalStrip], "ONLY");
812
813 if (mTOFHoles) {
814 if (istrip + totalStrip + 1 > 53) {
815 TVirtualMC::GetMC()->Gspos(
816 "FSTR", istrip + totalStrip + 1, "FLTC", xpos, ypos,
817 -zpos - (zlenA * 0.5 - 2. * Geo::MODULEWALLTHICKNESS + Geo::INTERCENTRMODBORDER1) * 0.5,
818 idrotm[istrip + totalStrip], "ONLY");
819 }
820 if (istrip + totalStrip + 1 < 39) {
821 TVirtualMC::GetMC()->Gspos(
822 "FSTR", istrip + totalStrip + 1, "FLTB", xpos, ypos,
823 -zpos + (zlenA * 0.5 - 2. * Geo::MODULEWALLTHICKNESS + Geo::INTERCENTRMODBORDER1) * 0.5,
824 idrotm[istrip + totalStrip], "ONLY");
825 }
826 }
827 }
828 }
829}
830
831void Detector::createModuleCovers(Double_t xtof, Double_t zlenA) const
832{
833 //
834 // Create covers for module:
835 // per each module zone, defined according to
836 // fgkInterCentrModBorder2, fgkExterInterModBorder1 and zlenA+2 values,
837 // there is a frame of thickness 2cm in Al
838 // and the contained zones in honeycomb of Al.
839 // There is also an interface layer (1.6mm thichness)
840 // and plastic and Cu corresponding to the flat cables.
841 //
842
843 Double_t par[3];
844 par[0] = xtof * 0.5 + 2.;
846 par[2] = zlenA * 0.5 + 2.;
847 TVirtualMC::GetMC()->Gsvolu("FPEA", "BOX ", getMediumID(kAir), par, 3); // Air
848 if (mTOFHoles) {
849 TVirtualMC::GetMC()->Gsvolu("FPEB", "BOX ", getMediumID(kAir), par, 3); // Air
850 }
851
852 constexpr Double_t ALCOVERTHICKNESS = 1.5;
853 constexpr Double_t INTERFACECARDTHICKNESS = 0.16;
854 constexpr Double_t ALSKINTHICKNESS = 0.1;
855 constexpr Double_t PLASTICFLATCABLETHICKNESS = 0.25;
856 constexpr Double_t COPPERFLATCABLETHICKNESS = 0.01;
857
858 // par[0] = xtof*0.5 + 2.;
859 par[1] = ALCOVERTHICKNESS * 0.5;
860 // par[2] = zlenA*0.5 + 2.;
861 TVirtualMC::GetMC()->Gsvolu("FALT", "BOX ", getMediumID(kAlFrame), par, 3); // Al
862 if (mTOFHoles) {
863 TVirtualMC::GetMC()->Gsvolu("FALB", "BOX ", getMediumID(kAlFrame), par, 3); // Al
864 }
865 Double_t xcoor, ycoor, zcoor;
866 xcoor = 0.;
867 ycoor = 0.;
868 zcoor = 0.;
869 TVirtualMC::GetMC()->Gspos("FALT", 0, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
870 if (mTOFHoles) {
871 TVirtualMC::GetMC()->Gspos("FALB", 0, "FPEB", xcoor, ycoor, zcoor, 0, "ONLY");
872 }
873
874 par[0] = xtof * 0.5;
875 // par[1] = ALCOVERTHICKNESS*0.5;
877 TVirtualMC::GetMC()->Gsvolu("FPE1", "BOX ", getMediumID(kHoneycomb), par, 3); // Al honeycomb
878 // xcoor = 0.;
879 // ycoor = 0.;
880 // zcoor = 0.;
881 TVirtualMC::GetMC()->Gspos("FPE1", 0, "FALT", xcoor, ycoor, zcoor, 0, "ONLY");
882
883 if (mTOFHoles) {
884 // par[0] = xtof*0.5;
885 par[1] = ALCOVERTHICKNESS * 0.5 - ALSKINTHICKNESS;
886 // par[2] = Geo::INTERCENTRMODBORDER2 - 2.;
887 TVirtualMC::GetMC()->Gsvolu("FPE4", "BOX ", getMediumID(kHoneyHoles), par, 3); // Al honeycomb for holes
888 // xcoor = 0.;
889 // ycoor = 0.;
890 // zcoor = 0.;
891 TVirtualMC::GetMC()->Gspos("FPE4", 0, "FALB", xcoor, ycoor, zcoor, 0, "ONLY");
892 }
893
894 // par[0] = xtof*0.5;
895 // par[1] = ALCOVERTHICKNESS*0.5;
897 TVirtualMC::GetMC()->Gsvolu("FPE2", "BOX ", getMediumID(kHoneycomb), par, 3); // Al honeycomb
898 // xcoor = 0.;
899 // ycoor = 0.;
901 TVirtualMC::GetMC()->Gspos("FPE2", 1, "FALT", xcoor, ycoor, zcoor, 0, "ONLY");
902 TVirtualMC::GetMC()->Gspos("FPE2", 2, "FALT", xcoor, ycoor, -zcoor, 0, "ONLY");
903
904 if (mTOFHoles) {
905 // xcoor = 0.;
906 // ycoor = 0.;
907 // zcoor = (Geo::EXTERINTERMODBORDER1 + Geo::INTERCENTRMODBORDER2)*0.5;
908 TVirtualMC::GetMC()->Gspos("FPE2", 1, "FALB", xcoor, ycoor, zcoor, 0, "ONLY");
909 TVirtualMC::GetMC()->Gspos("FPE2", 2, "FALB", xcoor, ycoor, -zcoor, 0, "ONLY");
910 }
911
912 // par[0] = xtof*0.5;
913 // par[1] = ALCOVERTHICKNESS*0.5;
914 par[2] = (zlenA * 0.5 + 2. - Geo::EXTERINTERMODBORDER1) * 0.5 - 2.;
915 TVirtualMC::GetMC()->Gsvolu("FPE3", "BOX ", getMediumID(kHoneycomb), par, 3); // Al honeycomb
916 // xcoor = 0.;
917 // ycoor = 0.;
918 zcoor = (zlenA * 0.5 + 2. + Geo::EXTERINTERMODBORDER1) * 0.5;
919 TVirtualMC::GetMC()->Gspos("FPE3", 1, "FALT", xcoor, ycoor, zcoor, 0, "ONLY");
920 TVirtualMC::GetMC()->Gspos("FPE3", 2, "FALT", xcoor, ycoor, -zcoor, 0, "ONLY");
921
922 if (mTOFHoles) {
923 // xcoor = 0.;
924 // ycoor = 0.;
925 zcoor = (zlenA * 0.5 + 2. + Geo::EXTERINTERMODBORDER1) * 0.5;
926 TVirtualMC::GetMC()->Gspos("FPE3", 1, "FALB", xcoor, ycoor, zcoor, 0, "ONLY");
927 TVirtualMC::GetMC()->Gspos("FPE3", 2, "FALB", xcoor, ycoor, -zcoor, 0, "ONLY");
928 }
929
930 // volumes for Interface cards
931 par[0] = xtof * 0.5;
932 par[1] = INTERFACECARDTHICKNESS * 0.5;
934 TVirtualMC::GetMC()->Gsvolu("FIF1", "BOX ", getMediumID(kG10), par, 3); // G10
935 // xcoor = 0.;
936 ycoor = ALCOVERTHICKNESS * 0.5 + INTERFACECARDTHICKNESS * 0.5;
937 zcoor = 0.;
938 TVirtualMC::GetMC()->Gspos("FIF1", 0, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
939
940 // par[0] = xtof*0.5;
941 // par[1] = INTERFACECARDTHICKNESS*0.5;
943 TVirtualMC::GetMC()->Gsvolu("FIF2", "BOX ", getMediumID(kG10), par, 3); // G10
944 // xcoor = 0.;
945 // ycoor = ALCOVERTHICKNESS*0.5 + INTERFACECARDTHICKNESS*0.5;
947 TVirtualMC::GetMC()->Gspos("FIF2", 1, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
948 TVirtualMC::GetMC()->Gspos("FIF2", 2, "FPEA", xcoor, ycoor, -zcoor, 0, "ONLY");
949 if (mTOFHoles) {
950 TVirtualMC::GetMC()->Gspos("FIF2", 1, "FPEB", xcoor, ycoor, zcoor, 0, "ONLY");
951 TVirtualMC::GetMC()->Gspos("FIF2", 2, "FPEB", xcoor, ycoor, -zcoor, 0, "ONLY");
952 }
953
954 // par[0] = xtof*0.5;
955 // par[1] = INTERFACECARDTHICKNESS*0.5;
956 par[2] = (zlenA * 0.5 + 2. - Geo::EXTERINTERMODBORDER1) * 0.5 - 2.;
957 TVirtualMC::GetMC()->Gsvolu("FIF3", "BOX ", getMediumID(kG10), par, 3); // G10
958 // xcoor = 0.;
959 // ycoor = ALCOVERTHICKNESS*0.5 + INTERFACECARDTHICKNESS*0.5;
960 zcoor = (zlenA * 0.5 + 2. + Geo::EXTERINTERMODBORDER1) * 0.5;
961 TVirtualMC::GetMC()->Gspos("FIF3", 1, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
962 TVirtualMC::GetMC()->Gspos("FIF3", 2, "FPEA", xcoor, ycoor, -zcoor, 0, "ONLY");
963 if (mTOFHoles) {
964 TVirtualMC::GetMC()->Gspos("FIF3", 1, "FPEB", xcoor, ycoor, zcoor, 0, "ONLY");
965 TVirtualMC::GetMC()->Gspos("FIF3", 2, "FPEB", xcoor, ycoor, -zcoor, 0, "ONLY");
966 }
967
968 // volumes for flat cables
969 // plastic
970 par[0] = xtof * 0.5;
971 par[1] = PLASTICFLATCABLETHICKNESS * 0.5;
973 TVirtualMC::GetMC()->Gsvolu("FFC1", "BOX ", getMediumID(kPlastic), par, 3); // Plastic (CH2)
974 // xcoor = 0.;
975 ycoor = -ALCOVERTHICKNESS * 0.5 - PLASTICFLATCABLETHICKNESS * 0.5;
976 zcoor = 0.;
977 TVirtualMC::GetMC()->Gspos("FFC1", 0, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
978
979 // par[0] = xtof*0.5;
980 // par[1] = PLASTICFLATCABLETHICKNESS*0.5;
982 TVirtualMC::GetMC()->Gsvolu("FFC2", "BOX ", getMediumID(kPlastic), par, 3); // Plastic (CH2)
983 // xcoor = 0.;
984 // ycoor = -ALCOVERTHICKNESS*0.5 - PLASTICFLATCABLETHICKNESS*0.5;
986 TVirtualMC::GetMC()->Gspos("FFC2", 1, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
987 TVirtualMC::GetMC()->Gspos("FFC2", 2, "FPEA", xcoor, ycoor, -zcoor, 0, "ONLY");
988 if (mTOFHoles) {
989 TVirtualMC::GetMC()->Gspos("FFC2", 1, "FPEB", xcoor, ycoor, zcoor, 0, "ONLY");
990 TVirtualMC::GetMC()->Gspos("FFC2", 2, "FPEB", xcoor, ycoor, -zcoor, 0, "ONLY");
991 }
992
993 // par[0] = xtof*0.5;
994 // par[1] = PLASTICFLATCABLETHICKNESS*0.5;
995 par[2] = (zlenA * 0.5 + 2. - Geo::EXTERINTERMODBORDER1) * 0.5 - 2.;
996 TVirtualMC::GetMC()->Gsvolu("FFC3", "BOX ", getMediumID(kPlastic), par, 3); // Plastic (CH2)
997 // xcoor = 0.;
998 // ycoor = -ALCOVERTHICKNESS*0.5 - PLASTICFLATCABLETHICKNESS*0.5;
999 zcoor = (zlenA * 0.5 + 2. + Geo::EXTERINTERMODBORDER1) * 0.5;
1000 TVirtualMC::GetMC()->Gspos("FFC3", 1, "FPEA", xcoor, ycoor, zcoor, 0, "ONLY");
1001 TVirtualMC::GetMC()->Gspos("FFC3", 2, "FPEA", xcoor, ycoor, -zcoor, 0, "ONLY");
1002 if (mTOFHoles) {
1003 TVirtualMC::GetMC()->Gspos("FFC3", 1, "FPEB", xcoor, ycoor, zcoor, 0, "ONLY");
1004 TVirtualMC::GetMC()->Gspos("FFC3", 2, "FPEB", xcoor, ycoor, -zcoor, 0, "ONLY");
1005 }
1006
1007 // Cu
1008 par[0] = xtof * 0.5;
1009 par[1] = COPPERFLATCABLETHICKNESS * 0.5;
1011 TVirtualMC::GetMC()->Gsvolu("FCC1", "BOX ", getMediumID(kCopper), par, 3); // Cu
1012 TVirtualMC::GetMC()->Gspos("FCC1", 0, "FFC1", 0., 0., 0., 0, "ONLY");
1013
1014 // par[0] = xtof*0.5;
1015 // par[1] = COPPERFLATCABLETHICKNESS*0.5;
1017 TVirtualMC::GetMC()->Gsvolu("FCC2", "BOX ", getMediumID(kCopper), par, 3); // Cu
1018 TVirtualMC::GetMC()->Gspos("FCC2", 0, "FFC2", 0., 0., 0., 0, "ONLY");
1019
1020 // par[0] = xtof*0.5;
1021 // par[1] = COPPERFLATCABLETHICKNESS*0.5;
1022 par[2] = (zlenA * 0.5 + 2. - Geo::EXTERINTERMODBORDER1) * 0.5 - 2.;
1023 TVirtualMC::GetMC()->Gsvolu("FCC3", "BOX ", getMediumID(kCopper), par, 3); // Cu
1024 TVirtualMC::GetMC()->Gspos("FCC3", 0, "FFC3", 0., 0., 0., 0, "ONLY");
1025}
1026
1027std::vector<Detector::FEAContainer> Detector::feaContainers(Double_t zlenA, Bool_t holes) const
1028{
1029 //
1030 // Returns the FEA card containers of one supermodule in placement order, each with the z it
1031 // sits at, its copy number and whether it is rotated. Creates and places nothing itself. The
1032 // modules with the PHOS hole (holes) carry four row blocks instead of five. The container at
1033 // the centre of the supermodule is not in the list: makeCentralFEAContainer builds that one.
1034 //
1035
1036 const Double_t rowstep = 6.66;
1037 const Double_t rowgap[5] = {13.5, 22.9, 16.94, 23.8, 20.4};
1038 const Int_t rowb[5] = {6, 7, 6, 19, 7};
1039 const Int_t nblocks = holes ? 4 : 5;
1040
1041 std::vector<FEAContainer> cont;
1042 Int_t row = 1;
1043 for (Int_t sg = -1; sg < 2; sg += 2) {
1044 Double_t zcoor = sg * zlenA * 0.5 - 0.8;
1045 for (Int_t nb = 0; nb < nblocks; ++nb) {
1046 zcoor = zcoor - sg * (rowgap[nb] - rowstep);
1047 const Int_t nrow = row + rowb[nb];
1048 for (; row < nrow; ++row) {
1049 zcoor -= sg * rowstep;
1050 cont.push_back({zcoor, row, sg == -1 && nb != 4});
1051 }
1052 }
1053 }
1054 return cont;
1055}
1056
1057void Detector::makeCentralFEAContainer(Double_t ytof) const
1058{
1059 //
1060 // Creates FCM1 and FCM2, the FEA card container at the centre of a supermodule, as assemblies
1061 // of the FCA1/FCA2 content, and places one in FAIA and one in FAIC. Here it is the container
1062 // that gives way to the cooling bars and not the other way round, and an assembly has no shape
1063 // of its own to overlap them. What was its air is now the FAIA/FAIC air around it, which is the
1064 // same medium.
1065 //
1066
1067 const Double_t carY = Geo::FEAPARAMETERS[1] + Geo::ROOF1PARAMETERS[1] + Geo::ROOF2PARAMETERS[1] * 0.5;
1068 const Double_t ycoor = -(ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 + carY;
1069
1070 const char* source[2] = {"FCA1", "FCA2"};
1071 const char* central[2] = {"FCM1", "FCM2"};
1072 const char* mother[2] = {"FAIA", "FAIC"};
1073 for (Int_t i = 0; i < 2; ++i) {
1074 TGeoVolume* from = gGeoManager->GetVolume(source[i]);
1075 auto* assembly = new TGeoVolumeAssembly(central[i]);
1076 for (Int_t k = 0; k < from->GetNdaughters(); ++k) {
1077 TGeoNode* nd = from->GetNode(k);
1078 assembly->AddNode(nd->GetVolume(), nd->GetNumber(), new TGeoHMatrix(*nd->GetMatrix()));
1079 }
1080 gGeoManager->GetVolume(mother[i])->AddNode(assembly, 91, new TGeoTranslation(0., ycoor, -0.8));
1081 }
1082}
1083
1084TGeoVolume* Detector::coolingBarPiece(Double_t dx, Double_t dy, Double_t dz) const
1085{
1086 //
1087 // Returns the volume for one piece of a segmented longitudinal cooling bar, creating it the
1088 // first time that size is asked for. The pieces come in a handful of sizes that repeat all
1089 // along a supermodule, so each size becomes one volume placed many times. The sizes compare
1090 // exactly because every caller derives them from the same arithmetic.
1091 //
1092
1093 const std::array<Double_t, 3> key{dx, dy, dz};
1094 auto it = mBarPieces.find(key);
1095 if (it != mBarPieces.end()) {
1096 return it->second;
1097 }
1098
1099 const TString name = TString::Format("FLOS%zu", mBarPieces.size() + 1);
1100 auto* vol = new TGeoVolume(name, new TGeoBBox(name + "box", dx, dy, dz),
1101 o2::base::MaterialManager::Instance().getTGeoMedium(GetName(), kAlFrame)); // Al
1102 mBarPieces[key] = vol;
1103 return vol;
1104}
1105
1106void Detector::placeCoolingBar(const char* mother, const std::vector<FEAContainer>& cont, Double_t crateDZ,
1107 Double_t crateY0, Double_t crateY1, Double_t xcoor, Double_t dx, Double_t ycoor,
1108 Double_t dy, Double_t zcoor, Double_t dz, Int_t& copy) const
1109{
1110 //
1111 // Places one longitudinal cooling bar in mother, as the pieces that survive between the FEA
1112 // card containers it crosses. A bar crosses about nineteen of them, and they are placed ONLY
1113 // and so take priority over it. Advances copy past the pieces it places.
1114 //
1115
1116 const Double_t barZ0 = zcoor - dz, barZ1 = zcoor + dz;
1117 const Double_t barY0 = ycoor - dy, barY1 = ycoor + dy;
1118
1119 // the container slabs that really cut this bar, along z
1120 std::vector<std::pair<Double_t, Double_t>> cut;
1121 if (crateY1 > barY0 && crateY0 < barY1) {
1122 for (auto const& c : cont) {
1123 const Double_t z0 = std::max(barZ0, c.z - crateDZ);
1124 const Double_t z1 = std::min(barZ1, c.z + crateDZ);
1125 if (z1 > z0) {
1126 cut.emplace_back(z0, z1);
1127 }
1128 }
1129 std::sort(cut.begin(), cut.end());
1130 }
1131
1132 // the bar at full height, in the gaps between containers
1133 Double_t z = barZ0;
1134 for (auto const& c : cut) {
1135 if (c.first > z) {
1136 TVirtualMC::GetMC()->Gspos(coolingBarPiece(dx, dy, 0.5 * (c.first - z))->GetName(), ++copy, mother,
1137 xcoor, ycoor, 0.5 * (z + c.first), 0, "ONLY");
1138 }
1139 z = std::max(z, c.second);
1140 }
1141 if (barZ1 > z) {
1142 TVirtualMC::GetMC()->Gspos(coolingBarPiece(dx, dy, 0.5 * (barZ1 - z))->GetName(), ++copy, mother,
1143 xcoor, ycoor, 0.5 * (z + barZ1), 0, "ONLY");
1144 }
1145
1146 // and, where the bar is taller than the container it crosses, the strip that stands proud of it
1147 const Double_t strip[2][2] = {{barY0, std::min(barY1, crateY0)}, {std::max(barY0, crateY1), barY1}};
1148 for (auto const& c : cut) {
1149 for (auto const& sy : strip) {
1150 if (sy[1] <= sy[0]) {
1151 continue;
1152 }
1153 TVirtualMC::GetMC()->Gspos(coolingBarPiece(dx, 0.5 * (sy[1] - sy[0]), 0.5 * (c.second - c.first))->GetName(),
1154 ++copy, mother, xcoor, 0.5 * (sy[0] + sy[1]), 0.5 * (c.first + c.second), 0, "ONLY");
1155 }
1156 }
1157}
1158
1159void Detector::createBackZone(Double_t xtof, Double_t ytof, Double_t zlenA) const
1160{
1161 //
1162 // Define:
1163 // - containers for FEA cards, cooling system
1164 // signal cables and supermodule support structure
1165 // (volumes called FAIA/B/C),
1166 // - containers for FEA cards and some cooling
1167 // elements for a FEA (volumes called FCA1/2).
1168 //
1169
1170 Int_t idrotm[1] = {0};
1171
1172 // Definition of the air card containers (FAIA, FAIC and FAIB)
1173
1174 Double_t par[3];
1175 par[0] = xtof * 0.5;
1176 par[1] = (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5;
1177 par[2] = zlenA * 0.5;
1178 TVirtualMC::GetMC()->Gsvolu("FAIA", "BOX ", getMediumID(kAir), par, 3); // Air
1179 if (mTOFHoles) {
1180 TVirtualMC::GetMC()->Gsvolu("FAIB", "BOX ", getMediumID(kAir), par, 3); // Air
1181 }
1182 TVirtualMC::GetMC()->Gsvolu("FAIC", "BOX ", getMediumID(kAir), par, 3); // Air
1183
1184 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1185 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1186 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1187 // Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1188
1189 // FEA card mother-volume definition
1190 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1191 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1192 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1193 TVirtualMC::GetMC()->Gsvolu("FCA1", "BOX ", getMediumID(kAir), carpar, 3); // Air
1194 TVirtualMC::GetMC()->Gsvolu("FCA2", "BOX ", getMediumID(kAir), carpar, 3); // Air
1195
1196 // rotation matrix
1197 Matrix(idrotm[0], 90., 180., 90., 90., 180., 0.);
1198
1199 // FEA card mother-volume positioning
1200 Double_t carpos[3] = {0., (-(ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 + carpar[1]), -0.8};
1201
1202 for (auto const& c : feaContainers(zlenA, kFALSE)) {
1203 TVirtualMC::GetMC()->Gspos("FCA1", c.row, "FAIA", carpos[0], carpos[1], c.z, c.rotated ? idrotm[0] : 0, "ONLY");
1204 TVirtualMC::GetMC()->Gspos("FCA2", c.row, "FAIC", carpos[0], carpos[1], c.z, c.rotated ? idrotm[0] : 0, "ONLY");
1205 }
1206
1207 if (mTOFHoles) {
1208 for (auto const& c : feaContainers(zlenA, kTRUE)) {
1209 TVirtualMC::GetMC()->Gspos("FCA1", c.row, "FAIB", carpos[0], carpos[1], c.z, c.rotated ? idrotm[0] : 0, "ONLY");
1210 }
1211 }
1212}
1213
1214void Detector::makeFrontEndElectronics(Double_t xtof) const
1215{
1216 //
1217 // Fill FCA1/2 volumes with FEA cards (FFEA volumes).
1218 //
1219
1220 // FEA card volume definition
1221 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1222 TVirtualMC::GetMC()->Gsvolu("FFEA", "BOX ", getMediumID(kG10), feaParam, 3); // G10
1223
1224 Double_t al1[3] = {Geo::AL1PARAMETERS[0], Geo::AL1PARAMETERS[1], Geo::AL1PARAMETERS[2]};
1225 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1226 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1227 // Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1228
1229 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1230 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1231 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1232
1233 // FEA card volume positioning
1234 Double_t xCoor = xtof * 0.5 - 25.;
1235 Double_t yCoor = -carpar[1] + feaParam[1];
1236 Double_t zCoor = -carpar[2] + (2. * feaRoof1[2] - 2. * al1[2] - feaParam[2]);
1237 TVirtualMC::GetMC()->Gspos("FFEA", 1, "FCA1", -xCoor, yCoor, zCoor, 0, "ONLY");
1238 TVirtualMC::GetMC()->Gspos("FFEA", 4, "FCA1", xCoor, yCoor, zCoor, 0, "ONLY");
1239 TVirtualMC::GetMC()->Gspos("FFEA", 1, "FCA2", -xCoor, yCoor, zCoor, 0, "ONLY");
1240 TVirtualMC::GetMC()->Gspos("FFEA", 4, "FCA2", xCoor, yCoor, zCoor, 0, "ONLY");
1241 xCoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1242 TVirtualMC::GetMC()->Gspos("FFEA", 2, "FCA1", -xCoor, yCoor, zCoor, 0, "ONLY");
1243 TVirtualMC::GetMC()->Gspos("FFEA", 3, "FCA1", xCoor, yCoor, zCoor, 0, "ONLY");
1244 TVirtualMC::GetMC()->Gspos("FFEA", 2, "FCA2", -xCoor, yCoor, zCoor, 0, "ONLY");
1245 TVirtualMC::GetMC()->Gspos("FFEA", 3, "FCA2", xCoor, yCoor, zCoor, 0, "ONLY");
1246}
1247
1248void Detector::makeFEACooling(Double_t xtof) const
1249{
1250 //
1251 // Make cooling system attached to each FEA card
1252 // (FAL1, FRO1 and FBAR/1/2 volumes)
1253 // in FCA1/2 volume containers.
1254 //
1255
1256 // first FEA cooling element definition
1257 Double_t al1[3] = {Geo::AL1PARAMETERS[0], Geo::AL1PARAMETERS[1], Geo::AL1PARAMETERS[2]};
1258 TVirtualMC::GetMC()->Gsvolu("FAL1", "BOX ", getMediumID(kAlFrame), al1, 3); // Al
1259
1260 // second FEA cooling element definition: an Al roof with the FRO2 Nino-mask groove cut out of
1261 // its shape. The groove is oversized by kGrooveEps where it leaves the box, so that the two
1262 // solids share no face.
1263 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1264 Double_t airHole[3] = {Geo::ROOF2PARAMETERS[0], (Geo::ROOF2PARAMETERS[1] * 0.5), feaRoof1[2]};
1265 const Double_t kGrooveEps = 1.e-3; // cm
1266 new TGeoBBox("FRO1box", feaRoof1[0], feaRoof1[1], feaRoof1[2]);
1267 new TGeoBBox("FRO1groove", airHole[0], airHole[1] + kGrooveEps, airHole[2] + kGrooveEps);
1268 auto* fro1GrooveTr = new TGeoTranslation("FRO1grooveTr", 0., feaRoof1[1] - airHole[1] + kGrooveEps, 0.);
1269 fro1GrooveTr->RegisterYourself();
1270 auto* fro1Shape = new TGeoCompositeShape("FRO1shape", "FRO1box-(FRO1groove:FRO1grooveTr)");
1271 new TGeoVolume("FRO1", fro1Shape, o2::base::MaterialManager::Instance().getTGeoMedium(GetName(), kAlFrame)); // Al
1272
1273 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1274 // Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1275
1276 // third FEA cooling element definition
1277 Double_t bar[3] = {Geo::BAR[0], Geo::BAR[1], Geo::BAR[2]};
1278 TVirtualMC::GetMC()->Gsvolu("FBAR", "BOX ", getMediumID(kAlFrame), bar, 3); // Al
1279
1280 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1281
1282 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1283 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1284 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1285
1286 // fourth FEA cooling element definition
1287 Double_t bar1[3] = {Geo::BAR1[0], Geo::BAR1[1], Geo::BAR1[2]};
1288 TVirtualMC::GetMC()->Gsvolu("FBA1", "BOX ", getMediumID(kAlFrame), bar1, 3); // Al
1289
1290 // fifth FEA cooling element definition
1291 Double_t bar2[3] = {Geo::BAR2[0], Geo::BAR2[1], Geo::BAR2[2]};
1292 TVirtualMC::GetMC()->Gsvolu("FBA2", "BOX ", getMediumID(kAlFrame), bar2, 3); // Al
1293
1294 // first FEA cooling element positioning
1295 Double_t xcoor = xtof * 0.5 - 25.;
1296 Double_t ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - al1[1];
1297 Double_t zcoor = -carpar[2] + 2. * feaRoof1[2] - al1[2];
1298 TVirtualMC::GetMC()->Gspos("FAL1", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1299 TVirtualMC::GetMC()->Gspos("FAL1", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1300 TVirtualMC::GetMC()->Gspos("FAL1", 1, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1301 TVirtualMC::GetMC()->Gspos("FAL1", 4, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1302 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1303 TVirtualMC::GetMC()->Gspos("FAL1", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1304 TVirtualMC::GetMC()->Gspos("FAL1", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1305 TVirtualMC::GetMC()->Gspos("FAL1", 2, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1306 TVirtualMC::GetMC()->Gspos("FAL1", 3, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1307
1308 // second FEA cooling element positioning
1309 xcoor = xtof * 0.5 - 25.;
1310 ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - feaRoof1[1];
1311 zcoor = -carpar[2] + feaRoof1[2];
1312 TVirtualMC::GetMC()->Gspos("FRO1", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1313 TVirtualMC::GetMC()->Gspos("FRO1", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1314 TVirtualMC::GetMC()->Gspos("FRO1", 1, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1315 TVirtualMC::GetMC()->Gspos("FRO1", 4, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1316 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1317 TVirtualMC::GetMC()->Gspos("FRO1", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1318 TVirtualMC::GetMC()->Gspos("FRO1", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1319 TVirtualMC::GetMC()->Gspos("FRO1", 2, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1320 TVirtualMC::GetMC()->Gspos("FRO1", 3, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1321
1322 // third FEA cooling element positioning
1323 xcoor = xtof * 0.5 - 25.;
1324 ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - bar[1];
1325 zcoor = -carpar[2] + bar[2];
1326 TVirtualMC::GetMC()->Gspos("FBAR", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1327 TVirtualMC::GetMC()->Gspos("FBAR", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1328 TVirtualMC::GetMC()->Gspos("FBAR", 1, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1329 TVirtualMC::GetMC()->Gspos("FBAR", 4, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1330 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1331 TVirtualMC::GetMC()->Gspos("FBAR", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1332 TVirtualMC::GetMC()->Gspos("FBAR", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1333 TVirtualMC::GetMC()->Gspos("FBAR", 2, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1334 TVirtualMC::GetMC()->Gspos("FBAR", 3, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1335
1336 // fourth FEA cooling element positioning
1337 Double_t tubepar[3] = {0., 0.4, (xtof * 0.5 - Geo::CBLW)};
1338 xcoor = xtof * 0.5 - 25.;
1339 ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - bar[1];
1340 zcoor = -carpar[2] + 2. * bar[2] + 2. * tubepar[1] + bar1[2];
1341 TVirtualMC::GetMC()->Gspos("FBA1", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1342 TVirtualMC::GetMC()->Gspos("FBA1", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1343 TVirtualMC::GetMC()->Gspos("FBA1", 1, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1344 TVirtualMC::GetMC()->Gspos("FBA1", 4, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1345 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1346 TVirtualMC::GetMC()->Gspos("FBA1", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1347 TVirtualMC::GetMC()->Gspos("FBA1", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1348 TVirtualMC::GetMC()->Gspos("FBA1", 2, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1349 TVirtualMC::GetMC()->Gspos("FBA1", 3, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1350
1351 // fifth FEA cooling element positioning
1352 xcoor = xtof * 0.5 - 25.;
1353 ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - bar2[1];
1354 zcoor = -carpar[2] + 2. * bar[2] + bar2[2];
1355 TVirtualMC::GetMC()->Gspos("FBA2", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1356 TVirtualMC::GetMC()->Gspos("FBA2", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1357 TVirtualMC::GetMC()->Gspos("FBA2", 1, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1358 TVirtualMC::GetMC()->Gspos("FBA2", 4, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1359 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1360 TVirtualMC::GetMC()->Gspos("FBA2", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1361 TVirtualMC::GetMC()->Gspos("FBA2", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1362 TVirtualMC::GetMC()->Gspos("FBA2", 2, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1363 TVirtualMC::GetMC()->Gspos("FBA2", 3, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1364
1365 xcoor = xtof * 0.5 - 25.;
1366 ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - 2. * bar2[1] - 2. * tubepar[1] - bar2[1];
1367 zcoor = -carpar[2] + 2. * bar[2] + bar2[2];
1368 TVirtualMC::GetMC()->Gspos("FBA2", 5, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1369 TVirtualMC::GetMC()->Gspos("FBA2", 8, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1370 TVirtualMC::GetMC()->Gspos("FBA2", 5, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1371 TVirtualMC::GetMC()->Gspos("FBA2", 8, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1372 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1373 TVirtualMC::GetMC()->Gspos("FBA2", 6, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1374 TVirtualMC::GetMC()->Gspos("FBA2", 7, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1375 TVirtualMC::GetMC()->Gspos("FBA2", 6, "FCA2", -xcoor, ycoor, zcoor, 0, "ONLY");
1376 TVirtualMC::GetMC()->Gspos("FBA2", 7, "FCA2", xcoor, ycoor, zcoor, 0, "ONLY");
1377}
1378
1379void Detector::makeNinoMask(Double_t xtof) const
1380{
1381 //
1382 // Make cooling Nino mask
1383 // for each FEA card (FAL2/3 and FRO2 volumes)
1384 // in FCA1 volume container.
1385 //
1386
1387 // first Nino ASIC mask volume definition
1388 Double_t al2[3] = {Geo::AL2PARAMETERS[0], Geo::AL2PARAMETERS[1], Geo::AL2PARAMETERS[2]};
1389 TVirtualMC::GetMC()->Gsvolu("FAL2", "BOX ", getMediumID(kAlFrame), al2, 3); // Al
1390
1391 // second Nino ASIC mask volume definition
1392 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1393 TVirtualMC::GetMC()->Gsvolu("FAL3", "BOX ", getMediumID(kAlFrame), al3, 3); // Al
1394
1395 // third Nino ASIC mask volume definition
1396 Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1397 TVirtualMC::GetMC()->Gsvolu("FRO2", "BOX ", getMediumID(kAlFrame), feaRoof2, 3); // Al
1398
1399 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1400 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1401
1402 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1403 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1404 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1405
1406 // first Nino ASIC mask volume positioning
1407 Double_t xcoor = xtof * 0.5 - 25.;
1408 Double_t ycoor = carpar[1] - 2. * al3[1];
1409 Double_t zcoor = carpar[2] - 2. * al3[2] - al2[2];
1410 TVirtualMC::GetMC()->Gspos("FAL2", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1411 TVirtualMC::GetMC()->Gspos("FAL2", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1412 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1413 TVirtualMC::GetMC()->Gspos("FAL2", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1414 TVirtualMC::GetMC()->Gspos("FAL2", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1415
1416 // second Nino ASIC mask volume positioning
1417 xcoor = xtof * 0.5 - 25.;
1418 ycoor = carpar[1] - al3[1];
1419 zcoor = carpar[2] - al3[2];
1420 TVirtualMC::GetMC()->Gspos("FAL3", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1421 TVirtualMC::GetMC()->Gspos("FAL3", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1422 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1423 TVirtualMC::GetMC()->Gspos("FAL3", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1424 TVirtualMC::GetMC()->Gspos("FAL3", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1425
1426 // third Nino ASIC mask volume positioning
1427 xcoor = xtof * 0.5 - 25.;
1428 ycoor = carpar[1] - Geo::ROOF2PARAMETERS[1];
1429 zcoor = carpar[2] - 2. * al3[2] - Geo::ROOF2PARAMETERS[2];
1430 TVirtualMC::GetMC()->Gspos("FRO2", 1, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1431 TVirtualMC::GetMC()->Gspos("FRO2", 4, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1432 xcoor = feaParam[0] + (Geo::FEAWIDTH2 * 0.5 - Geo::FEAWIDTH1);
1433 TVirtualMC::GetMC()->Gspos("FRO2", 2, "FCA1", -xcoor, ycoor, zcoor, 0, "ONLY");
1434 TVirtualMC::GetMC()->Gspos("FRO2", 3, "FCA1", xcoor, ycoor, zcoor, 0, "ONLY");
1435}
1436
1437void Detector::makeSuperModuleCooling(Double_t xtof, Double_t ytof, Double_t zlenA) const
1438{
1439 //
1440 // Make cooling tubes (FTUB volume)
1441 // and cooling bars (FTLN and FLO1/2/3 volumes)
1442 // in FAIA/B/C volume containers.
1443 //
1444
1445 Int_t idrotm[1] = {0};
1446
1447 // cooling tube volume definition
1448 Double_t tubepar[3] = {0., 0.4, (xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS)};
1449 TVirtualMC::GetMC()->Gsvolu("FTUB", "TUBE", getMediumID(kCopper), tubepar, 3); // Cu
1450
1451 // water cooling tube volume definition
1452 Double_t tubeparW[3] = {0., 0.3, tubepar[2]};
1453 TVirtualMC::GetMC()->Gsvolu("FITU", "TUBE", getMediumID(kWater), tubeparW, 3); // H2O
1454
1455 // Positioning of the water tube into the steel one
1456 TVirtualMC::GetMC()->Gspos("FITU", 1, "FTUB", 0., 0., 0., 0, "ONLY");
1457
1458 // definition of transverse components of SM cooling system
1459 Double_t trapar[3] = {tubepar[2], 6.175 /*6.15*/, 0.7};
1460 TVirtualMC::GetMC()->Gsvolu("FTLN", "BOX ", getMediumID(kAlFrame), trapar, 3); // Al
1461
1462 // rotation matrix
1463 Matrix(idrotm[0], 180., 90., 90., 90., 90., 0.);
1464
1465 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1466 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1467 Double_t bar[3] = {Geo::BAR[0], Geo::BAR[1], Geo::BAR[2]};
1468 Double_t bar2[3] = {Geo::BAR2[0], Geo::BAR2[1], Geo::BAR2[2]};
1469 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1470 // Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1471
1472 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1473 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1474 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1475
1476 Double_t ytub = -(ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 + carpar[1] + carpar[1] -
1477 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - 2. * bar2[1] - tubepar[1];
1478
1479 // Positioning of tubes for the SM cooling system
1480 Double_t ycoor = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - 2. * bar2[1] - tubepar[1];
1481 Double_t zcoor = -carpar[2] + 2. * bar[2] + tubepar[1];
1482 TVirtualMC::GetMC()->Gspos("FTUB", 1, "FCA1", 0., ycoor, zcoor, idrotm[0], "ONLY");
1483 TVirtualMC::GetMC()->Gspos("FTUB", 1, "FCA2", 0., ycoor, zcoor, idrotm[0], "ONLY");
1484 gGeoManager->GetVolume("FTUB")->VisibleDaughters(kFALSE);
1485
1486 Double_t yFLTN = trapar[1] - (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5;
1487 for (Int_t sg = -1; sg < 2; sg += 2) {
1488 // Positioning of transverse components for the SM cooling system
1489 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 4 * sg, "FAIA", 0., yFLTN, 369.9 * sg, 0, "ONLY");
1490 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 3 * sg, "FAIA", 0., yFLTN, 366.9 * sg, 0, "ONLY");
1491 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 2 * sg, "FAIA", 0., yFLTN, 198.8 * sg, 0, "ONLY");
1492 TVirtualMC::GetMC()->Gspos("FTLN", 5 + sg, "FAIA", 0., yFLTN, 56.82 * sg, 0, "ONLY");
1493 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 4 * sg, "FAIC", 0., yFLTN, 369.9 * sg, 0, "ONLY");
1494 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 3 * sg, "FAIC", 0., yFLTN, 366.9 * sg, 0, "ONLY");
1495 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 2 * sg, "FAIC", 0., yFLTN, 198.8 * sg, 0, "ONLY");
1496 TVirtualMC::GetMC()->Gspos("FTLN", 5 + sg, "FAIC", 0., yFLTN, 56.82 * sg, 0, "ONLY");
1497 }
1498
1499 // definition of longitudinal components of SM cooling system
1500 Double_t lonpar1[3] = {2., 0.5, 56.82 - trapar[2]};
1501 Double_t lonpar2[3] = {lonpar1[0], lonpar1[1], (198.8 - 56.82) * 0.5 - trapar[2]};
1502 Double_t lonpar3[3] = {lonpar1[0], lonpar1[1], (366.9 - 198.8) * 0.5 - trapar[2]};
1503 // Positioning of the longitudinal components of the SM cooling system, segmented between the
1504 // FEA card containers rather than declared overlapping.
1505 mBarPieces.clear();
1506 const std::vector<FEAContainer> contFull = feaContainers(zlenA, kFALSE);
1507 const std::vector<FEAContainer> contHoles = feaContainers(zlenA, kTRUE);
1508 const Double_t crateY = -(ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 + carpar[1];
1509 const Double_t crateY0 = crateY - carpar[1], crateY1 = crateY + carpar[1];
1510 const Double_t zcoor2 = (198.8 + 56.82) * 0.5;
1511 const Double_t zcoor3 = (366.9 + 198.8) * 0.5;
1512 Int_t copyA = 0, copyB = 0, copyC = 0;
1513
1514 for (Int_t up = 0; up < 2; ++up) {
1515 ycoor = up ? ytub + (tubepar[1] + 2. * bar2[1] + lonpar1[1]) : ytub - (tubepar[1] + 2. * bar2[1] + lonpar1[1]);
1516 for (Int_t sx = -1; sx < 2; sx += 2) {
1517 placeCoolingBar("FAIA", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar1[0], ycoor, lonpar1[1], 0.,
1518 lonpar1[2], copyA);
1519 placeCoolingBar("FAIC", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar1[0], ycoor, lonpar1[1], 0.,
1520 lonpar1[2], copyC);
1521 for (Int_t sz = -1; sz < 2; sz += 2) {
1522 placeCoolingBar("FAIA", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar2[0], ycoor, lonpar2[1],
1523 sz * zcoor2, lonpar2[2], copyA);
1524 placeCoolingBar("FAIC", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar2[0], ycoor, lonpar2[1],
1525 sz * zcoor2, lonpar2[2], copyC);
1526 placeCoolingBar("FAIA", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar3[0], ycoor, lonpar3[1],
1527 sz * zcoor3, lonpar3[2], copyA);
1528 placeCoolingBar("FAIC", contFull, carpar[2], crateY0, crateY1, sx * 24., lonpar3[0], ycoor, lonpar3[1],
1529 sz * zcoor3, lonpar3[2], copyC);
1530 }
1531 }
1532 }
1533
1534 Double_t carpos[3] = {(25. - xtof * 0.5),
1535 ((11.5 - (ytof * 0.5 - Geo::MODULECOVERTHICKNESS)) * 0.5), 0.};
1536 if (mTOFHoles) {
1537 for (Int_t sg = -1; sg < 2; sg += 2) {
1538 carpos[2] = sg * zlenA * 0.5;
1539 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 4 * sg, "FAIB", 0., yFLTN, 369.9 * sg, 0, "ONLY");
1540 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 3 * sg, "FAIB", 0., yFLTN, 366.9 * sg, 0, "ONLY");
1541 TVirtualMC::GetMC()->Gspos("FTLN", 5 + 2 * sg, "FAIB", 0., yFLTN, 198.8 * sg, 0, "ONLY");
1542 TVirtualMC::GetMC()->Gspos("FTLN", 5 + sg, "FAIB", 0., yFLTN, 56.82 * sg, 0, "ONLY");
1543 }
1544
1545 // the modules with the PHOS hole carry one x side per cooling layer, and no FLO1 bar
1546 for (Int_t up = 0; up < 2; ++up) {
1547 ycoor = up ? ytub + (tubepar[1] + 2. * bar2[1] + lonpar1[1]) : ytub - (tubepar[1] + 2. * bar2[1] + lonpar1[1]);
1548 const Double_t xcoor = up ? -24. : 24.;
1549 for (Int_t sz = -1; sz < 2; sz += 2) {
1550 placeCoolingBar("FAIB", contHoles, carpar[2], crateY0, crateY1, xcoor, lonpar2[0], ycoor, lonpar2[1],
1551 sz * zcoor2, lonpar2[2], copyB);
1552 placeCoolingBar("FAIB", contHoles, carpar[2], crateY0, crateY1, xcoor, lonpar3[0], ycoor, lonpar3[1],
1553 sz * zcoor3, lonpar3[2], copyB);
1554 }
1555 }
1556 }
1557
1558 Double_t barS[3] = {Geo::BARS[0], Geo::BARS[1], Geo::BARS[2]};
1559 TVirtualMC::GetMC()->Gsvolu("FBAS", "BOX ", getMediumID(kAlFrame), barS, 3); // Al
1560
1561 Double_t barS1[3] = {Geo::BARS1[0], Geo::BARS1[1], Geo::BARS1[2]};
1562 TVirtualMC::GetMC()->Gsvolu("FBS1", "BOX ", getMediumID(kAlFrame), barS1, 3); // Al
1563
1564 Double_t barS2[3] = {Geo::BARS2[0], Geo::BARS2[1], Geo::BARS2[2]};
1565 TVirtualMC::GetMC()->Gsvolu("FBS2", "BOX ", getMediumID(kAlFrame), barS2, 3); // Al
1566
1567 Double_t ytubBis = carpar[1] - 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - 2. * barS2[1] - tubepar[1];
1568 ycoor = ytubBis;
1569 zcoor = -carpar[2] + barS[2];
1570 TVirtualMC::GetMC()->Gspos("FBAS", 1, "FCA1", -24., ycoor, zcoor, 0, "ONLY");
1571 TVirtualMC::GetMC()->Gspos("FBAS", 2, "FCA1", 24., ycoor, zcoor, 0, "ONLY");
1572 TVirtualMC::GetMC()->Gspos("FBAS", 1, "FCA2", -24., ycoor, zcoor, 0, "ONLY");
1573 TVirtualMC::GetMC()->Gspos("FBAS", 2, "FCA2", 24., ycoor, zcoor, 0, "ONLY");
1574
1575 zcoor = -carpar[2] + 2. * barS[2] + 2. * tubepar[1] + barS1[2];
1576 TVirtualMC::GetMC()->Gspos("FBS1", 1, "FCA1", -24., ycoor, zcoor, 0, "ONLY");
1577 TVirtualMC::GetMC()->Gspos("FBS1", 2, "FCA1", 24., ycoor, zcoor, 0, "ONLY");
1578 TVirtualMC::GetMC()->Gspos("FBS1", 1, "FCA2", -24., ycoor, zcoor, 0, "ONLY");
1579 TVirtualMC::GetMC()->Gspos("FBS1", 2, "FCA2", 24., ycoor, zcoor, 0, "ONLY");
1580
1581 ycoor = ytubBis + (tubepar[1] + barS2[1]);
1582 zcoor = -carpar[2] + 2. * barS[2] + barS2[2];
1583 TVirtualMC::GetMC()->Gspos("FBS2", 1, "FCA1", -24., ycoor, zcoor, 0, "ONLY");
1584 TVirtualMC::GetMC()->Gspos("FBS2", 2, "FCA1", 24., ycoor, zcoor, 0, "ONLY");
1585 TVirtualMC::GetMC()->Gspos("FBS2", 1, "FCA2", -24., ycoor, zcoor, 0, "ONLY");
1586 TVirtualMC::GetMC()->Gspos("FBS2", 2, "FCA2", 24., ycoor, zcoor, 0, "ONLY");
1587
1588 ycoor = ytubBis - (tubepar[1] + barS2[1]);
1589 // zcoor =-carpar[2] + 2.*barS[2] + barS2[2];
1590 TVirtualMC::GetMC()->Gspos("FBS2", 3, "FCA1", -24., ycoor, zcoor, 0, "ONLY");
1591 TVirtualMC::GetMC()->Gspos("FBS2", 4, "FCA1", 24., ycoor, zcoor, 0, "ONLY");
1592 TVirtualMC::GetMC()->Gspos("FBS2", 3, "FCA2", -24., ycoor, zcoor, 0, "ONLY");
1593 TVirtualMC::GetMC()->Gspos("FBS2", 4, "FCA2", 24., ycoor, zcoor, 0, "ONLY");
1594}
1595
1596//_____________________________________________________________________________
1597void Detector::makeSuperModuleServices(Double_t xtof, Double_t ytof, Double_t zlenA) const
1598{
1599 //
1600 // Make signal cables (FCAB/L and FCBL/B volumes),
1601 // supemodule cover (FCOV volume) and wall (FSAW volume)
1602 // in FAIA/B/C volume containers.
1603 //
1604
1605 Int_t idrotm[3] = {0, 0, 0};
1606
1607 Double_t tubepar[3] = {0., 0.4, (xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS)};
1608 Double_t al1[3] = {Geo::AL1PARAMETERS[0], Geo::AL1PARAMETERS[1], Geo::AL1PARAMETERS[2]};
1609 Double_t al3[3] = {Geo::AL3PARAMETERS[0], Geo::AL3PARAMETERS[1], Geo::AL3PARAMETERS[2]};
1610 Double_t feaRoof1[3] = {Geo::ROOF1PARAMETERS[0], Geo::ROOF1PARAMETERS[1], Geo::ROOF1PARAMETERS[2]};
1611 // Double_t feaRoof2[3] = {Geo::ROOF2PARAMETERS[0], Geo::ROOF2PARAMETERS[1], Geo::ROOF2PARAMETERS[2]};
1612 Double_t feaParam[3] = {Geo::FEAPARAMETERS[0], Geo::FEAPARAMETERS[1], Geo::FEAPARAMETERS[2]};
1613
1614 // FEA cables definition
1615 Double_t cbpar[3] = {0., 0.5,
1616 ((tubepar[2] - (Geo::FEAWIDTH2 - Geo::FEAWIDTH1 / 6.) * 0.5) * 0.5)};
1617 TVirtualMC::GetMC()->Gsvolu("FCAB", "TUBE", getMediumID(kCable), cbpar, 3); // copper+alu
1618
1619 Double_t cbparS[3] = {cbpar[0], cbpar[1],
1620 (
1621 (tubepar[2] - (xtof * 0.5 - 25. + (Geo::FEAWIDTH1 - Geo::FEAWIDTH1 / 6.) * 0.5)) * 0.5)};
1622 TVirtualMC::GetMC()->Gsvolu("FCAL", "TUBE", getMediumID(kCable), cbparS, 3); // copper+alu
1623
1624 // rotation matrix
1625 Matrix(idrotm[0], 180., 90., 90., 90., 90., 0.);
1626
1627 Double_t carpar[3] = {(xtof * 0.5 - Geo::CBLW - Geo::SAWTHICKNESS),
1628 (feaParam[1] + feaRoof1[1] + Geo::ROOF2PARAMETERS[1] * 0.5),
1629 (feaRoof1[2] + Geo::BETWEENLANDMASK * 0.5 + al3[2])};
1630
1631 Double_t bar2[3] = {Geo::BAR2[0], Geo::BAR2[1], Geo::BAR2[2]};
1632 Double_t ytub = -(ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 + carpar[1] + carpar[1] -
1633 2. * Geo::ROOF2PARAMETERS[1] * 0.5 - 2. * feaRoof1[1] - 2. * bar2[1] - tubepar[1];
1634
1635 // FEA cables positioning
1636 Double_t xcoor = (tubepar[2] + (Geo::FEAWIDTH2 - Geo::FEAWIDTH1 / 6.) * 0.5) * 0.5;
1637 Double_t ycoor = ytub - 3.;
1638 Double_t zcoor = -carpar[2] + (2. * feaRoof1[2] - 2. * al1[2] - 2. * feaParam[2] - cbpar[1]);
1639 TVirtualMC::GetMC()->Gspos("FCAB", 1, "FCA1", -xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1640 TVirtualMC::GetMC()->Gspos("FCAB", 2, "FCA1", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1641 TVirtualMC::GetMC()->Gspos("FCAB", 1, "FCA2", -xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1642 TVirtualMC::GetMC()->Gspos("FCAB", 2, "FCA2", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1643 xcoor = (tubepar[2] + (xtof * 0.5 - 25. + (Geo::FEAWIDTH1 - Geo::FEAWIDTH1 / 6.) * 0.5)) * 0.5;
1644 ycoor -= 2. * cbpar[1];
1645 TVirtualMC::GetMC()->Gspos("FCAL", 1, "FCA1", -xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1646 TVirtualMC::GetMC()->Gspos("FCAL", 2, "FCA1", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1647 TVirtualMC::GetMC()->Gspos("FCAL", 1, "FCA2", -xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1648 TVirtualMC::GetMC()->Gspos("FCAL", 2, "FCA2", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1649
1650 // Cables and tubes on the side blocks
1651 // constants definition
1652 Double_t kCBLl = zlenA * 0.5; // length of block
1653 Double_t kCBLlh = zlenA * 0.5 - Geo::INTERCENTRMODBORDER2; // length of block in case of holes
1654 // constexpr Double_t Geo::CBLW = 13.5; // width of block
1655 // constexpr Double_t Geo::CBLH1 = 2.; // min. height of block
1656 // constexpr Double_t Geo::CBLH2 = 12.3; // max. height of block
1657 // constexpr Double_t Geo::SAWTHICKNESS = 1.; // Al wall thickness
1658
1659 // lateral cable and tube volume definition
1660 Double_t tgal = (Geo::CBLH2 - Geo::CBLH1) / (2. * kCBLl);
1661 Double_t cblpar[11];
1662 cblpar[0] = Geo::CBLW * 0.5;
1663 cblpar[1] = 0.;
1664 cblpar[2] = 0.;
1665 cblpar[3] = kCBLl * 0.5;
1666 cblpar[4] = Geo::CBLH1 * 0.5;
1667 cblpar[5] = Geo::CBLH2 * 0.5;
1668 cblpar[6] = TMath::ATan(tgal) * TMath::RadToDeg();
1669 cblpar[7] = kCBLl * 0.5;
1670 cblpar[8] = Geo::CBLH1 * 0.5;
1671 cblpar[9] = Geo::CBLH2 * 0.5;
1672 cblpar[10] = cblpar[6];
1673 TVirtualMC::GetMC()->Gsvolu("FCBL", "TRAP", getMediumID(kCableTubes), cblpar, 11); // cables and tubes mix
1674
1675 // Side Al Walls definition
1676 Double_t sawpar[3] = {(Geo::SAWTHICKNESS * 0.5), (Geo::CBLH2 * 0.5), kCBLl};
1677 TVirtualMC::GetMC()->Gsvolu("FSAW", "BOX ", getMediumID(kAlFrame), sawpar, 3); // Al
1678
1679 Matrix(idrotm[1], 90., 90., 180., 0., 90., 180.);
1680 Matrix(idrotm[2], 90., 90., 0., 0., 90., 0.);
1681
1682 // lateral cable and tube volume positioning
1683 xcoor = (xtof - Geo::CBLW) * 0.5 - 2. * sawpar[0];
1684 ycoor = (Geo::CBLH1 + Geo::CBLH2) * 0.25 - (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5;
1685 zcoor = kCBLl * 0.5;
1686 TVirtualMC::GetMC()->Gspos("FCBL", 1, "FAIA", -xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1687 TVirtualMC::GetMC()->Gspos("FCBL", 2, "FAIA", xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1688 TVirtualMC::GetMC()->Gspos("FCBL", 3, "FAIA", -xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1689 TVirtualMC::GetMC()->Gspos("FCBL", 4, "FAIA", xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1690 TVirtualMC::GetMC()->Gspos("FCBL", 1, "FAIC", -xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1691 TVirtualMC::GetMC()->Gspos("FCBL", 2, "FAIC", xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1692 TVirtualMC::GetMC()->Gspos("FCBL", 3, "FAIC", -xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1693 TVirtualMC::GetMC()->Gspos("FCBL", 4, "FAIC", xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1694
1695 if (mTOFHoles) {
1696 cblpar[3] = kCBLlh * 0.5;
1697 cblpar[5] = Geo::CBLH1 * 0.5 + kCBLlh * tgal;
1698 cblpar[7] = kCBLlh * 0.5;
1699 cblpar[9] = cblpar[5];
1700 TVirtualMC::GetMC()->Gsvolu("FCBB", "TRAP", getMediumID(kCableTubes), cblpar, 11); // cables and tubes mix
1701
1702 xcoor = (xtof - Geo::CBLW) * 0.5 - 2. * sawpar[0];
1703 ycoor = (Geo::CBLH1 + 2. * cblpar[5]) * 0.25 - (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5;
1704 zcoor = kCBLl - kCBLlh * 0.5;
1705 TVirtualMC::GetMC()->Gspos("FCBB", 1, "FAIB", -xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1706 TVirtualMC::GetMC()->Gspos("FCBB", 2, "FAIB", xcoor, ycoor, -zcoor, idrotm[1], "ONLY");
1707 TVirtualMC::GetMC()->Gspos("FCBB", 3, "FAIB", -xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1708 TVirtualMC::GetMC()->Gspos("FCBB", 4, "FAIB", xcoor, ycoor, zcoor, idrotm[2], "ONLY");
1709 }
1710
1711 // lateral cable and tube volume positioning
1712 xcoor = xtof * 0.5 - sawpar[0];
1713 ycoor = (Geo::CBLH2 - ytof * 0.5 + Geo::MODULECOVERTHICKNESS) * 0.5;
1714 zcoor = 0.;
1715 TVirtualMC::GetMC()->Gspos("FSAW", 1, "FAIA", -xcoor, ycoor, zcoor, 0, "ONLY");
1716 TVirtualMC::GetMC()->Gspos("FSAW", 2, "FAIA", xcoor, ycoor, zcoor, 0, "ONLY");
1717 TVirtualMC::GetMC()->Gspos("FSAW", 1, "FAIC", -xcoor, ycoor, zcoor, 0, "ONLY");
1718 TVirtualMC::GetMC()->Gspos("FSAW", 2, "FAIC", xcoor, ycoor, zcoor, 0, "ONLY");
1719
1720 if (mTOFHoles) {
1721 xcoor = xtof * 0.5 - sawpar[0];
1722 ycoor = (Geo::CBLH2 - ytof * 0.5 + Geo::MODULECOVERTHICKNESS) * 0.5;
1723 TVirtualMC::GetMC()->Gspos("FSAW", 1, "FAIB", -xcoor, ycoor, 0., 0, "ONLY");
1724 TVirtualMC::GetMC()->Gspos("FSAW", 2, "FAIB", xcoor, ycoor, 0., 0, "ONLY");
1725 }
1726
1727 // TOF Supermodule cover definition and positioning
1728 Double_t covpar[3] = {(xtof * 0.5), 0.075, (zlenA * 0.5)};
1729 TVirtualMC::GetMC()->Gsvolu("FCOV", "BOX ", getMediumID(kAlFrame), covpar, 3); // Al
1730 if (mTOFHoles) {
1731 covpar[2] = (zlenA * 0.5 - Geo::INTERCENTRMODBORDER2) * 0.5;
1732 TVirtualMC::GetMC()->Gsvolu("FCOB", "BOX ", getMediumID(kAlFrame), covpar, 3); // Al
1733 covpar[2] = Geo::INTERCENTRMODBORDER2;
1734 TVirtualMC::GetMC()->Gsvolu("FCOP", "BOX ", getMediumID(kPlastic), covpar, 3); // Plastic (CH2)
1735 }
1736
1737 xcoor = 0.;
1738 ycoor = (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5 - covpar[1];
1739 zcoor = 0.;
1740 TVirtualMC::GetMC()->Gspos("FCOV", 0, "FAIA", xcoor, ycoor, zcoor, 0, "ONLY");
1741 TVirtualMC::GetMC()->Gspos("FCOV", 0, "FAIC", xcoor, ycoor, zcoor, 0, "ONLY");
1742 if (mTOFHoles) {
1743 zcoor = (zlenA * 0.5 + Geo::INTERCENTRMODBORDER2) * 0.5;
1744 TVirtualMC::GetMC()->Gspos("FCOB", 1, "FAIB", xcoor, ycoor, zcoor, 0, "ONLY");
1745 TVirtualMC::GetMC()->Gspos("FCOB", 2, "FAIB", xcoor, ycoor, -zcoor, 0, "ONLY");
1746 zcoor = 0.;
1747 TVirtualMC::GetMC()->Gspos("FCOP", 0, "FAIB", xcoor, ycoor, zcoor, 0, "ONLY");
1748 }
1749}
1750
1751//_____________________________________________________________________________
1752void Detector::makeReadoutCrates(Double_t ytof) const
1753{
1754 // Services Volumes
1755
1756 // Empty crate weight: 50 Kg, electronics cards + cables ~ 52 Kg.
1757 // Per each side (A and C) the total weight is: 2x102 ~ 204 Kg.
1758 // ... + weight of the connection pannel for the steel cooling system (Cr 18%, Ni 12%, Fe 70%)
1759 // + other remaining elements + various supports
1760
1761 // Each FEA card weight + all supports
1762 // (including all bolts and not including the cable connectors)
1763 // 353.1 g.
1764 // Per each strip there are 4 FEA cards, then
1765 // the total weight of the front-end electonics section is: 353.1 g x 4 = 1412.4 g.
1766
1767 // Services Volumes
1768
1769 // Empty crate weight: 50 Kg, electronics cards + cables ~ 52 Kg.
1770 // Per each side (A and C) the total weight is: 2x102 ~ 204 Kg.
1771 // ... + weight of the connection pannel for the steel cooling system (Cr 18%, Ni 12%, Fe 70%)
1772 // + other remaining elements + various supports
1773
1774 // Each FEA card weight + all supports
1775 // (including all bolts and not including the cable connectors)
1776 // 353.1 g.
1777 // Per each strip there are 4 FEA cards, then
1778 // the total weight of the front-end electonics section is: 353.1 g x 4 = 1412.4 g.
1779 //
1780
1781 Int_t idrotm[Geo::NSECTORS];
1782 for (Int_t ii = 0; ii < Geo::NSECTORS; ii++) {
1783 idrotm[ii] = 0;
1784 }
1785
1786 // volume definition
1787 Double_t serpar[3] = {29. * 0.5, 121. * 0.5, 90. * 0.5};
1788 TVirtualMC::GetMC()->Gsvolu("FTOS", "BOX ", getMediumID(kCrates), serpar, 3); // Al + Cu + steel
1789
1790 Double_t xcoor, ycoor, zcoor;
1791 zcoor = (118. - 90.) * 0.5;
1792 Double_t phi = -10., ra = Geo::RMIN + ytof * 0.5;
1793 for (Int_t i = 0; i < Geo::NSECTORS; i++) {
1794 phi += Geo::PHISEC;
1795 xcoor = ra * TMath::Cos(phi * TMath::DegToRad());
1796 ycoor = ra * TMath::Sin(phi * TMath::DegToRad());
1797 Matrix(idrotm[i], 90., phi, 90., phi + 270., 0., 0.);
1798 TVirtualMC::GetMC()->Gspos("FTOS", i, "BFMO", xcoor, ycoor, zcoor, idrotm[i], "ONLY");
1799 }
1800
1801 zcoor = (90. - 223.) * 0.5;
1802 TVirtualMC::GetMC()->Gspos("FTOS", 1, "BBCE", ra, -3., zcoor, 0, "ONLY");
1803}
1804
1805void Detector::makeModulesInBTOFvolumes(Double_t ytof, Double_t zlenA) const
1806{
1807 //
1808 // Fill BTOF_%i (for i=0,...17) volumes
1809 // with volumes FTOA (MRPC strip container),
1810 // In case of TOF holes, three sectors (i.e. 13th, 14th and 15th)
1811 // are filled with volumes: FTOB and FTOC (MRPC containers),
1812 //
1813
1814 constexpr Int_t SIZESTR = 16;
1815
1816 Int_t idrotm[1] = {0};
1817
1818 // Matrix(idrotm[0], 90., 0., 0., 0., 90.,-90.);
1819 Matrix(idrotm[0], 90., 0., 0., 0., 90., 270.);
1820
1821 Double_t xcoor, ycoor, zcoor;
1822 xcoor = 0.;
1823
1824 // Positioning of fibre glass modules (FTOA, FTOB and FTOC)
1825 for (Int_t isec = 0; isec < Geo::NSECTORS; isec++) {
1826 if (mTOFSectors[isec] == -1) {
1827 continue;
1828 }
1829
1830 char name[SIZESTR];
1831 snprintf(name, SIZESTR, "BTOF%d", isec);
1832 if (mTOFHoles && (isec == 13 || isec == 14 || isec == 15)) {
1833 // xcoor = 0.;
1834 ycoor = (zlenA * 0.5 + Geo::INTERCENTRMODBORDER1) * 0.5;
1835 zcoor = -ytof * 0.25;
1836 TVirtualMC::GetMC()->Gspos("FTOB", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1837 TVirtualMC::GetMC()->Gspos("FTOC", 0, name, xcoor, -ycoor, zcoor, idrotm[0], "ONLY");
1838 } else {
1839 // xcoor = 0.;
1840 ycoor = 0.;
1841 zcoor = -ytof * 0.25;
1842 TVirtualMC::GetMC()->Gspos("FTOA", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1843 }
1844 }
1845
1846 // float par[3] = {100,500,10};
1847 // TVirtualMC::GetMC()->Gsvolu("FTEM", "BOX ", getMediumID(kAlFrame), par, 3); // Fibre glass
1848 // ycoor = 0.;
1849 // zcoor = 350;
1850 // TVirtualMC::GetMC()->Gspos("FTEM", 0, "cave", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1851
1852 // TVirtualMC::GetMC()->Gspos("FTOA", 0, "cave", xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1853}
1854
1855void Detector::makeCoversInBTOFvolumes() const
1856{
1857 //
1858 // Fill BTOF_%i (for i=0,...17) volumes
1859 // with volumes FPEA (to separate strips from FEA cards)
1860 // In case of TOF holes, three sectors (i.e. 13th, 14th and 15th)
1861 // are filled with FPEB volumes
1862 // (to separate MRPC strips from FEA cards)
1863 //
1864
1865 constexpr Int_t SIZESTR = 16;
1866
1867 Int_t idrotm[1] = {0};
1868
1869 // Matrix(idrotm[0], 90., 0., 0., 0., 90.,-90.);
1870 Matrix(idrotm[0], 90., 0., 0., 0., 90., 270.);
1871
1872 Double_t xcoor, ycoor, zcoor;
1873 xcoor = 0.;
1874 ycoor = 0.;
1875 zcoor = Geo::MODULECOVERTHICKNESS * 0.5;
1876
1877 char name[SIZESTR];
1878
1879 // Positioning of module covers (FPEA, FPEB)
1880 for (Int_t isec = 0; isec < Geo::NSECTORS; isec++) {
1881 if (mTOFSectors[isec] == -1) {
1882 continue;
1883 }
1884 snprintf(name, SIZESTR, "BTOF%d", isec);
1885 if (mTOFHoles && (isec == 13 || isec == 14 || isec == 15)) {
1886 TVirtualMC::GetMC()->Gspos("FPEB", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1887 } else {
1888 TVirtualMC::GetMC()->Gspos("FPEA", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1889 }
1890 }
1891}
1892
1893//_____________________________________________________________________________
1894void Detector::makeBackInBTOFvolumes(Double_t ytof) const
1895{
1896 //
1897 // Fill BTOF_%i (for i=0,...17) volumes with volumes called FAIA and
1898 // FAIC (FEA cards and services container).
1899 // In case of TOF holes, three sectors (i.e. 13th, 14th and 15th) are
1900 // filled with volumes FAIB (FEA cards and services container).
1901 //
1902
1903 constexpr Int_t SIZESTR = 16;
1904
1905 Int_t idrotm[1] = {0};
1906
1907 // Matrix(idrotm[0], 90., 0., 0., 0., 90.,-90.);
1908 Matrix(idrotm[0], 90., 0., 0., 0., 90., 270.);
1909
1910 Double_t xcoor, ycoor, zcoor;
1911 xcoor = 0.;
1912 ycoor = 0.;
1913 zcoor = Geo::MODULECOVERTHICKNESS + (ytof * 0.5 - Geo::MODULECOVERTHICKNESS) * 0.5;
1914
1915 char name[SIZESTR];
1916
1917 // Positioning of FEA cards and services containers (FAIA, FAIC and FAIB)
1918 for (Int_t isec = 0; isec < Geo::NSECTORS; isec++) {
1919 if (mTOFSectors[isec] == -1) {
1920 continue;
1921 }
1922 snprintf(name, SIZESTR, "BTOF%d", isec);
1923 if (Geo::FEAWITHMASKS[isec]) {
1924 TVirtualMC::GetMC()->Gspos("FAIA", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1925 } else {
1926 if (mTOFHoles && (isec == 13 || isec == 14 || isec == 15)) {
1927 TVirtualMC::GetMC()->Gspos("FAIB", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1928 } else {
1929 TVirtualMC::GetMC()->Gspos("FAIC", 0, name, xcoor, ycoor, zcoor, idrotm[0], "ONLY");
1930 }
1931 }
1932 }
1933}
1934
1936{
1937 //
1938 // Create entries for alignable volumes associating the symbolic volume
1939 // name with the corresponding volume path. Needs to be syncronized with
1940 // eventual changes in the geometry.
1941 //
1942
1943 o2::detectors::DetID::ID idTOF = o2::detectors::DetID::TOF;
1944 Int_t modUID, modnum = 0;
1945
1946 TString volPath;
1947 TString symName;
1948
1949 TString vpL0 = "cave/barrel_1/B077_1/BSEGMO";
1950 TString vpL1 = "_1/BTOF";
1951 TString vpL2 = "_1";
1952 TString vpL3 = "/FTOA_0";
1953 TString vpL4 = "/FLTA_0/FSTR_";
1954
1955 TString snSM = "TOF/sm";
1956 TString snSTRIP = "/strip";
1957
1958 //
1959 // The TOF MRPC Strips
1960 // The symbolic names are: TOF/sm00/strip01
1961 // ...
1962 // TOF/sm17/strip91
1963
1964 Int_t imod = 0;
1965
1966 for (Int_t isect = 0; isect < Geo::NSECTORS; isect++) {
1967 for (Int_t istr = 1; istr <= Geo::NSTRIPXSECTOR; istr++) {
1968 modUID = o2::base::GeometryManager::getSensID(idTOF, modnum++);
1969 LOG(debug) << "modUID: " << modUID;
1970
1971 if (mTOFSectors[isect] == -1) {
1972 continue;
1973 }
1974
1975 if (mTOFHoles && (isect == 13 || isect == 14 || isect == 15)) {
1976 if (istr < 39) {
1977 vpL3 = "/FTOB_0";
1978 vpL4 = "/FLTB_0/FSTR_";
1979 } else if (istr > 53) {
1980 vpL3 = "/FTOC_0";
1981 vpL4 = "/FLTC_0/FSTR_";
1982 } else {
1983 continue;
1984 }
1985 } else {
1986 vpL3 = "/FTOA_0";
1987 vpL4 = "/FLTA_0/FSTR_";
1988 }
1989
1990 volPath = vpL0;
1991 volPath += isect;
1992 volPath += vpL1;
1993 volPath += isect;
1994 volPath += vpL2;
1995 volPath += vpL3;
1996 volPath += vpL4;
1997 volPath += istr;
1998
1999 symName = snSM;
2000 symName += Form("%02d", isect);
2001 symName += snSTRIP;
2002 symName += Form("%02d", istr);
2003
2004 LOG(debug) << "--------------------------------------------"
2005 << "\n";
2006 LOG(debug) << "Alignable object" << imod << "\n";
2007 LOG(debug) << "volPath=" << volPath << "\n";
2008 LOG(debug) << "symName=" << symName << "\n";
2009 LOG(debug) << "--------------------------------------------"
2010 << "\n";
2011
2012 LOG(debug) << "Check for alignable entry: " << symName;
2013
2014 if (!gGeoManager->SetAlignableEntry(symName.Data(), volPath.Data(), modUID)) {
2015 LOG(error) << "Alignable entry " << symName << " NOT set";
2016 }
2017 LOG(debug) << "Alignable entry " << symName << " set";
2018
2019 // T2L matrices for alignment
2020 TGeoPNEntry* e = gGeoManager->GetAlignableEntryByUID(modUID);
2021 LOG(debug) << "Got TGeoPNEntry " << e;
2022
2023 if (e) {
2024 TGeoHMatrix* globMatrix = e->GetGlobalOrig();
2025 Double_t phi = Geo::PHISEC * (isect % Geo::NSECTORS) + Geo::PHISEC * 0.5;
2026 TGeoHMatrix* t2l = new TGeoHMatrix();
2027 t2l->RotateZ(phi);
2028 const TGeoHMatrix& globMatrixi = globMatrix->Inverse();
2029 t2l->MultiplyLeft(&globMatrixi);
2030 e->SetMatrix(t2l);
2031 } else {
2032 // AliError(Form("Alignable entry %s is not valid!",symName.Data()));
2033 }
2034 imod++;
2035 }
2036 }
2037
2038 //
2039 // The TOF supermodules
2040 // The symbolic names are: TOF/sm00
2041 // ...
2042 // TOF/sm17
2043 //
2044 for (Int_t isect = 0; isect < Geo::NSECTORS; isect++) {
2045 volPath = vpL0;
2046 volPath += isect;
2047 volPath += vpL1;
2048 volPath += isect;
2049 volPath += vpL2;
2050
2051 symName = snSM;
2052 symName += Form("%02d", isect);
2053
2054 // AliDebug(2,"--------------------------------------------");
2055 // AliDebug(2,Form("Alignable object %d", isect+imod));
2056 // AliDebug(2,Form("volPath=%s\n",volPath.Data()));
2057 // AliDebug(2,Form("symName=%s\n",symName.Data()));
2058 // AliDebug(2,"--------------------------------------------");
2059
2060 gGeoManager->SetAlignableEntry(symName.Data(), volPath.Data());
2061 }
2062}
Definition of the GeometryManager class.
Definition of the Stack class.
std::ostringstream debug
int16_t time
Definition RawEventData.h:4
int32_t i
uint16_t pos
Definition RawData.h:3
uint32_t c
Definition RawData.h:2
uint32_t stack
Definition RawData.h:1
ClassImp(Detector)
StringRef key
V GetEnergyLoss() const
Definition BaseHits.h:103
void Matrix(Int_t &nmat, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3, Double_t phi3) const
Definition Detector.cxx:104
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
Definition Detector.cxx:66
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
Definition Detector.cxx:72
int getMediumID(int imed) const
Definition Detector.h:136
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
Definition Detector.cxx:59
std::string addNameTo(const char *ext) const
Definition Detector.h:151
static int getSensID(o2::detectors::DetID detid, int sensid)
static MaterialManager & Instance()
Int_t GetCurrentTrackNumber() const override
Definition Stack.h:133
int ID
Detector identifiers: continuous, starting from 0.
Definition DetID.h:63
~Detector() override
Definition Detector.cxx:60
virtual void MaterialMixer(Float_t *p, const Float_t *const a, const Float_t *const m, Int_t n) const final
Definition Detector.cxx:297
void ConstructGeometry() final
Definition Detector.cxx:312
void Register() override
Definition Detector.cxx:121
void InitializeO2Detector() final
Definition Detector.cxx:65
void addAlignableVolumes() const override
declare alignable volumes of detector
Bool_t ProcessHits(FairVolume *v=nullptr) final
Definition Detector.cxx:75
void EndOfEvent() final
Definition Detector.cxx:328
Detector()=default
virtual void DefineGeometry(Double_t xtof, Double_t ytof, Double_t zlenA) final
Definition Detector.cxx:329
void Reset() final
Definition Detector.cxx:126
static double getDistances(Int_t iplate, Int_t istrip)
Definition Geo.h:83
static constexpr double AL3PARAMETERS[3]
Definition Geo.h:316
static constexpr Int_t NSECTORS
Definition Geo.h:122
static constexpr double AL2PARAMETERS[3]
Definition Geo.h:315
static double getHeights(Int_t iplate, Int_t istrip)
Definition Geo.h:82
static constexpr double HSENSMY
Definition Geo.h:339
static constexpr double LENGTHEXINMODBORDER
Definition Geo.h:291
static constexpr double ZPAD
Definition Geo.h:143
static constexpr Int_t NPADZ
Definition Geo.h:111
static constexpr double PHISEC
Definition Geo.h:149
static constexpr double AL1PARAMETERS[3]
Definition Geo.h:314
static constexpr double BARS[3]
Definition Geo.h:323
static constexpr double WPCBZ2
Definition Geo.h:335
static constexpr double WPCBZ1
Definition Geo.h:334
static constexpr double WHONZ
Definition Geo.h:333
static constexpr double STRIPLENGTH
Definition Geo.h:144
static constexpr double LENGTHINCEMODBORDERU
Definition Geo.h:283
static constexpr Int_t NSTRIPXSECTOR
Definition Geo.h:118
static constexpr double CBLH2
Definition Geo.h:309
static constexpr Int_t NSTRIPB
Definition Geo.h:115
static constexpr Int_t NSTRIPC
Definition Geo.h:116
static constexpr double BAR1[3]
Definition Geo.h:321
static constexpr Int_t NSTRIPA
Definition Geo.h:114
static constexpr double BAR[3]
Definition Geo.h:320
static constexpr double INTERCENTRMODBORDER1
Definition Geo.h:255
static constexpr double BARS2[3]
Definition Geo.h:325
static constexpr double FEAWIDTH2
Definition Geo.h:301
static constexpr double ROOF2PARAMETERS[3]
Definition Geo.h:318
static constexpr double MODULECOVERTHICKNESS
Definition Geo.h:296
static constexpr double BARS1[3]
Definition Geo.h:324
static constexpr double HFILIY
Definition Geo.h:330
static constexpr double MODULEWALLTHICKNESS
Definition Geo.h:254
static constexpr double INTERCENTRMODBORDER2
Definition Geo.h:262
static constexpr double LENGTHINCEMODBORDERD
Definition Geo.h:287
static constexpr double HGLASSY
Definition Geo.h:331
static constexpr double HPCBY
Definition Geo.h:328
static constexpr double EXTERINTERMODBORDER2
Definition Geo.h:276
static constexpr double XPAD
Definition Geo.h:141
static constexpr double HRGLY
Definition Geo.h:329
static constexpr double CBLH1
Definition Geo.h:307
static constexpr double ROOF1PARAMETERS[3]
Definition Geo.h:317
static constexpr double RMIN
Definition Geo.h:135
static constexpr double WCPCBZ
Definition Geo.h:336
static Int_t getIndex(const Int_t *detId)
Definition Geo.cxx:563
static constexpr double FEAPARAMETERS[3]
Definition Geo.h:319
static constexpr double SAWTHICKNESS
Definition Geo.h:304
static constexpr Int_t NPLATES
Definition Geo.h:124
static constexpr double FEAWIDTH1
Definition Geo.h:298
static constexpr double BAR2[3]
Definition Geo.h:322
static constexpr double RMAX
Definition Geo.h:136
static constexpr double HCPCBY
Definition Geo.h:332
static void getPadDxDyDz(const Float_t *pos, Int_t *det, Float_t *DeltaPos, int sector=-1)
Definition Geo.cxx:835
static constexpr Int_t NPADX
Definition Geo.h:109
static constexpr double WRGLZ
Definition Geo.h:337
static constexpr double HHONY
Definition Geo.h:327
static constexpr double EXTERINTERMODBORDER1
Definition Geo.h:269
static constexpr double WGLFZ
Definition Geo.h:338
static constexpr double BETWEENLANDMASK
Definition Geo.h:311
static constexpr double CBLW
Definition Geo.h:306
static constexpr Bool_t FEAWITHMASKS[NSECTORS]
Definition Geo.h:248
static constexpr double ZLENA
Definition Geo.h:130
static double getAngles(Int_t iplate, Int_t istrip)
Definition Geo.h:81
static ShmManager & Instance()
Definition ShmManager.h:61
GLdouble n
Definition glcorearb.h:1982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
const GLfloat * m
Definition glcorearb.h:4066
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLboolean * data
Definition glcorearb.h:298
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
Node par(int index)
Parameters.
float float float float z1
Definition MathUtils.h:82
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Common utility functions.
void empty(int)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row