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