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 < DetectorsBase/Detector.h>
13+ #include < DetectorsBase/MaterialManager.h>
14+ #include < Alice3DetectorsPassive/Magnet.h>
15+ #include < TGeoCompositeShape.h>
16+ #include < TGeoManager.h>
17+ #include < TGeoMatrix.h>
18+ #include < TGeoMedium.h>
19+ #include < TGeoVolume.h>
20+ #include < TGeoTube.h>
21+
22+ using namespace o2 ::passive;
23+
24+ Alice3Magnet::~Alice3Magnet () = default ;
25+ Alice3Magnet::Alice3Magnet () : Alice3PassiveBase(" A3MAG" , " " ) {}
26+ Alice3Magnet::Alice3Magnet (const char * name, const char * title) : Alice3PassiveBase(name, title) {}
27+ Alice3Magnet::Alice3Magnet (const Alice3Magnet& rhs) = default;
28+
29+ Alice3Magnet& Alice3Magnet::operator =(const Alice3Magnet& rhs)
30+ {
31+ if (this == &rhs) {
32+ return *this ;
33+ }
34+
35+ Alice3PassiveBase::operator =(rhs);
36+
37+ return *this ;
38+ }
39+
40+ void Alice3Magnet::createMaterials ()
41+ {
42+ auto & matmgr = o2::base::MaterialManager::Instance ();
43+ int isxfld = 2 .;
44+ float sxmgmx = 10 .;
45+ o2::base::Detector::initFieldTrackingParams (isxfld, sxmgmx);
46+
47+ // Current information is scarce, we have some X/X0 and thicknesses but no full material information
48+ // We use then two main materials: Aluminium for insulation, cryostats, stabiliser, supports and strips.
49+ // Copper for the coils.
50+ // Latest updated reference table is, for the moment:
51+ // +------------------+-------------------------+----------+--------+
52+ // | layer | effective thickness [mm]| X0 [cm] | X0 [%] |
53+ // +------------------+-------------------------+----------+--------+
54+ // | Support cylinder | 20 | 8.896 | 0.225 |
55+ // | Al-strip | 1 | 8.896 | 0.011 |
56+ // | NbTi/Cu | 3 | 1.598 | 0.188 |
57+ // | Insulation | 11 | 17.64 | 0.062 |
58+ // | Al-stabiliser | 33 | 8.896 | 0.371 |
59+ // | Inner cryostat | 10 | 8.896 | 0.112 |
60+ // | Outer cryostat | 30 | 8.896 | 0.337 |
61+ // +------------------+-------------------------+----------+--------+
62+ // Geometry will be oversimplified in two wrapping cylindrical Al layers (symmetric for the time being) with a Copper layer in between.
63+
64+ float epsil, stmin, tmaxfd, deemax, stemax;
65+ epsil = .001 ; // Tracking precision,
66+ stemax = -0.01 ; // Maximum displacement for multiple scat
67+ tmaxfd = -20 .; // Maximum angle due to field deflection
68+ deemax = -.3 ; // Maximum fractional energy loss, DLS
69+ stmin = -.8 ;
70+
71+ matmgr.Material (" A3MAG" , 9 , " Al1$" , 26.98 , 13 ., 2.7 , 8.9 , 37.2 );
72+ matmgr.Material (" A3MAG" , 19 , " Cu1$" , 63.55 , 29 ., 8.96 , 1.6 , 18.8 );
73+
74+ matmgr.Medium (" A3MAG" , 9 , " ALU_C0" , 9 , 0 , isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
75+ matmgr.Medium (" A3MAG" , 19 , " CU_C0" , 19 , 0 , isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
76+ }
77+
78+ void Alice3Magnet::ConstructGeometry ()
79+ {
80+ createMaterials ();
81+
82+ TGeoManager* geoManager = gGeoManager ;
83+ TGeoVolume* barrel = geoManager->GetVolume (" barrel" );
84+ if (!barrel) {
85+ LOGP (fatal, " Could not find barrel volume while constructing Alice 3 magnet geometry" );
86+ }
87+
88+ auto & matmgr = o2::base::MaterialManager::Instance ();
89+ auto kMedAl = matmgr.getTGeoMedium (" A3MAG_ALU_C0" );
90+ auto kMedCu = matmgr.getTGeoMedium (" A3MAG_CU_C0" );
91+
92+ float wrapThickness = (mTotalThickness - mCoilThickness ) / 2 ; // Thickness of the Al wraps
93+ float innerCoilsRadius = mInnerWrapInnerRadius + wrapThickness; // Inner radius of the Cu coils
94+ float externalWrapInnerRadius = innerCoilsRadius + mCoilThickness ; // Inner radius of the external wrapping Al cylinder
95+
96+ // inner wrap
97+ LOGP (debug, " Alice 3 magnet: creating inner wrap with inner radius {} and thickness {}" , mInnerWrapInnerRadius , wrapThickness);
98+ TGeoTube* innerLayer = new TGeoTube (mInnerWrapInnerRadius , mInnerWrapInnerRadius + wrapThickness, mZLength / 2 );
99+ // coils layer
100+ LOGP (debug, " Alice 3 magnet: creating coils layer with inner radius {} and thickness {}" , innerCoilsRadius, mCoilThickness );
101+ TGeoTube* coilsLayer = new TGeoTube (innerCoilsRadius, innerCoilsRadius + mCoilThickness , mZLength / 2 );
102+ // outer wrap
103+ LOGP (debug, " Alice 3 magnet: creating outer wrap with inner radius {} and thickness {}" , externalWrapInnerRadius, wrapThickness);
104+ TGeoTube* outerLayer = new TGeoTube (externalWrapInnerRadius, externalWrapInnerRadius + wrapThickness, mZLength / 2 );
105+
106+ TGeoVolume* innerWrap = new TGeoVolume (" innerWrap" , innerLayer, kMedAl );
107+ TGeoVolume* coils = new TGeoVolume (" coils" , coilsLayer, kMedCu );
108+ TGeoVolume* outerWrap = new TGeoVolume (" outerWrap" , outerLayer, kMedAl );
109+ innerWrap->SetLineColor (kRed );
110+ coils->SetLineColor (kOrange );
111+ outerWrap->SetLineColor (kRed );
112+
113+ new TGeoVolumeAssembly (" magnet" );
114+ auto * magnet = gGeoManager ->GetVolume (" magnet" );
115+ magnet->AddNode (innerWrap, 1 , nullptr );
116+ magnet->AddNode (coils, 1 , nullptr );
117+ magnet->AddNode (outerWrap, 1 , nullptr );
118+
119+ magnet->SetVisibility (1 );
120+
121+ barrel->AddNode (magnet, 1 , new TGeoTranslation (0 , 30 .f , 0 ));
122+ }
123+
124+ FairModule* Alice3Magnet::CloneModule () const
125+ {
126+ return new Alice3Magnet (*this );
127+ }
128+ ClassImp (o2::passive::Alice3Magnet)
0 commit comments