1515#ifndef FT3MODULECONSTANTS_H
1616#define FT3MODULECONSTANTS_H
1717
18+ #include < array>
19+ #include < unordered_map>
1820#include < vector>
1921#include < map>
2022#include < TColor.h>
@@ -29,17 +31,19 @@ namespace o2::ft3::ModuleConstants
2931 * When stacking 2x1 modules, there is a 0.2mm gap between them. By default, we assume this
3032 * gap to be ABOVE the most recently placed module.
3133 *
32- * |<- 25mm ->|<- 25mm ->|
34+ * |<- 25mm ->|| <- 25mm ->|
3335 * _______________________
34- * ----------------------- 0.2mm gap above
35- * | | | | |
36- * | | | | |
37- * | | | | |
38- * | | | | | 29mm sensor height
39- * | | | | |
40- * | | | | |
36+ * ------------------------ 0.2mm gap above
37+ * | | || | |
38+ * | | || | |
39+ * | | || | |
40+ * | | || | | 29mm sensor height
41+ * | | || | |
42+ * | | || | |
4143 * ------------------------
42- *
44+ * ^
45+ * |
46+ * 0.2mm gap in the middle
4347 */
4448// First set all layout constants for the rest of the function
4549const double single_sensor_width = 2.5 ;
@@ -98,12 +102,88 @@ inline const double z_offsetStave(double x_midpoint_spacing)
98102 (2 - x_midpoint_spacing / (sensor2x1_width / 2 + staveSensorGap));
99103}
100104
101- const int SiColor = kGreen ;
105+ /*
106+ * Materials of the FT3 module.
107+ *
108+ * Everything the simulation needs to know about a material lives in the
109+ * materials map below, keyed by its FT3-local ID: composition, density,
110+ * transport parameters and the colour its volumes are drawn in.
111+ * Detector::createMaterials() registers the whole map with the MaterialManager,
112+ * and FT3Module/FT3Layer look the media up again by MaterialID, so no ID,
113+ * density or colour is ever written out by hand.
114+ */
115+ enum class MaterialID : unsigned {
116+ Air = 1 ,
117+ Silicon,
118+ Copper,
119+ Kapton,
120+ CarbonFiber,
121+ Epoxy,
122+ Aluminum,
123+ Foam,
124+ Water
125+ };
126+
127+ // Transport parameters of a medium, in the order expected by Detector::Medium()
128+ struct TrackingParams {
129+ float tmaxfd; // maximum field-induced angular deviation per step, degrees
130+ float stemax; // maximum step length, cm
131+ float deemax; // maximum fractional energy loss per step
132+ float epsil; // tracking precision, cm
133+ float stmin; // minimum step length, cm
134+ };
135+
136+ constexpr TrackingParams sensitiveTracking = {0 .1f , 0 .0075f , 0 .1f , 1 .0e-4f , 0 .0f };
137+ constexpr TrackingParams passiveTracking = {0 .1f , 1 .0f , 0 .1f , 1 .0e-4f , 0 .0f };
138+
139+ // Maximum number of elements any of the mixtures below is built from
140+ constexpr unsigned maxMaterialComponents = 4 ;
141+ using ComponentArray = std::array<float , maxMaterialComponents>;
142+
143+ struct MaterialProperties {
144+ const char * name;
145+ int colour; // ROOT colour every volume made of this material is drawn in
146+ float density; // g/cm3
147+ // Radiation and nuclear interaction length, cm. Only single elements carry
148+ // them: Mixture() derives both from the composition and takes no such
149+ // arguments. A non-positive value lets the transport engine compute it.
150+ float radl;
151+ float absl;
152+ int nComponents; // 0: single element; > 0: mixture by weight; < 0: mixture by atom count
153+ ComponentArray a; // mass numbers; only a[0] is used for a single element
154+ ComponentArray z; // atomic numbers; only z[0] is used for a single element
155+ ComponentArray w; // weight fractions or atom counts; unused for a single element
156+ TrackingParams tracking;
157+ };
158+
159+ /*
160+ * Silicon, copper and carbon fibre are shared with TRK and are kept numerically
161+ * identical to its SILICON$, COPPER$ and CARBONFIBER$ (TRK Detector::createMaterials()),
162+ * down to the radiation lengths. Kapton, epoxy and aluminium have no TRK
163+ * counterpart: TRK models the flex as the effective FPC$ mixture instead.
164+ */
165+ inline const std::unordered_map<MaterialID, MaterialProperties> materials = {
166+ // Air volumes get their colour set individually where they are built
167+ {MaterialID::Air, {" AIR$" , kWhite , 1 .20479e-3f , 0 .0f , 0 .0f , 4 , {12 .0107f , 14 .0067f , 15 .9994f , 39 .948f }, {6 .0f , 7 .0f , 8 .0f , 18 .0f }, {0 .000124f , 0 .755267f , 0 .231781f , 0 .012827f }, passiveTracking}},
168+ {MaterialID::Silicon, {" SILICON$" , kGreen , 2 .33f , 9 .36f , 999 .0f , 0 , {28 .086f }, {14 .0f }, {}, sensitiveTracking}},
169+ // Copper planes of the end-of-stave cards: X0 = 1.436 cm
170+ {MaterialID::Copper, {" COPPER$" , kOrange , 8 .96f , 1 .436f , 999 .0f , 0 , {63 .546f }, {29 .0f }, {}, passiveTracking}},
171+ // Kapton: C22 H10 N2 O5, by weight fraction. Also the cooling pipe material.
172+ {MaterialID::Kapton, {" KAPTON$" , kYellow , 1 .346f , 0 .0f , 0 .0f , 4 , {12 .0107f , 1 .00794f , 14 .0067f , 15 .999f }, {6 .0f , 1 .0f , 7 .0f , 8 .0f }, {0 .5641f , 0 .2564f , 0 .0513f , 0 .1282f }, passiveTracking}},
173+ // Carbon fibre: density tuned so X0 ~ 27 cm, as in TRK
174+ // TODO: Check with Rene the exact type of carbon fiber
175+ {MaterialID::CarbonFiber, {" CARBONFIBER$" , kGray + 1 , 1 .45f , 27 .0f , 999 .0f , 0 , {12 .0107f }, {6 .0f }, {}, passiveTracking}},
176+ // Epoxy: C18 H19 O3, by atom count (negative nComponents)
177+ {MaterialID::Epoxy, {" EPOXY$" , kBlue , 2 .186f , 0 .0f , 0 .0f , -3 , {12 .0107f , 1 .00794f , 15 .999f }, {6 .0f , 1 .0f , 8 .0f }, {18 .0f , 19 .0f , 3 .0f }, passiveTracking}},
178+ // No TRK counterpart; X0 and lambda are left to the transport engine
179+ {MaterialID::Aluminum, {" ALUMINUM$" , kBlack , 2 .7f , 0 .0f , 0 .0f , 0 , {26 .98f }, {13 .0f }, {}, passiveTracking}},
180+ // Carbon foam core of the disk separation layer
181+ {MaterialID::Foam, {" FOAM$" , kBlack , 0 .17f , 0 .0f , 0 .0f , 0 , {12 .0107f }, {6 .0f }, {}, passiveTracking}},
182+ // Coolant inside the kapton pipes
183+ {MaterialID::Water, {" WATER$" , kBlue , 1 .064f , 0 .0f , 0 .0f , 0 , {18 .01528f }, {8 .0f }, {}, passiveTracking}}};
184+ // The inactive rim of a sensor is made of silicon as well, but is drawn
185+ // separately so that it can be told apart from the active area.
102186const int SiInactiveColor = kRed ;
103- const int glueColor = kBlue ;
104- const int CuColor = kOrange ;
105- const int kaptonColor = kYellow ;
106- const int carbonFiberColor = kGray + 1 ;
107187
108188// Struct for stave position configuration (varies between ML/OT)
109189struct StaveConfig {
0 commit comments