]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDG3Simulator.cxx
Corrected mapping management group definition
[u/mrichter/AliRoot.git] / FMD / AliFMDG3Simulator.cxx
CommitLineData
1a1fdef7 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18//____________________________________________________________________
19//
20// Forward Multiplicity Detector based on Silicon wafers. This class
21// contains the base procedures for the Forward Multiplicity detector
22// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
23// which has 1 or 2 rings of silicon sensors.
24//
25// This is the base class for all FMD manager classes.
26//
27// The actual code is done by various separate classes. Below is
28// diagram showing the relationship between the various FMD classes
29// that handles the simulation
30//
31// +--------+ 1 +-----------------+
32// | AliFMD |<>-----| AliFMDSimulator |
33// +--------+ +-----------------+
34// ^
35// |
36// +-------------+-------------+
37// | |
38// +--------------------+ +-------------------+
39// | AliFMDGeoSimulator | | AliFMDG3Simulator |
4ac75127 40// +--------------------+ +-------------------+
41// ^
42// |
43// +--------------------+
44// | AliFMDOldSimulator |
45// +--------------------+
1a1fdef7 46//
47// * AliFMD
48// This defines the interface for the various parts of AliROOT that
49// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
50// AliFMDReconstructor, and so on.
51//
52// * AliFMDSimulator
53// This is the base class for the FMD simulation tasks. The
54// simulator tasks are responsible to implment the geoemtry, and
55// process hits.
56//
57// * AliFMDGeoSimulator
58// This is a concrete implementation of the AliFMDSimulator that
59// uses the TGeo classes directly only. This defines the active
60// volume as an ONLY XTRU shape with a divided MANY TUBS shape
61// inside to implement the particular shape of the silicon
62// sensors.
63//
64// * AliFMDG3Simulator
65// This is a concrete implementation of the AliFMDSimulator that
66// uses the TVirtualMC interface with GEANT 3.21-like messages.
67// This implements the active volume as a divided TUBS shape. Hits
68// in the corners should be cut away at run time (but currently
69// isn't).
70//
4ac75127 71// * AliFMDOldSimulator
72// This is a concrete implementation of AliFMDSimulator. It
73// approximates the of the rings as segmented disks.
74//
ede5852a 75#include <math.h>
1a1fdef7 76#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
77#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
78#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
79#include "AliFMDRing.h" // ALIFMDRING_H
80#include "AliFMD1.h" // ALIFMD1_H
81#include "AliFMD2.h" // ALIFMD2_H
82#include "AliFMD3.h" // ALIFMD3_H
83#include "AliFMD.h" // ALIFMD_H
84#include <AliLog.h> // ALILOG_H
85#include <TVector2.h> // ROOT_TVector2
86#include <TVirtualMC.h> // ROOT_TVirtualMC
87#include <TArrayI.h> // ROOT_TArrayI
88
89//====================================================================
90ClassImp(AliFMDG3Simulator)
91#if 0
92 ; // This is here to keep Emacs for indenting the next line
93#endif
94
95//____________________________________________________________________
96AliFMDG3Simulator::AliFMDG3Simulator()
97{
98 // Default constructor
99 fSectorOff = 1;
100 fModuleOff = 3;
101 fRingOff = 4;
102 fDetectorOff = 5;
103}
104
105//____________________________________________________________________
106AliFMDG3Simulator::AliFMDG3Simulator(AliFMD* fmd, Bool_t detailed)
107 : AliFMDSimulator(fmd, detailed)
108{
109 // Normal constructor
110 //
111 // Parameters:
112 //
113 // fmd Pointer to AliFMD object
114 // detailed Whether to make a detailed simulation or not
115 //
116 fSectorOff = 1;
117 fModuleOff = 3;
118 fRingOff = 4;
119 fDetectorOff = 5;
120}
121
122//____________________________________________________________________
123Bool_t
124AliFMDG3Simulator::RingGeometry(AliFMDRing* r)
125{
126 // Setup the geometry of a ring. The defined TGeoVolume is
127 // returned, and should be used when setting up the rest of the
128 // volumes.
129 //
130 // Parameters:
131 //
132 // r Pointer to ring geometry object
133 //
134 // Returns:
135 // true on success
136 //
137 if (!r) {
138 AliError("Didn't get a ring object");
139 return kFALSE;
140 }
141 Char_t id = r->GetId();
142 Double_t siThick = r->GetSiThickness();
143 // const Int_t nv = r->GetNVerticies();
144 TVector2* a = r->GetVertex(5);
145 TVector2* b = r->GetVertex(3);
146 TVector2* c = r->GetVertex(4);
147 Double_t theta = r->GetTheta();
148 Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
149 * r->GetBondingWidth());
150 Double_t rmax = b->Mod();
151 Double_t rmin = r->GetLowR();
152 Double_t pcbThick = r->GetPrintboardThickness();
153 Double_t modSpace = r->GetModuleSpacing();
154 Double_t legr = r->GetLegRadius();
155 Double_t legl = r->GetLegLength();
156 Double_t legoff = r->GetLegOffset();
157 Int_t ns = r->GetNStrips();
4ac75127 158 Double_t space = r->GetSpacing();
1a1fdef7 159 Double_t stripoff = a->Mod();
160 Double_t dstrip = (rmax - stripoff) / ns;
161 Double_t par[10];
162 TString name;
163 TString name2;
164 TVirtualMC* mc = TVirtualMC::GetMC();
165
4ac75127 166 Int_t siId = fFMD->GetIdtmed()->At(kSiId);
1a1fdef7 167 Int_t airId = fFMD->GetIdtmed()->At(kAirId);
168 Int_t pcbId = fFMD->GetIdtmed()->At(kPcbId);
169 Int_t plaId = fFMD->GetIdtmed()->At(kPlasticId);
54240c8d 170 // Int_t copId = fFMD->GetIdtmed()->At(kCopperId);
171 // Int_t chiId = fFMD->GetIdtmed()->At(kSiChipId);
4ac75127 172
173 Double_t ringWidth = r->GetRingDepth();
174 Double_t x = 0;
175 Double_t y = 0;
176 Double_t z = 0;
177 Double_t backWidth = siThick + pcbThick + legl + space;
178 Double_t frontWidth = backWidth + modSpace;
1a1fdef7 179
1a1fdef7 180 // Ring mother volume
181 par[0] = rmin;
182 par[1] = rmax;
4ac75127 183 par[2] = ringWidth / 2;
1a1fdef7 184 name = Form(fgkRingName, id);
185 mc->Gsvolu(name.Data(), "TUBE", airId, par, 3);
186
4ac75127 187 // Back container volume
1a1fdef7 188 par[0] = rmin;
189 par[1] = rmax;
4ac75127 190 par[2] = backWidth / 2;
1a1fdef7 191 par[3] = -theta;
4ac75127 192 par[4] = +theta;
193 TString backName(Form(fgkBackVName, id));
194 mc->Gsvolu(backName.Data(), "TUBS", airId, par, 5);
195
196 // Front container volume
197 par[2] = frontWidth / 2;
198 TString frontName(Form(fgkFrontVName, id));
199 mc->Gsvolu(frontName.Data(), "TUBS", airId, par, 5);
200
201 Double_t topL = (b->X() - c->X());
202 Double_t botL = (c->X() - a->X());
203 Int_t rot;
204 mc->Matrix(rot, 90, 90, 0, 90, 90, 0);
205
206 Double_t zFront = - frontWidth / 2 + siThick / 2;
207 Double_t zBack = - backWidth / 2 + siThick / 2;
208 if (fUseDivided) {
209 fSectorOff = 1;
210 fModuleOff = 3;
211 fRingOff = 4;
212 fDetectorOff = 5;
213
214 // Virtual volume shape to divide - This volume is only defined if
215 // the geometry is set to be detailed.
216 par[0] = rmin;
217 par[1] = rmax;
218 par[2] = siThick / 2;
219 par[3] = -theta;
220 par[4] = theta;
221 name = Form(fgkActiveName, id);
222 mc->Gsvolu(name.Data(), "TUBS", (fDetailed ? airId : siId), par, 5);
1a1fdef7 223
4ac75127 224 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, 0, "ONLY");
225 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, 0, "ONLY");
1a1fdef7 226
4ac75127 227 Int_t sid = -1;
228 if (fDetailed) {
229 // Divide the volume into sectors
230 name2 = name;
231 name = Form(fgkSectorName, id);
232 mc->Gsdvn2(name.Data(), name2.Data(), 2, 2, -theta, siId);
233
234 // Divide the volume into strips
235 name2 = name;
236 name = Form(fgkStripName, id);
237 mc->Gsdvt2(name.Data(), name2.Data(), dstrip, 1, stripoff, siId, ns);
238 sid = mc->VolId(name.Data());
239 AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
240 }
1a1fdef7 241
4ac75127 242 switch (id) {
243 case 'i': case 'I': fActiveId[0] = sid; break;
244 case 'o': case 'O': fActiveId[2] = sid; break;
245 }
1a1fdef7 246 }
4ac75127 247 else {
248 fSectorOff = -1;
249 fModuleOff = 1;
250 fRingOff = 2;
251 fDetectorOff = 3;
252
253 // Create top of module shape
254 par[0] = c->Y();
255 par[1] = b->Y();
256 par[2] = siThick / 2;
257 par[3] = topL / 2;
258 name = Form(fgkModuleName, id);
259 name[3] = 'T';
260 mc->Gsvolu(name.Data(), "TRD1", siId, par, 4);
261 Int_t tid = mc->VolId(name.Data());
262 x = rmin + botL + topL / 2;
263 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
264 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
1a1fdef7 265
4ac75127 266
267 // Create bottom of module shape
268 par[0] = a->Y();
269 par[1] = c->Y();
270 par[3] = botL / 2;
271 name = Form(fgkModuleName, id);
272 name[3] = 'B';
273 mc->Gsvolu(name.Data(), "TRD1", siId, par, 4);
274 Int_t bid = mc->VolId(name.Data());
275 x = rmin + botL / 2;
276 z = - backWidth / 2 + siThick / 2;
277 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
278 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
279
280 switch (id) {
281 case 'i': case 'I': fActiveId[0] = tid; fActiveId[1] = bid; break;
282 case 'o': case 'O': fActiveId[2] = tid; fActiveId[3] = bid; break;
283 }
284 }
285
286
1a1fdef7 287 // Shape of Printed circuit Board
288 // Top
4ac75127 289 par[0] = c->Y() - off;
290 par[1] = b->Y() - off;
291 par[2] = pcbThick / 2;
292 par[3] = topL / 2;
293 x = rmin + botL + topL / 2;
294 zBack += siThick / 2 + space + pcbThick / 2;
295 zFront += siThick / 2 + space + pcbThick / 2;
1a1fdef7 296 name = Form(fgkPCBName, id, 'T');
297 mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
4ac75127 298 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
299 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
300
1a1fdef7 301 // Bottom
302 par[0] = a->Y() - off;
303 par[1] = c->Y() - off;
4ac75127 304 par[3] = botL / 2;
1a1fdef7 305 name = Form(fgkPCBName, id, 'B');
4ac75127 306 x = rmin + botL / 2;
1a1fdef7 307 mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
4ac75127 308 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
309 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
1a1fdef7 310
4ac75127 311 Double_t x1, y1;
1a1fdef7 312 // Short leg volume
4ac75127 313 par[0] = legr - .1;
314 par[1] = legr;
315 par[2] = legl / 2;
316 x = a->X() + legoff + legr;
317 x1 = c->X();
318 y1 = c->Y() - legoff - legr - off;
319 zBack += pcbThick / 2 + legl / 2;
320 zFront += pcbThick / 2 + legl / 2 + modSpace / 2;
1a1fdef7 321 name = Form(fgkShortLegName, id);
322 mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
4ac75127 323 mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, 0, "ONLY");
324 mc->Gspos(name.Data(), 1, backName.Data(), x1, y1, zBack, 0, "ONLY");
325 mc->Gspos(name.Data(), 2, backName.Data(), x1, -y1, zBack, 0, "ONLY");
1a1fdef7 326
327 // Long leg volume
328 par[2] += modSpace / 2;
329 name = Form(fgkLongLegName, id);
330 mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
4ac75127 331 mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, 0, "ONLY");
332 mc->Gspos(name.Data(), 1, frontName.Data(), x1, y1, zFront, 0, "ONLY");
333 mc->Gspos(name.Data(), 2, frontName.Data(), x1, -y1, zFront, 0, "ONLY");
1a1fdef7 334
4ac75127 335 // Place modules+pcb+legs in ring volume
1a1fdef7 336 Int_t nmod = r->GetNModules();
337 name2 = Form(fgkRingName, id);
338 AliDebug(10, Form("making %d modules in ring %c", nmod, id));
339 for (Int_t i = 0; i < nmod; i++) {
340 Double_t th = (i + .5) * 2 * theta;
341 Bool_t isFront = (i % 2 == 0);
4ac75127 342 name = (isFront ? frontName : backName);
343 z = (isFront ? 0 : modSpace) / 2;
1a1fdef7 344 mc->Matrix(rot, 90, th, 90, fmod(90 + th, 360), 0, 0);
345 mc->Gspos(name.Data(), i, name2.Data(), 0, 0, z, rot, "ONLY");
346 }
4ac75127 347
1a1fdef7 348 return kTRUE;
349}
350
351//____________________________________________________________________
352Bool_t
353AliFMDG3Simulator::DetectorGeometry(AliFMDDetector* d, Double_t zmother)
354{
355 // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
356 // This includes putting the Honeycomb support plates and the rings
357 // into the mother volumes.
358 //
359 // Parameeters:
360 // d The detector geometry to use
361 // zmother The midpoint in global coordinates of detector vol.
362 //
363 // Returns:
364 // true on success
365 //
366 if (!d) return kFALSE;
367
368 TString name;
369 TString name2;
370 TVirtualMC* mc = TVirtualMC::GetMC();
371
372 // Loop over the defined rings
373 for (int i = 0; i < 2; i++) {
374 AliFMDRing* r = 0;
375 Double_t lowr = 0;
376 Double_t highr = 0;
377 Double_t rz = 0;
378 switch (i) {
379 case 0:
380 r = d->GetInner();
381 lowr = d->GetInnerHoneyLowR();
382 highr = d->GetInnerHoneyHighR();
383 rz = d->GetInnerZ();
384 break;
385 case 1:
386 r = d->GetOuter();
387 lowr = d->GetOuterHoneyLowR();
388 highr = d->GetOuterHoneyHighR();
389 rz = d->GetOuterZ();
390 break;
391 }
392 if (!r) continue;
393 Char_t c = r->GetId();
394 Int_t id = d->GetId();
395 Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
396 Int_t alId = (fFMD->GetIdtmed()->At(kAlId));
397 Double_t hcThick = d->GetHoneycombThickness();
398 Double_t alThick = d->GetAlThickness();
399 Double_t par[10];
400 Double_t z;
401 // Place ring in mother volume
402 if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
403 else z = zmother - rz + r->GetRingDepth() / 2;
404 name = Form(fgkRingName, c);
405 name2 = d->GetName();
406 mc->Gspos(name.Data(), Int_t(c), name2.Data(), 0, 0, z, 0, "ONLY");
407
408 // Place Top Honeycomb in mother volume
409 z += + r->GetRingDepth() / 2 + hcThick / 2;
410 // Top of Honeycomb
411 par[0] = lowr;
412 par[1] = highr;
413 par[2] = hcThick / 2;
414 par[3] = 0;
415 par[4] = 180;
416 name = Form(fgkTopHCName, id, c);
417 mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
418 mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
419
420 par[0] += alThick;
421 par[1] -= alThick;
422 par[2] -= alThick / 2;
423 name2 = name;
424 name = Form(fgkTopIHCName, id, c);
425 mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
426 mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
427
428 // Bot of Honeycomb
429 par[0] = lowr;
430 par[1] = highr;
431 par[2] = hcThick / 2;
432 par[3] = 180;
433 par[4] = 360;
434 name2 = d->GetName();
435 name = Form(fgkBotHCName, id, c);
436 mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
437 mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
438
439 par[0] += alThick;
440 par[1] -= alThick;
441 par[2] -= alThick / 2;
442 name2 = name;
443 name = Form(fgkBotIHCName, id, c);
444 mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
445 mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
446 }
447 return kTRUE;
448}
449
450//____________________________________________________________________
451Bool_t
452AliFMDG3Simulator::FMD1Geometry(AliFMD1* fmd1)
453{
454 // Setup the FMD1 geometry. The FMD1 only has one ring, and no
455 // special support as it is at the momement.
456 //
457 // See also AliFMDG3Simulator::DetectorGeometry
458 //
459 if (!fmd1) return kFALSE;
460 Double_t rmin = fmd1->GetInner()->GetLowR();
461 Double_t rmax = fmd1->GetInnerHoneyHighR();
462 Double_t hcThick = fmd1->GetHoneycombThickness();
463 Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
464 Double_t z = fmd1->GetInnerZ() + w / 2;
465 TVirtualMC* mc = TVirtualMC::GetMC();
466 Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
467
468 Double_t par[3];
469 par[0] = rmin;
470 par[1] = rmax;
471 par[2] = w / 2;
472 mc->Gsvolu(fmd1->GetName(), "TUBE", airId, par, 3);
473 mc->Gspos(fmd1->GetName(), fmd1->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
474
475 return DetectorGeometry(fmd1, z);
476}
477
478//____________________________________________________________________
479Bool_t
480AliFMDG3Simulator::FMD2Geometry(AliFMD2* fmd2)
481{
482 // Setup the FMD2 geometry. The FMD2 has no
483 // special support as it is at the momement.
484 //
485 // See also AliFMDG3Simulator::DetectorGeometry
486 //
487 if (!fmd2) return kFALSE;
488 Double_t rmin = fmd2->GetInner()->GetLowR();
489 Double_t rmax = fmd2->GetOuterHoneyHighR();
490 Double_t hcThick = fmd2->GetHoneycombThickness();
491 Double_t ow = fmd2->GetInner()->GetRingDepth();
492 Double_t iz = fmd2->GetInnerZ();
493 Double_t oz = fmd2->GetOuterZ();
494 Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
495 Double_t z = oz + w / 2;
496
497 TVirtualMC* mc = TVirtualMC::GetMC();
498 Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
499
500 Double_t par[3];
501 par[0] = rmin;
502 par[1] = rmax;
503 par[2] = w / 2;
504 mc->Gsvolu(fmd2->GetName(), "TUBE", airId, par, 3);
505 mc->Gspos(fmd2->GetName(), fmd2->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
506
507 return DetectorGeometry(fmd2, z);
508}
509
510//____________________________________________________________________
511Bool_t
512AliFMDG3Simulator::FMD3Geometry(AliFMD3* fmd3)
513{
514 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
515 // structure, as the support will also support the vacuum
516 // beam-pipe.
517 //
518 // See also AliFMDG3Simulator::DetectorGeometry
519 //
520 if (!fmd3) return kFALSE;
521 Double_t nlen = fmd3->GetNoseLength();
522 Double_t nz = fmd3->GetNoseZ();
523 Double_t noser1 = fmd3->GetNoseLowR();
524 Double_t noser2 = fmd3->GetNoseHighR();
525 Double_t conel = fmd3->GetConeLength();
526 Double_t backl = fmd3->GetBackLength();
527 Double_t backr1 = fmd3->GetBackLowR();
528 Double_t backr2 = fmd3->GetBackHighR();
529 Double_t zdist = conel - backl - nlen;
530 Double_t tdist = backr2 - noser2;
531 Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
532 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
533 Double_t innerZ = fmd3->GetInnerZ();
534 Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
535 - fmd3->GetHoneycombThickness());
536 Double_t outerZ = fmd3->GetOuterZ();
537 Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
538 - fmd3->GetHoneycombThickness());
539 Double_t innerr1 = fmd3->GetInner()->GetLowR();
540 // Double_t innerr2 = fmd3->GetInner()->GetHighR();
541 Double_t outerr1 = fmd3->GetOuter()->GetLowR();
542 // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
543 Double_t flanger = fmd3->GetFlangeR();
544 Double_t minZ = TMath::Min(nz - conel, outerZh);
545 Double_t z = fmd3->GetZ();
546 Double_t zi;
547 TVirtualMC* mc = TVirtualMC::GetMC();
548 Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
549 Int_t cId = (fFMD->GetIdtmed()->At(kCarbonId));
550 Double_t par[27];
551
552 // FMD3 volume
553 par[0] = 0;
554 par[1] = 360;
555 par[2] = 8;
556 // First
557 par[3] = z - nz;
558 par[4] = noser1;
559 par[5] = noser2;
560 // Second
561 par[6] = z - (nz - nlen);
562 par[7] = noser1;
563 par[8] = fmd3->ConeR(z - par[6])+.15;
564 // Third
565 par[9] = z - innerZ;
566 par[10] = innerr1;
567 par[11] = fmd3->ConeR(z - par[9])+.15;
568 // Fourth
569 par[12] = z - innerZh;
570 par[13] = innerr1;
571 par[14] = fmd3->ConeR(z - par[12])+.15;
572 // Fifth
573 par[15] = par[12];
574 par[16] = outerr1;
575 par[17] = fmd3->ConeR(z - par[15])+.15;
576 // Sixth
577 par[18] = z - nz + zdist + nlen;
578 par[19] = outerr1;
579 par[20] = fmd3->ConeR(z - par[18])+.15;
580 // Seventh
581 par[21] = z - nz + nlen + zdist;
582 par[22] = outerr1;
583 par[23] = flanger+1.5;
584 // Eight
585 par[24] = z - minZ;
586 par[25] = outerr1;
587 par[26] = flanger+1.5;
588 mc->Gsvolu(fmd3->GetName(), "PCON", airId, par, 27);
589
590 Int_t id;
591 mc->Matrix(id, 270, 180, 90, 90, 180, 0);
592 mc->Gspos(fmd3->GetName(), fmd3->GetId(), "ALIC", 0, 0, z, id, "ONLY");
593
594 // Nose volume
595 par[0] = noser1;
596 par[1] = noser2;
597 par[2] = nlen / 2;
598 zi = z - nz + nlen / 2;
599 mc->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
600 mc->Gspos(fgkNoseName, 0, fmd3->GetName(), 0, 0, zi, 0, "MANY");
601
602 // Back
603 par[0] = backr1;
604 par[1] = backr2;
605 par[2] = backl / 2;
606 zi = z - nz + conel - backl / 2;
607 mc->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
608 mc->Gspos(fgkBackName, 0, fmd3->GetName(), 0, 0, zi, 0, "ONLY");
609
610 Int_t n;
611 Double_t r;
612 // The flanges
613 par[0] = (flanger - backr2) / 2;
614 par[1] = fmd3->GetBeamWidth() / 2;
615 par[2] = backl / 2;
616 mc->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
617 n = fmd3->GetNFlange();
618 r = backr2 + (flanger - backr2) / 2;
619 for (Int_t i = 0; i < n; i++) {
620 Double_t phi = 360. / n * i + 180. / n;
621 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
622 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
623 Int_t id;
624 mc->Matrix(id, 90, phi, 90, 90 + phi, 0, 0);
625 mc->Gspos(fgkFlangeName, i, fmd3->GetName(), x, y, zi, id, "ONLY");
626 }
627
628 // The Beams
629 par[0] = fmd3->GetBeamThickness() / 2;
630 par[1] = fmd3->GetBeamWidth() / 2;
631 par[2] = beaml / 2;
632 mc->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
633 n = fmd3->GetNBeam();
634 r = noser2 + tdist / 2;
635 zi = z - nz + nlen + zdist / 2;
636 for (Int_t i = 0; i < n; i++) {
637 Double_t phi = 360. / n * i;
638 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
639 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
640 Int_t id;
641 (void)theta;
642 mc->Matrix(id, 90-theta, phi, 90, 90 + phi, 360 - theta, phi);
643 mc->Gspos(fgkBeamName, i, fmd3->GetName(), x, y, zi, id, "MANY");
644 }
645
646 return DetectorGeometry(fmd3, z);
647}
648
649//____________________________________________________________________
650void
651AliFMDG3Simulator::DefineGeometry()
652{
653 // Setup up the FMD geometry.
654 AliDebug(10, "Setting up volume");
655
656 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
657 if (!RingGeometry(fmd->GetInner())) {
658 AliError("Failed to create inner ring volume");
659 return;
660 }
661 if (!RingGeometry(fmd->GetOuter())) {
662 AliError("Failed to create outer ring volume");
663 return;
664 }
665 FMD1Geometry(fmd->GetFMD1());
666 FMD2Geometry(fmd->GetFMD2());
667 FMD3Geometry(fmd->GetFMD3());
668}
669
670//____________________________________________________________________
671//
672// EOF
673//