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
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,
78 Double_t /* outerZl */,
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(30, Form("\tTheta = %lf", theta));
100 const Char_t* mother = "FMD3";
101 Double_t p[3 + 9 * 3];
103 // ------------- Mother volume -------------------------------------
104 // The planes should be defined with increasing Z, as it will become
110 // First plane (at back of back or outer ring)
111 p[3] = minZ - fZ - eps;
112 p[4] = outerRl - eps;
113 p[5] = fFlangeR + eps;
114 // Second plane (at front of back, at end of flanges)
115 p[6] = fNoseZ - zdist - fNoseLength - fZ + eps;
118 // Third plane (at front of back)
121 p[11] = ConeR(p[9] + fZ) + eps;
122 // Fourth plane (at back of inner ring)
123 p[12] = innerZh - fZ - eps;
124 p[13] = outerRl - 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] = innerRl - eps;
129 p[17] = ConeR(p[15] + fZ) + eps;
130 // Sixth plane (at front of inner ring)
131 p[18] = innerZl - fZ + eps;
133 p[20] = ConeR(p[18] + fZ) + eps;
134 // Seventh plane (at end of nose)
135 p[21] = fNoseZ - fNoseLength - fZ - eps;
136 p[22] = fNoseLowR - eps;
137 p[23] = ConeR(p[21] + fZ) + eps; // fNoseHighR;
138 // Eight (and final) plane (at start of nose)
139 p[24] = fNoseZ - fZ + eps;
141 p[26] = fNoseHighR + eps;
144 gMC->Gsvolu(mother, "PCON", airId, p, 27);
146 // ------------- Support Structures --------------------------------
147 fRotations.Set(fNBeam + fNFlange);
153 par[2] = fNoseLength / 2;
154 fNoseId = gMC->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
159 par[2] = fBackLength / 2;
160 fBackId = gMC->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
163 par[0] = fBeamThickness / 2;
164 par[1] = fBeamWidth / 2;
166 fBeamId = gMC->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
167 for (Int_t i = 0; i < fNBeam; i++) {
168 // cout << "Making beam # " << i << endl;
169 Double_t phi = 360. / fNBeam * i;
171 gMC->Matrix(id, 180 - theta, phi, 90, 90 + phi, theta, phi);
176 par[0] = (fFlangeR - fBackHighR) / 2;
177 par[1] = fBeamWidth / 2;
178 par[2] = fBackLength / 2;
179 fFlangeId = gMC->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
180 for (Int_t i = 0; i < fNFlange; i++) {
181 Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
183 gMC->Matrix(id, 90, phi, 90, 90+phi, 0, 0);
184 fRotations[fNBeam + i] = id;
188 //____________________________________________________________________
190 AliFMD3Support::Geometry(const char* mother, Int_t idRotId, Double_t zTop)
192 // Position the FMD3 sub-detector volume
196 // mother name of the mother volume
197 // idRotId Identity rotation matrix ID
202 Double_t zdist = fConeLength - fBackLength - fNoseLength;
203 Double_t tdist = fBackHighR - fNoseHighR;
204 const Char_t* name = "FMD3";
207 // Placing mother volume
208 AliDebug(10, Form("\tPutting %s in %s at z=%lf", name, mother, zTop));
209 gMC->Gspos(name, 1, mother, 0, 0, zTop, idRotId, "ONLY");
212 z = fNoseZ - fNoseLength / 2 - fZ;
213 AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf/2-%lf=%lf",
214 fgkNoseName, name, fNoseZ, fNoseLength, fZ, z));
215 gMC->Gspos(fgkNoseName, 1, name, 0., 0., z, idRotId, "");
218 z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
219 AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
220 fgkBackName, name, fNoseZ, fNoseLength, zdist,
221 fBackLength, fZ, z));
222 gMC->Gspos(fgkBackName, 1, name, 0., 0., z, idRotId, "");
225 z = fNoseZ - fNoseLength - zdist / 2 - fZ;
226 Double_t r = fNoseHighR + tdist / 2;
227 AliDebug(10, Form("\tPutting %s's in %s at z=%lf-%lf-%lf/2-%lf=%lf",
228 fgkBeamName, name, fNoseZ, fNoseLength, zdist, fZ, z));
229 for (Int_t i = 0; i < fNBeam; i++) {
230 // cout << "Making beam # " << i << endl;
231 Double_t phi = 360. / fNBeam * i;
232 gMC->Gspos(fgkBeamName, i, name,
233 r * TMath::Cos(TMath::Pi() / 180 * phi),
234 r * TMath::Sin(TMath::Pi() / 180 * phi),
235 z, fRotations[i], "");
238 // Placing the flanges
239 r = fBackHighR + (fFlangeR - fBackHighR) / 2;
240 z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
241 AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
242 fgkFlangeName, name, fNoseZ, fNoseLength, zdist,
243 fBackLength, fZ, z));
244 for (Int_t i = 0; i < fNFlange; i++) {
245 Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
246 gMC->Gspos(fgkFlangeName, i, name,
247 r * TMath::Cos(TMath::Pi() / 180 * phi),
248 r * TMath::Sin(TMath::Pi() / 180 * phi),
249 z, fRotations[fNBeam + i], "");
254 //____________________________________________________________________
256 AliFMD3Support::ConeR(Double_t z, Option_t* opt) const
258 // Calculate the cone radius at Z
260 Warning("ConeR", "alpha not set: %lf", fAlpha);
264 Warning("ConeR", "z=%lf is before start of cone %lf", z, fNoseZ);
267 Double_t e = fBeamThickness / TMath::Cos(TMath::ATan(fAlpha));
268 if (opt[0] == 'I' || opt[1] == 'i') e *= -1;
269 if (z > fNoseZ - fNoseLength) return fNoseHighR + e;
270 if (z < fNoseZ - fConeLength + fBackLength) return fBackHighR + e;
271 Double_t r = fNoseHighR + fAlpha * TMath::Abs(z - fNoseZ + fNoseLength) + e;
275 //____________________________________________________________________
277 AliFMD3Support::Gsatt() const
279 // Set drawing attributes for the FMD3 Support
280 gMC->Gsatt(fgkNoseName, "SEEN", 1);
281 gMC->Gsatt(fgkBeamName, "SEEN", 1);
282 gMC->Gsatt(fgkBackName, "SEEN", 1);
283 gMC->Gsatt(fgkFlangeName, "SEEN", 1);
287 //____________________________________________________________________