Project
Loading...
Searching...
No Matches
Detector.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "TGeoBBox.h"
13#include "TGeoCompositeShape.h"
14#include "TGeoManager.h" // for TGeoManager
15#include "TGeoMatrix.h"
16#include "TGeoVolume.h"
17#include "TMath.h"
18#include "TString.h"
19
20#include <fairlogger/Logger.h>
21#include "FairVolume.h"
22#include "FairRootManager.h"
23
24#include "TOFSimulation/Detector.h"
25
26#include <TVirtualMC.h> // for TVirtualMC, gMC
29#include "DetectorsBase/Stack.h"
30
31#include <algorithm>
32#include <array>
33#include <map>
34#include <utility>
35#include <vector>
36
37using namespace o2::tof;
38
40
42 : o2::base::DetImpl<Detector>("TOF", active), mEventNr(0), mTOFHoles(kTRUE), mHits(o2::utils::createSimVector<HitType>())
43{
44 for (Int_t i = 0; i < Geo::NSECTORS; i++) {
45 mTOFSectors[i] = 1;
46 }
47}
48
50 : o2::base::DetImpl<Detector>(rhs),
51 mEventNr(0),
52 mTOFHoles(rhs.mTOFHoles),
53 mHits(o2::utils::createSimVector<HitType>())
54{
55 for (Int_t i = 0; i < Geo::NSECTORS; i++) {
56 mTOFSectors[i] = rhs.mTOFSectors[i];
57 }
58}
59
64
66{
67 TGeoVolume* v = gGeoManager->GetVolume("FPAD");
68 if (v == nullptr) {
69 printf("Sensitive volume FSEN not found!!!!!!!!");
70 } else {
71 AddSensitiveVolume(v);
72 }
73}
74
75Bool_t Detector::ProcessHits(FairVolume* v)
76{
77 // This method is called from the MC stepping for the sensitive volume only
78 if (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
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
V GetEnergyLoss() const
Definition BaseHits.h:103
void Matrix(Int_t &nmat, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3, Double_t phi3) const
Definition Detector.cxx:104
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
Definition Detector.cxx:66
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
Definition Detector.cxx:72
int getMediumID(int imed) const
Definition Detector.h:136
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
Definition Detector.cxx:59
std::string addNameTo(const char *ext) const
Definition Detector.h:151
static int getSensID(o2::detectors::DetID detid, int sensid)
static MaterialManager & Instance()
Int_t GetCurrentTrackNumber() const override
Definition Stack.h:133
int ID
Detector identifiers: continuous, starting from 0.
Definition DetID.h:63
~Detector() override
Definition Detector.cxx:60
virtual void MaterialMixer(Float_t *p, const Float_t *const a, const Float_t *const m, Int_t n) const final
Definition Detector.cxx: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:61
GLdouble n
Definition glcorearb.h:1982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
const GLfloat * m
Definition glcorearb.h:4066
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLboolean * data
Definition glcorearb.h:298
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
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