1 /**************************************************************************
2 * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //____________________________________________________________________
20 // Concrete implementation of AliFMDSubDetector
22 // This implements the geometry for FMD3
24 #include "TVirtualMC.h" // ROOT_TVirtualMC
25 #include "AliFMD3Support.h" // ALIFMD3SUPPORT_H
26 #include "AliLog.h" // ALILOG_H
27 #include <Riostream.h> // ROOT_Riostream
28 // #define FMD3_COMPLICATED_MOTHER
29 //____________________________________________________________________
30 ClassImp(AliFMD3Support);
32 //____________________________________________________________________
33 const Char_t* AliFMD3Support::fgkNoseName = "F3SN";
34 const Char_t* AliFMD3Support::fgkBackName = "F3SB";
35 const Char_t* AliFMD3Support::fgkBeamName = "F3SL";
36 const Char_t* AliFMD3Support::fgkFlangeName = "F3SF";
38 //____________________________________________________________________
39 AliFMD3Support::AliFMD3Support()
47 // Default constructor for the support of FMD3 sub-detector
64 //____________________________________________________________________
65 AliFMD3Support::~AliFMD3Support()
67 // Destructor - does nothing
71 //____________________________________________________________________
73 AliFMD3Support::SetupGeometry(Int_t airId,
82 // Setup the FMD3 sub-detector geometry
86 // airId Id # of the Air medium
87 // cId Id # of the Carbon fibre medium
90 // Global stuff we need
91 Double_t zdist = fConeLength - fBackLength - fNoseLength;
92 Double_t tdist = fBackHighR - fNoseHighR;
93 Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
94 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
95 Double_t minZ = TMath::Min(fNoseZ - fConeLength, outerZh);
96 fAlpha = tdist / zdist;
97 fZ = fNoseZ + (minZ - fNoseZ) / 2;
98 AliDebug(10, Form("Theta = %lf", theta));
100 const Char_t* mother = "FMD3";
101 #ifdef FMD3_COMPLICATED_MOTHER
102 // ------------- Mother volume -------------------------------------
103 Double_t p[3 + 9 * 3];
110 // First plane (at start of nose)
111 p[3] = fNoseZ - fZ + eps;
112 p[4] = fNoseLowR - eps;
113 p[5] = fNoseHighR + eps;
114 // Second plane (at end of nose)
115 p[6] = fNoseZ - fNoseLength - fZ - eps;
116 p[7] = fNoseLowR - eps;
117 p[8] = ConeR(p[6] + fZ) + eps; // fNoseHighR;
118 // Third plane (at front of inner ring)
119 p[9] = innerZl - fZ + eps;
120 p[10] = innerRl - eps;
121 p[11] = ConeR(p[9] + fZ) + eps;
122 // Fourth plane (at back of inner ring)
123 p[12] = innerZh - fZ - eps;
125 p[14] = ConeR(p[12] + fZ) + eps;
126 // Fifth plane (at back of inner ring)
127 p[15] = p[12] - eps/2;
128 p[16] = outerRl - eps;
129 p[17] = ConeR(p[15] + fZ) + eps;
130 // Sixth plane (at front of back)
131 p[18] = fNoseZ - zdist - fNoseLength - fZ + eps;
132 p[19] = outerRl - eps;
133 p[20] = ConeR(p[18] + fZ) + eps;
134 // Seventh plane (at front of back, at end of flanges)
135 p[21] = p[18] - eps/2;
137 p[23] = fFlangeR + eps;
138 // Eight (and final) plane (at back of back or outer ring)
139 p[24] = minZ - fZ - eps;
143 gMC->Gsvolu(mother, "PCON", airId, p, 27);
144 if (outerZh - fZ < p[24])
145 Warning("SetupGeometry", "Outer ring back is at %f (%f), "
146 "but support ends %f", outerZh, outerZl,
153 p[2] = TMath::Abs((minZ - fNoseZ) / 2);
154 gMC->Gsvolu(mother, "TUBE", airId, p, 3);
162 // ------------- Support Structures --------------------------------
163 fRotations.Set(fNBeam + fNFlange);
169 par[2] = fNoseLength / 2;
170 fNoseId = gMC->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
175 par[2] = fBackLength / 2;
176 fBackId = gMC->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
179 par[0] = fBeamThickness / 2;
180 par[1] = fBeamWidth / 2;
182 fBeamId = gMC->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
183 for (Int_t i = 0; i < fNBeam; i++) {
184 // cout << "Making beam # " << i << endl;
185 Double_t phi = 360. / fNBeam * i;
187 gMC->Matrix(id, 180 - theta, phi, 90, 90 + phi, theta, phi);
192 par[0] = (fFlangeR - fBackHighR) / 2;
193 par[1] = fBeamWidth / 2;
194 par[2] = fBackLength / 2;
195 fFlangeId = gMC->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
196 for (Int_t i = 0; i < fNFlange; i++) {
197 Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
199 gMC->Matrix(id, 90, phi, 90, 90+phi, 0, 0);
200 fRotations[fNBeam + i] = id;
204 //____________________________________________________________________
206 AliFMD3Support::Geometry(const char* mother, Int_t idRotId, Double_t zTop)
208 // Position the FMD3 sub-detector volume
212 // mother name of the mother volume
213 // idRotId Identity rotation matrix ID
218 Double_t zdist = fConeLength - fBackLength - fNoseLength;
219 Double_t tdist = fBackHighR - fNoseHighR;
220 const Char_t* name = "FMD3";
223 // Placing mother volume
224 AliDebug(10, Form("Putting %s in %s at z=%lf", name, mother, zTop));
225 gMC->Gspos(name, 1, mother, 0, 0, zTop, idRotId);
228 z = fNoseZ - fNoseLength / 2 - fZ;
229 AliDebug(10, Form("Putting %s in %s at z=%lf-%lf/2-%lf=%lf",
230 fgkNoseName, name, fNoseZ, fNoseLength, fZ, z));
231 gMC->Gspos(fgkNoseName, 1, name, 0., 0., z, idRotId, "");
234 z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
235 AliDebug(10, Form("Putting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
236 fgkBackName, name, fNoseZ, fNoseLength, zdist,
237 fBackLength, fZ, z));
238 gMC->Gspos(fgkBackName, 1, name, 0., 0., z, idRotId, "");
241 z = fNoseZ - fNoseLength - zdist / 2 - fZ;
242 Double_t r = fNoseHighR + tdist / 2;
243 AliDebug(10, Form("Putting %s's in %s at z=%lf-%lf-%lf/2-%lf=%lf",
244 fgkBeamName, name, fNoseZ, fNoseLength, zdist, fZ, z));
245 for (Int_t i = 0; i < fNBeam; i++) {
246 // cout << "Making beam # " << i << endl;
247 Double_t phi = 360. / fNBeam * i;
248 gMC->Gspos(fgkBeamName, i, name,
249 r * TMath::Cos(TMath::Pi() / 180 * phi),
250 r * TMath::Sin(TMath::Pi() / 180 * phi),
251 z, fRotations[i], "");
254 // Placing the flanges
255 r = fBackHighR + (fFlangeR - fBackHighR) / 2;
256 z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
257 AliDebug(10, Form("Putting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
258 fgkFlangeName, name, fNoseZ, fNoseLength, zdist,
259 fBackLength, fZ, z));
260 for (Int_t i = 0; i < fNFlange; i++) {
261 Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
262 gMC->Gspos(fgkFlangeName, i, name,
263 r * TMath::Cos(TMath::Pi() / 180 * phi),
264 r * TMath::Sin(TMath::Pi() / 180 * phi),
265 z, fRotations[fNBeam + i], "");
269 //____________________________________________________________________
271 AliFMD3Support::ConeR(Double_t z, Option_t* opt) const
273 // Calculate the cone radius at Z
275 Warning("ConeR", "alpha not set: %lf", fAlpha);
279 Warning("ConeR", "z=%lf is before start of cone %lf", z, fNoseZ);
282 Double_t e = fBeamThickness / TMath::Cos(TMath::ATan(fAlpha));
283 if (opt[0] == 'I' || opt[1] == 'i') e *= -1;
284 if (z > fNoseZ - fNoseLength) return fNoseHighR + e;
285 if (z < fNoseZ - fConeLength + fBackLength) return fBackHighR + e;
286 Double_t r = fNoseHighR + fAlpha * TMath::Abs(z - fNoseZ + fNoseLength) + e;
290 //____________________________________________________________________
292 AliFMD3Support::Gsatt()
294 // Set drawing attributes for the FMD3 Support
295 gMC->Gsatt(fgkNoseName, "SEEN", 1);
296 gMC->Gsatt(fgkBeamName, "SEEN", 1);
297 gMC->Gsatt(fgkBackName, "SEEN", 1);
298 gMC->Gsatt(fgkFlangeName, "SEEN", 1);
302 //____________________________________________________________________