]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMD.cxx
Added various ROOT and Shell scripts used for development of the FMD code
[u/mrichter/AliRoot.git] / FMD / AliFMD.cxx
CommitLineData
4c039060 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 **************************************************************************/
88cb7938 15
16/* $Id$ */
17
e802be3e 18//____________________________________________________________________
4347b38f 19//
37c4363a 20// Forward Multiplicity Detector based on Silicon wafers. This class
21// contains the base procedures for the Forward Multiplicity detector
22// Detector consists of 5 Si volumes covered pseudorapidity interval
23// from 1.7 to 5.1.
24//
25// This is the base class for all FMD manager classes.
26//
4347b38f 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 geometry
30//
31//
32// +----------+ +----------+
33// | AliFMDv1 | | AliFMDv1 |
34// +----------+ +----------+
35// | |
36// +----+--------------+
37// |
38// | +------------+ 1 +---------------+
39// | +- | AliFMDRing |<>--| AliFMDPolygon |
40// V 2 | +------------+ +---------------+
41// +--------+<>--+ |
42// | AliFMD | ^
43// +--------+<>--+ V 1..2
44// 3 | +-------------------+
45// +-| AliFMDSubDetector |
46// +-------------------+
47// ^
48// |
49// +-------------+-------------+
50// | | |
51// +---------+ +---------+ +---------+
52// | AliFMD1 | | AliFMD2 | | AliFMD3 |
53// +---------+ +---------+ +---------+
54//
55//
56// * AliFMD
57// This defines the interface for the various parts of AliROOT that
58// uses the FMD, like AliFMDDigitizer, AliFMDReconstructor, and so
59// on.
60//
61// * AliFMDv1
62// This is a concrete implementation of the AliFMD interface.
63// It is the responsibility of this class to create the FMD
64// geometry, process hits in the FMD, and serve hits and digits to
65// the various clients.
66//
67// It uses the objects of class AliFMDSubDetector to do the various
68// stuff for FMD1, 2, and 3
69//
70// * AliFMDRing
71// This class contains all stuff needed to do with a ring. It's
72// used by the AliFMDSubDetector objects to instantise inner and
73// outer rings. The AliFMDRing objects are shared by the
74// AliFMDSubDetector objects, and owned by the AliFMDv1 object.
75//
76// * AliFMDPolygon
77// The code I lifted from TGeoPolygon to help with the geometry of
78// the modules, as well as to decide wether a hit is actually with
79// in the real module shape. The point is, that the shape of the
80// various ring modules are really polygons (much like the lid of a
81// coffin), but it's segmented at constant radius. That is very
82// hard to implement using GEANT 3.21 shapes, so instead the
83// modules are implemented as TUBS (tube sections), and in the step
84// procedure we do the test whether the track was inside the real
85// shape of the module.
86//
87// * AliFMD1, AliFMD2, and AliFMD3
88// These are specialisation of AliFMDSubDetector, that contains the
89// particularities of each of the sub-detector system. It is
90// envisioned that the classes should also define the support
91// volumes and material for each of the detectors.
92//
37c4363a 93// The responsible person for this module is Alla Maevskaia
94// <Alla.Maevskaia@cern.ch>.
95//
96// Many modifications by Christian Holm Christensen <cholm@nbi.dk>
97//
fe4da5cc 98
56b1929b 99// These files are not in the same directory, so there's no reason to
100// ask the preprocessor to search in the current directory for these
101// files by including them with `#include "..."'
102#include <TClonesArray.h> // ROOT_TClonesArray
103#include <TGeometry.h> // ROOT_TGeomtry
104#include <TNode.h> // ROOT_TNode
105#include <TTUBE.h> // ROOT_TTUBE
106#include <TTree.h> // ROOT_TTree
107#include <TVirtualMC.h> // ROOT_TVirtualMC
108#include <TBrowser.h> // ROOT_TBrowser
109#include <TMath.h> // ROOT_TMath
110
111#include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
112#include <AliLoader.h> // ALILOADER_H
113#include <AliRun.h> // ALIRUN_H
114#include <AliMC.h> // ALIMC_H
115#include <AliLog.h> // ALILOG_H
116#include <AliMagF.h> // ALIMAGF_H
e802be3e 117#include "AliFMD.h" // ALIFMD_H
118#include "AliFMDDigit.h" // ALIFMDDIGIG_H
119#include "AliFMDHit.h" // ALIFMDHIT_H
120#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
121#include "AliFMD1.h" // ALIFMD1_H
122#include "AliFMD2.h" // ALIFMD2_H
123#include "AliFMD3.h" // ALIFMD3_H
124#include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H
88cb7938 125
4347b38f 126//____________________________________________________________________
127ClassImp(AliFMD);
128
129//____________________________________________________________________
130AliFMD::AliFMD()
131 : fInner(0),
132 fOuter(0),
133 fFMD1(0),
134 fFMD2(0),
afddaa11 135 fFMD3(0),
136 fSDigits(0),
137 fNsdigits(0),
afddaa11 138 fPrintboardRotationId(0),
139 fIdentityRotationId(0),
140 fShortLegId(0),
141 fLongLegId(0),
142 fLegLength(0),
143 fLegRadius(0),
56b1929b 144 fModuleSpacing(0),
145 fSiDensity(0),
146 fSiThickness(0),
147 fSiDeDxMip(1.664),
148 fVA1MipRange(0),
149 fAltroChannelSize(0),
150 fSampleRate(0)
fe4da5cc 151{
152 //
153 // Default constructor for class AliFMD
154 //
4347b38f 155 AliDebug(0, "Default CTOR");
dc8af42e 156 fHits = 0;
157 fDigits = 0;
4347b38f 158 fIshunt = 0;
fe4da5cc 159}
dc8af42e 160
56b1929b 161//____________________________________________________________________
162AliFMD::AliFMD(const AliFMD& other)
163 : AliDetector(other),
164 fInner(other.fInner),
165 fOuter(other.fOuter),
166 fFMD1(other.fFMD1),
167 fFMD2(other.fFMD2),
168 fFMD3(other.fFMD3),
169 fSDigits(other.fSDigits),
170 fNsdigits(other.fNsdigits),
171 fPrintboardRotationId(other.fPrintboardRotationId),
172 fIdentityRotationId(other.fIdentityRotationId),
173 fShortLegId(other.fShortLegId),
174 fLongLegId(other.fLongLegId),
175 fLegLength(other.fLegLength),
176 fLegRadius(other.fLegRadius),
177 fModuleSpacing(other.fModuleSpacing),
178 fSiDensity(other.fSiDensity),
179 fSiThickness(other.fSiThickness),
180 fSiDeDxMip(other.fSiDeDxMip),
181 fVA1MipRange(other.fVA1MipRange),
182 fAltroChannelSize(other.fAltroChannelSize),
183 fSampleRate(other.fSampleRate)
184{
185 // Copy constructor
186}
187
4347b38f 188//____________________________________________________________________
189AliFMD::AliFMD(const char *name, const char *title, bool detailed)
190 : AliDetector (name, title),
191 fInner(0),
192 fOuter(0),
193 fFMD1(0),
194 fFMD2(0),
afddaa11 195 fFMD3(0),
196 fSDigits(0),
197 fNsdigits(0),
afddaa11 198 fPrintboardRotationId(0),
199 fIdentityRotationId(0),
200 fShortLegId(0),
201 fLongLegId(0),
202 fLegLength(0),
203 fLegRadius(0),
56b1929b 204 fModuleSpacing(0),
205 fSiDensity(0),
206 fSiThickness(0),
207 fSiDeDxMip(1.664),
208 fVA1MipRange(0),
209 fAltroChannelSize(0),
210 fSampleRate(0)
fe4da5cc 211{
212 //
213 // Standard constructor for Forward Multiplicity Detector
214 //
4347b38f 215 AliDebug(0, "Standard CTOR");
dc8af42e 216
fe4da5cc 217 // Initialise Hit array
4347b38f 218 HitsArray();
219 gAlice->GetMCApp()->AddHitList(fHits);
d1280e40 220
4347b38f 221 // (S)Digits for the detectors disk
222 DigitsArray();
223 SDigitsArray();
224
225 // CHC: What is this?
dc8af42e 226 fIshunt = 0;
4347b38f 227 SetMarkerColor(kRed);
228 SetLineColor(kYellow);
229 SetSiDensity();
230
231 // Create sub-volume managers
232 fInner = new AliFMDRing('I', detailed);
233 fOuter = new AliFMDRing('O', detailed);
234 fFMD1 = new AliFMD1();
235 fFMD2 = new AliFMD2();
236 fFMD3 = new AliFMD3();
237
238 // Specify parameters of sub-volume managers
239 fFMD1->SetInner(fInner);
240 fFMD1->SetOuter(0);
241
242 fFMD2->SetInner(fInner);
243 fFMD2->SetOuter(fOuter);
244
245 fFMD3->SetInner(fInner);
246 fFMD3->SetOuter(fOuter);
247
248 SetLegLength();
249 SetLegRadius();
250 SetLegOffset();
251 SetModuleSpacing();
56b1929b 252 SetSiThickness();
253 SetSiDensity();
254 SetVA1MipRange();
255 SetAltroChannelSize();
256 SetSampleRate();
4347b38f 257
258 fInner->SetLowR(4.3);
259 fInner->SetHighR(17.2);
260 fInner->SetWaferRadius(13.4/2);
261 fInner->SetTheta(36/2);
262 fInner->SetNStrips(512);
56b1929b 263 fInner->SetSiThickness(fSiThickness);
4347b38f 264 fInner->SetPrintboardThickness(.11);
265 fInner->SetBondingWidth(.5);
266
267 fOuter->SetLowR(15.6);
268 fOuter->SetHighR(28.0);
269 fOuter->SetWaferRadius(13.4/2);
270 fOuter->SetTheta(18/2);
56b1929b 271 fOuter->SetNStrips(256);
272 fOuter->SetSiThickness(fSiThickness);
4347b38f 273 fOuter->SetPrintboardThickness(.1);
274 fOuter->SetBondingWidth(.5);
275
276
277 fFMD1->SetHoneycombThickness(1);
278 fFMD1->SetInnerZ(340.0);
279
280 fFMD2->SetHoneycombThickness(1);
281 fFMD2->SetInnerZ(83.4);
282 fFMD2->SetOuterZ(75.2);
283
284 fFMD3->SetHoneycombThickness(1);
285 fFMD3->SetInnerZ(-62.8);
286 fFMD3->SetOuterZ(-75.2);
fe4da5cc 287}
d28dcc0d 288
4347b38f 289//____________________________________________________________________
dc8af42e 290AliFMD::~AliFMD ()
d28dcc0d 291{
4347b38f 292 // Destructor for base class AliFMD
293 if (fHits) {
294 fHits->Delete();
295 delete fHits;
296 fHits = 0;
297 }
298 if (fDigits) {
299 fDigits->Delete();
300 delete fDigits;
301 fDigits = 0;
302 }
303 if (fSDigits) {
304 fSDigits->Delete();
305 delete fSDigits;
306 fSDigits = 0;
307 }
308}
309
56b1929b 310//____________________________________________________________________
311AliFMD&
312AliFMD::operator=(const AliFMD& other)
313{
314 AliDetector::operator=(other);
315 fInner = other.fInner;
316 fOuter = other.fOuter;
317 fFMD1 = other.fFMD1;
318 fFMD2 = other.fFMD2;
319 fFMD3 = other.fFMD3;
320 fSDigits = other.fSDigits;
321 fNsdigits = other.fNsdigits;
322 fSiDensity = other.fSiDensity;
323 fPrintboardRotationId = other.fPrintboardRotationId;
324 fIdentityRotationId = other.fIdentityRotationId;
325 fShortLegId = other.fShortLegId;
326 fLongLegId = other.fLongLegId;
327 fLegLength = other.fLegLength;
328 fLegRadius = other.fLegRadius;
329 fModuleSpacing = other.fModuleSpacing;
330 fSiDensity = other.fSiDensity;
331 fSiThickness = other.fSiThickness;
332 fVA1MipRange = other.fVA1MipRange;
333 fAltroChannelSize = other.fAltroChannelSize;
334 fSampleRate = other.fSampleRate;
335
336 return *this;
337}
338
4347b38f 339//====================================================================
340//
341// GEometry ANd Traking
342//
343//____________________________________________________________________
344void
345AliFMD::CreateGeometry()
346{
4347b38f 347 //
37c4363a 348 // Create the geometry of Forward Multiplicity Detector. The actual
349 // construction of the geometry is delegated to the class AliFMDRing
350 // and AliFMDSubDetector and the relevant derived classes.
351 //
352 // The flow of this member function is:
353 //
354 // FOR rings fInner and fOuter DO
355 // AliFMDRing::Init();
356 // END FOR
357 //
358 // Set up hybrud card support (leg) volume shapes
359 //
360 // FOR rings fInner and fOuter DO
361 // AliFMDRing::SetupGeometry();
362 // END FOR
363 //
364 // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO
365 // AliFMDSubDetector::SetupGeomtry();
366 // END FOR
367 //
368 // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO
369 // AliFMDSubDetector::Geomtry();
370 // END FOR
371 //
372
4347b38f 373 // DebugGuard guard("AliFMD::CreateGeometry");
374 AliDebug(10, "Creating geometry");
dc8af42e 375
4347b38f 376 fInner->Init();
377 fOuter->Init();
378
379 TString name;
380 Double_t par[3];
381
382 par[0] = fLegRadius - .1;
383 par[1] = fLegRadius;
384 par[2] = fLegLength / 2;
42403906 385 name = "FSL";
4347b38f 386 fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
387
388 par[2] += fModuleSpacing / 2;
42403906 389 name = "FLL";
4347b38f 390 fLongLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
391
392 fInner->SetupGeometry((*fIdtmed)[kAirId],
393 (*fIdtmed)[kSiId],
394 (*fIdtmed)[kPcbId],
395 fPrintboardRotationId,
396 fIdentityRotationId);
397 fOuter->SetupGeometry((*fIdtmed)[kAirId],
398 (*fIdtmed)[kSiId],
399 (*fIdtmed)[kPcbId],
400 fPrintboardRotationId,
401 fIdentityRotationId);
402
56b1929b 403 fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
404 fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
405 fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
4347b38f 406
407 fFMD1->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
408 fFMD2->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
409 fFMD3->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
410}
411
412//____________________________________________________________________
413void AliFMD::CreateMaterials()
414{
415 // Register various materials and tracking mediums with the
416 // backend.
417 //
418 // Currently defined materials and mediums are
419 //
420 // FMD Air Normal air
421 // FMD Si Active silicon of sensors
422 // FMD Carbon Normal carbon used in support, etc.
423 // FMD Kapton Carbon used in Honeycomb
424 // FMD PCB Printed circuit board material
425 // FMD Plastic Material for support legs
426 //
427 // Also defined are two rotation matricies.
428 //
429 // DebugGuard guard("AliFMD::CreateMaterials");
430 AliDebug(10, "Creating materials");
431 Int_t id;
432 Double_t a = 0;
433 Double_t z = 0;
434 Double_t density = 0;
435 Double_t radiationLength = 0;
436 Double_t absorbtionLength = 999;
437 Int_t fieldType = gAlice->Field()->Integ(); // Field type
438 Double_t maxField = gAlice->Field()->Max(); // Field max.
439 Double_t maxBending = 0; // Max Angle
440 Double_t maxStepSize = 0.001; // Max step size
441 Double_t maxEnergyLoss = 1; // Max Delta E
442 Double_t precision = 0.001; // Precision
443 Double_t minStepSize = 0.001; // Minimum step size
444
445 // Silicon
446 a = 28.0855;
447 z = 14.;
448 density = fSiDensity;
449 radiationLength = 9.36;
450 maxBending = 1;
451 maxStepSize = .001;
452 precision = .001;
453 minStepSize = .001;
454 id = kSiId;
455 AliMaterial(id, "FMD Si$", a, z, density, radiationLength, absorbtionLength);
456 AliMedium(kSiId, "FMD Si$",id,1,fieldType,maxField,maxBending,
457 maxStepSize,maxEnergyLoss,precision,minStepSize);
458
459
460 // Carbon
461 a = 12.011;
462 z = 6.;
463 density = 2.265;
464 radiationLength = 18.8;
465 maxBending = 10;
466 maxStepSize = .01;
467 precision = .003;
468 minStepSize = .003;
469 id = kCarbonId;
470 AliMaterial(id, "FMD Carbon$", a, z, density, radiationLength,
471 absorbtionLength);
472 AliMedium(kCarbonId, "FMD Carbon$",id,0,fieldType,maxField,maxBending,
473 maxStepSize,maxEnergyLoss,precision,minStepSize);
474
56b1929b 475 // Aluminum
476 a = 26.981539;
477 z = 13.;
478 density = 2.7;
479 radiationLength = 8.9;
480 id = kAlId;
481 AliMaterial(id, "FMD Aluminum$", a, z, density, radiationLength,
482 absorbtionLength);
483 AliMedium(kAlId, "FMD Aluminum$", id, 0, fieldType, maxField, maxBending,
484 maxStepSize, maxEnergyLoss, precision, minStepSize);
485
486
4347b38f 487 // Silicon chip
488 {
489 Float_t as[] = { 12.0107, 14.0067, 15.9994,
490 1.00794, 28.0855, 107.8682 };
491 Float_t zs[] = { 6., 7., 8.,
492 1., 14., 47. };
493 Float_t ws[] = { 0.039730642, 0.001396798, 0.01169634,
494 0.004367771, 0.844665, 0.09814344903 };
495 density = 2.36436;
496 maxBending = 10;
497 maxStepSize = .01;
498 precision = .003;
499 minStepSize = .003;
500 id = kSiChipId;
501 AliMixture(id, "FMD Si Chip$", as, zs, density, 6, ws);
502 AliMedium(kSiChipId, "FMD Si Chip$", id, 0, fieldType, maxField,
503 maxBending, maxStepSize, maxEnergyLoss, precision, minStepSize);
504 }
505
56b1929b 506#if 0
507 // Kaption
4347b38f 508 {
509 Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994};
510 Float_t zs[] = { 1., 6., 7., 8.};
511 Float_t ws[] = { 0.026362, 0.69113, 0.07327, 0.209235};
512 density = 1.42;
513 maxBending = 1;
514 maxStepSize = .001;
515 precision = .001;
516 minStepSize = .001;
56b1929b 517 id = KaptionId;
4347b38f 518 AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
56b1929b 519 AliMedium(kAlId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
4347b38f 520 maxStepSize,maxEnergyLoss,precision,minStepSize);
521 }
56b1929b 522#endif
523
4347b38f 524 // Air
525 {
526 Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 };
527 Float_t zs[] = { 6., 7., 8., 18. };
528 Float_t ws[] = { 0.000124, 0.755267, 0.231781, 0.012827 };
529 density = .00120479;
530 maxBending = 1;
531 maxStepSize = .001;
532 precision = .001;
533 minStepSize = .001;
534 id = kAirId;
535 AliMixture(id, "FMD Air$", as, zs, density, 4, ws);
536 AliMedium(kAirId, "FMD Air$", id,0,fieldType,maxField,maxBending,
537 maxStepSize,maxEnergyLoss,precision,minStepSize);
538 }
539
540 // PCB
541 {
542 Float_t zs[] = { 14., 20., 13., 12.,
543 5., 22., 11., 19.,
544 26., 9., 8., 6.,
545 7., 1.};
546 Float_t as[] = { 28.0855, 40.078, 26.981538, 24.305,
547 10.811, 47.867, 22.98977, 39.0983,
548 55.845, 18.9984, 15.9994, 12.0107,
549 14.0067, 1.00794};
550 Float_t ws[] = { 0.15144894, 0.08147477, 0.04128158, 0.00904554,
551 0.01397570, 0.00287685, 0.00445114, 0.00498089,
552 0.00209828, 0.00420000, 0.36043788, 0.27529426,
553 0.01415852, 0.03427566};
554 density = 1.8;
555 maxBending = 1;
556 maxStepSize = .001;
557 precision = .001;
558 minStepSize = .001;
559 id = kPcbId;
560 AliMixture(id, "FMD PCB$", as, zs, density, 14, ws);
561 AliMedium(kPcbId, "FMD PCB$", id,1,fieldType,maxField,maxBending,
562 maxStepSize,maxEnergyLoss,precision,minStepSize);
563 }
564
565 // Plastic
566 {
567 Float_t as[] = { 1.01, 12.01 };
568 Float_t zs[] = { 1., 6. };
569 Float_t ws[] = { 1., 1. };
570 density = 1.03;
571 maxBending = 10;
572 maxStepSize = .01;
573 precision = .003;
574 minStepSize = .003;
575 id = kPlasticId;
576 AliMixture(id, "FMD Plastic$", as, zs, density, -2, ws);
577 AliMedium(kPlasticId, "FMD Plastic$", id,0,fieldType,maxField,maxBending,
578 maxStepSize,maxEnergyLoss,precision,minStepSize);
579 }
580 AliMatrix(fPrintboardRotationId, 90, 90, 0, 90, 90, 0);
581 AliMatrix(fIdentityRotationId, 90, 0, 90, 90, 0, 0);
d28dcc0d 582}
dc8af42e 583
4347b38f 584//____________________________________________________________________
585void
586AliFMD::Init()
fe4da5cc 587{
588 //
4347b38f 589 // Initialis the FMD after it has been built
590 Int_t i;
591 //
592 if (fDebug) {
7c09877a 593 cout << "\n" << ClassName() << ": " << flush;
594 for (i = 0; i < 35; i++) cout << "*";
595 cout << " FMD_INIT ";
596 for (i = 0; i < 35; i++) cout << "*";
597 cout << "\n" << ClassName() << ": " << flush;
4347b38f 598 //
599 // Here the FMD initialisation code (if any!)
7c09877a 600 for (i = 0; i < 80; i++) cout << "*";
601 cout << endl;
4347b38f 602 }
603 //
fe4da5cc 604 //
fe4da5cc 605}
dc8af42e 606
4347b38f 607//====================================================================
608//
609// Graphics and event display
610//
611//____________________________________________________________________
612void
613AliFMD::BuildGeometry()
b9a2d5e4 614{
4347b38f 615 //
616 // Build simple ROOT TNode geometry for event display
617 //
618 // Build a simplified geometry of the FMD used for event display
619 //
37c4363a 620 // The actual building of the TNodes is done by
621 // AliFMDSubDetector::SimpleGeometry.
4347b38f 622 AliDebug(10, "Creating a simplified geometry");
b9a2d5e4 623
4347b38f 624 TNode* top = gAlice->GetGeometry()->GetNode("alice");
625
626 fFMD1->SimpleGeometry(fNodes, top, GetLineColor(), 0);
627 fFMD2->SimpleGeometry(fNodes, top, GetLineColor(), 0);
628 fFMD3->SimpleGeometry(fNodes, top, GetLineColor(), 0);
37c55dc0 629}
88cb7938 630
4347b38f 631//____________________________________________________________________
632void
633AliFMD::DrawDetector()
fe4da5cc 634{
635 //
37c4363a 636 // Draw a shaded view of the Forward multiplicity detector
fe4da5cc 637 //
4347b38f 638 // DebugGuard guard("AliFMD::DrawDetector");
639 AliDebug(10, "Draw detector");
640
641 //Set ALIC mother transparent
642 gMC->Gsatt("ALIC","SEEN",0);
643
644 //Set volumes visible
645 fFMD1->Gsatt();
646 fFMD2->Gsatt();
647 fFMD3->Gsatt();
648 fInner->Gsatt();
649 fOuter->Gsatt();
650
651 //
652 gMC->Gdopt("hide", "on");
653 gMC->Gdopt("shad", "on");
654 gMC->Gsatt("*", "fill", 7);
655 gMC->SetClipBox(".");
656 gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
657 gMC->DefaultRange();
658 gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055);
659 gMC->Gdhead(1111, "Forward Multiplicity Detector");
660 gMC->Gdman(16, 10, "MAN");
661 gMC->Gdopt("hide", "off");
fe4da5cc 662}
dc8af42e 663
4347b38f 664//____________________________________________________________________
17323043 665Int_t
4347b38f 666AliFMD::DistanceToPrimitive(Int_t, Int_t)
fe4da5cc 667{
668 //
669 // Calculate the distance from the mouse to the FMD on the screen
670 // Dummy routine
671 //
672 return 9999;
673}
dc8af42e 674
4347b38f 675//====================================================================
676//
677// Hit and Digit managment
678//
679//____________________________________________________________________
680void
681AliFMD::MakeBranch(Option_t * option)
682{
683 // Create Tree branches for the FMD.
37c4363a 684 //
685 // Options:
686 //
687 // H Make a branch of TClonesArray of AliFMDHit's
688 // D Make a branch of TClonesArray of AliFMDDigit's
689 // S Make a branch of TClonesArray of AliFMDSDigit's
690 //
4347b38f 691 const Int_t kBufferSize = 16000;
692 TString branchname(GetName());
693 TString opt(option);
694
695 if (opt.Contains("H", TString::kIgnoreCase)) {
696 HitsArray();
697 AliDetector::MakeBranch(option);
698 }
699 if (opt.Contains("D", TString::kIgnoreCase)) {
700 DigitsArray();
701 MakeBranchInTree(fLoader->TreeD(), branchname.Data(),
702 &fDigits, kBufferSize, 0);
703 }
704 if (opt.Contains("S", TString::kIgnoreCase)) {
705 SDigitsArray();
706 MakeBranchInTree(fLoader->TreeS(), branchname.Data(),
707 &fSDigits, kBufferSize, 0);
708 }
709}
710
711//____________________________________________________________________
712void
713AliFMD::SetTreeAddress()
714{
afddaa11 715 // Set branch address for the Hits, Digits, and SDigits Tree.
4347b38f 716 if (fLoader->TreeH()) HitsArray();
717 AliDetector::SetTreeAddress();
718
719 TTree *treeD = fLoader->TreeD();
720 if (treeD) {
721 DigitsArray();
722 TBranch* branch = treeD->GetBranch ("FMD");
723 if (branch) branch->SetAddress(&fDigits);
724 }
725
726 TTree *treeS = fLoader->TreeS();
727 if (treeS) {
728 SDigitsArray();
729 TBranch* branch = treeS->GetBranch ("FMD");
730 if (branch) branch->SetAddress(&fSDigits);
731 }
732}
733
734
735
736//____________________________________________________________________
737void
738AliFMD::SetHitsAddressBranch(TBranch *b)
b9a2d5e4 739{
37c4363a 740 // Set the TClonesArray to read hits into.
4347b38f 741 b->SetAddress(&fHits);
b9a2d5e4 742}
743
4347b38f 744//____________________________________________________________________
745void
746AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
747{
748 // Add a hit to the hits tree
749 //
750 // The information of the two arrays are decoded as
751 //
752 // Parameters
753 // track Track #
754 // ivol[0] [UShort_t ] Detector #
755 // ivol[1] [Char_t ] Ring ID
756 // ivol[2] [UShort_t ] Sector #
757 // ivol[3] [UShort_t ] Strip #
758 // hits[0] [Float_t ] Track's X-coordinate at hit
759 // hits[1] [Float_t ] Track's Y-coordinate at hit
760 // hits[3] [Float_t ] Track's Z-coordinate at hit
761 // hits[4] [Float_t ] X-component of track's momentum
762 // hits[5] [Float_t ] Y-component of track's momentum
763 // hits[6] [Float_t ] Z-component of track's momentum
764 // hits[7] [Float_t ] Energy deposited by track
765 // hits[8] [Int_t ] Track's particle Id #
37c4363a 766 // hits[9] [Float_t ] Time when the track hit
767 //
768 //
4347b38f 769 AddHit(track,
770 UShort_t(vol[0]), // Detector #
771 Char_t(vol[1]), // Ring ID
772 UShort_t(vol[2]), // Sector #
773 UShort_t(vol[3]), // Strip #
774 hits[0], // X
775 hits[1], // Y
776 hits[2], // Z
777 hits[3], // Px
778 hits[4], // Py
779 hits[5], // Pz
780 hits[6], // Energy loss
781 Int_t(hits[7]), // PDG
782 hits[8]); // Time
783}
784
785//____________________________________________________________________
786void
787AliFMD::AddHit(Int_t track,
788 UShort_t detector,
789 Char_t ring,
790 UShort_t sector,
791 UShort_t strip,
792 Float_t x,
793 Float_t y,
794 Float_t z,
795 Float_t px,
796 Float_t py,
797 Float_t pz,
798 Float_t edep,
799 Int_t pdg,
800 Float_t t)
b9a2d5e4 801{
dc8af42e 802 //
4347b38f 803 // Add a hit to the list
dc8af42e 804 //
4347b38f 805 // Parameters:
806 //
807 // track Track #
808 // detector Detector # (1, 2, or 3)
809 // ring Ring ID ('I' or 'O')
810 // sector Sector # (For inner/outer rings: 0-19/0-39)
811 // strip Strip # (For inner/outer rings: 0-511/0-255)
812 // x Track's X-coordinate at hit
813 // y Track's Y-coordinate at hit
814 // z Track's Z-coordinate at hit
815 // px X-component of track's momentum
816 // py Y-component of track's momentum
817 // pz Z-component of track's momentum
818 // edep Energy deposited by track
819 // pdg Track's particle Id #
820 // t Time when the track hit
821 //
822 TClonesArray& a = *(HitsArray());
823 // Search through the list of already registered hits, and see if we
824 // find a hit with the same parameters. If we do, then don't create
825 // a new hit, but rather update the energy deposited in the hit.
826 // This is done, so that a FLUKA based simulation will get the
827 // number of hits right, not just the enerrgy deposition.
828 for (Int_t i = 0; i < fNhits; i++) {
829 if (!a.At(i)) continue;
830 AliFMDHit* hit = static_cast<AliFMDHit*>(a.At(i));
831 if (hit->Detector() == detector
832 && hit->Ring() == ring
833 && hit->Sector() == sector
834 && hit->Strip() == strip
835 && hit->Track() == track) {
37c4363a 836 Warning("AddHit", "already had a hit in FMD%d%c[%2d,%3d] for track # %d,"
837 " adding energy (%f) to that hit (%f) -> %f",
838 detector, ring, sector, strip, track, edep, hit->Edep(),
839 hit->Edep() + edep);
4347b38f 840 hit->SetEdep(hit->Edep() + edep);
841 return;
842 }
843 }
844 // If hit wasn't already registered, do so know.
845 new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, strip,
846 x, y, z, px, py, pz, edep, pdg, t);
847 fNhits++;
b9a2d5e4 848}
fe4da5cc 849
4347b38f 850//____________________________________________________________________
851void
852AliFMD::AddDigit(Int_t* digits)
fe4da5cc 853{
4347b38f 854 // Add a digit to the Digit tree
855 //
856 // Paramters
fe4da5cc 857 //
4347b38f 858 // digits[0] [UShort_t] Detector #
859 // digits[1] [Char_t] Ring ID
860 // digits[2] [UShort_t] Sector #
861 // digits[3] [UShort_t] Strip #
862 // digits[4] [UShort_t] ADC Count
863 // digits[5] [Short_t] ADC Count, -1 if not used
864 // digits[6] [Short_t] ADC Count, -1 if not used
865 //
866 AddDigit(UShort_t(digits[0]), // Detector #
867 Char_t(digits[1]), // Ring ID
868 UShort_t(digits[2]), // Sector #
869 UShort_t(digits[3]), // Strip #
870 UShort_t(digits[4]), // ADC Count1
871 Short_t(digits[5]), // ADC Count2
872 Short_t(digits[6])); // ADC Count3
873}
874
875//____________________________________________________________________
876void
877AliFMD::AddDigit(UShort_t detector,
878 Char_t ring,
879 UShort_t sector,
880 UShort_t strip,
881 UShort_t count1,
882 Short_t count2,
883 Short_t count3)
884{
885 // add a real digit - as coming from data
886 //
887 // Parameters
fe4da5cc 888 //
4347b38f 889 // detector Detector # (1, 2, or 3)
890 // ring Ring ID ('I' or 'O')
891 // sector Sector # (For inner/outer rings: 0-19/0-39)
892 // strip Strip # (For inner/outer rings: 0-511/0-255)
893 // count1 ADC count (a 10-bit word)
894 // count2 ADC count (a 10-bit word), or -1 if not used
895 // count3 ADC count (a 10-bit word), or -1 if not used
896 TClonesArray& a = *(DigitsArray());
897
898 new (a[fNdigits++])
899 AliFMDDigit(detector, ring, sector, strip, count1, count2, count3);
900}
901
902//____________________________________________________________________
903void
904AliFMD::AddSDigit(Int_t* digits)
905{
906 // Add a digit to the SDigit tree
907 //
908 // Paramters
b9a2d5e4 909 //
4347b38f 910 // digits[0] [UShort_t] Detector #
911 // digits[1] [Char_t] Ring ID
912 // digits[2] [UShort_t] Sector #
913 // digits[3] [UShort_t] Strip #
914 // digits[4] [Float_t] Total energy deposited
915 // digits[5] [UShort_t] ADC Count
916 // digits[6] [Short_t] ADC Count, -1 if not used
917 // digits[7] [Short_t] ADC Count, -1 if not used
918 //
919 AddSDigit(UShort_t(digits[0]), // Detector #
920 Char_t(digits[1]), // Ring ID
921 UShort_t(digits[2]), // Sector #
922 UShort_t(digits[3]), // Strip #
923 Float_t(digits[4]), // Edep
924 UShort_t(digits[5]), // ADC Count1
925 Short_t(digits[6]), // ADC Count2
926 Short_t(digits[7])); // ADC Count3
927}
928
929//____________________________________________________________________
930void
931AliFMD::AddSDigit(UShort_t detector,
932 Char_t ring,
933 UShort_t sector,
934 UShort_t strip,
935 Float_t edep,
936 UShort_t count1,
937 Short_t count2,
938 Short_t count3)
939{
940 // add a summable digit
941 //
942 // Parameters
b9a2d5e4 943 //
4347b38f 944 // detector Detector # (1, 2, or 3)
945 // ring Ring ID ('I' or 'O')
946 // sector Sector # (For inner/outer rings: 0-19/0-39)
947 // strip Strip # (For inner/outer rings: 0-511/0-255)
948 // edep Total energy deposited
949 // count1 ADC count (a 10-bit word)
950 // count2 ADC count (a 10-bit word), or -1 if not used
951 // count3 ADC count (a 10-bit word), or -1 if not used
37c4363a 952 //
4347b38f 953 TClonesArray& a = *(SDigitsArray());
954
955 new (a[fNsdigits++])
956 AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3);
fe4da5cc 957}
4347b38f 958
959//____________________________________________________________________
960void
961AliFMD::ResetSDigits()
d28dcc0d 962{
4347b38f 963 //
964 // Reset number of digits and the digits array for this detector
965 //
966 fNsdigits = 0;
967 if (fSDigits) fSDigits->Clear();
968}
969
970
971//____________________________________________________________________
972TClonesArray*
973AliFMD::HitsArray()
974{
975 // Initialize hit array if not already, and return pointer to it.
976 if (!fHits) {
977 fHits = new TClonesArray("AliFMDHit", 1000);
978 fNhits = 0;
979 }
980 return fHits;
981}
982
983//____________________________________________________________________
984TClonesArray*
985AliFMD::DigitsArray()
986{
987 // Initialize digit array if not already, and return pointer to it.
988 if (!fDigits) {
989 fDigits = new TClonesArray("AliFMDDigit", 1000);
990 fNdigits = 0;
991 }
992 return fDigits;
993}
994
995//____________________________________________________________________
996TClonesArray*
997AliFMD::SDigitsArray()
998{
999 // Initialize digit array if not already, and return pointer to it.
1000 if (!fSDigits) {
1001 fSDigits = new TClonesArray("AliFMDSDigit", 1000);
1002 fNsdigits = 0;
1003 }
1004 return fSDigits;
1005}
1006
1007//====================================================================
1008//
1009// Digitization
1010//
1011//____________________________________________________________________
1012void
1013AliFMD::Hits2Digits()
1014{
37c4363a 1015 // Create AliFMDDigit's from AliFMDHit's. This is done by making a
1016 // AliFMDDigitizer, and executing that code.
1017 //
4347b38f 1018 AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
1019 manager->SetInputStream(0, "galice.root");
1020 manager->SetOutputFile("H2Dfile");
dc8af42e 1021
4347b38f 1022 /* AliDigitizer* dig =*/ CreateDigitizer(manager);
1023 manager->Exec("");
1024}
1025
1026//____________________________________________________________________
1027void
1028AliFMD::Hits2SDigits()
1029{
37c4363a 1030 // Create AliFMDSDigit's from AliFMDHit's. This is done by creating
1031 // an AliFMDSDigitizer object, and executing it.
1032 //
56b1929b 1033 AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root");
1034 digitizer->SetSampleRate(fSampleRate);
1035 digitizer->SetVA1MipRange(fVA1MipRange);
1036 digitizer->SetAltroChannelSize(fAltroChannelSize);
1037 digitizer->Exec("");
4347b38f 1038}
1039
dc8af42e 1040
4347b38f 1041//____________________________________________________________________
1042AliDigitizer*
1043AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
1044{
1045 // Create a digitizer object
56b1929b 1046 AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager);
1047 digitizer->SetSampleRate(fSampleRate);
1048 digitizer->SetVA1MipRange(fVA1MipRange);
1049 digitizer->SetAltroChannelSize(fAltroChannelSize);
1050 return digitizer;
4347b38f 1051}
b9a2d5e4 1052
4347b38f 1053//====================================================================
1054//
1055// Raw data simulation
1056//
1057//__________________________________________________________________
1058void
1059AliFMD::Digits2Raw()
1060{
37c4363a 1061 // Turn digits into raw data.
1062 //
e802be3e 1063 // This uses the class AliFMDRawWriter to do the job. Please refer
1064 // to that class for more information.
1065 AliFMDRawWriter writer(this);
56b1929b 1066 writer.SetSampleRate(fSampleRate);
e802be3e 1067 writer.Exec();
b9a2d5e4 1068}
1069
4347b38f 1070//==================================================================
1071//
1072// Various setter functions for the common paramters
1073//
b9a2d5e4 1074
4347b38f 1075//__________________________________________________________________
1076void
1077AliFMD::SetLegLength(Double_t length)
1078{
37c4363a 1079 // Set lenght of plastic legs that hold the hybrid (print board and
4347b38f 1080 // silicon sensor) onto the honeycomp support
1081 //
1082 // DebugGuard guard("AliFMD::SetLegLength");
37c4363a 1083 AliDebug(10, "AliFMD::SetLegLength");
4347b38f 1084 fLegLength = length;
1085 fInner->SetLegLength(fLegLength);
1086 fOuter->SetLegLength(fLegLength);
1087}
b9a2d5e4 1088
4347b38f 1089//__________________________________________________________________
1090void
1091AliFMD::SetLegOffset(Double_t offset)
1092{
1093 // Set offset from edge of hybrid to plastic legs that hold the
1094 // hybrid (print board and silicon sensor) onto the honeycomp
1095 // support
1096 //
1097 // DebugGuard guard("AliFMD::SetLegOffset");
1098 AliDebug(10, "AliFMD::SetLegOffset");
1099 fInner->SetLegOffset(offset);
1100 fOuter->SetLegOffset(offset);
1101}
4110645f 1102
4347b38f 1103//__________________________________________________________________
1104void
1105AliFMD::SetLegRadius(Double_t radius)
4110645f 1106{
4347b38f 1107 // Set the diameter of the plastic legs that hold the hybrid (print
1108 // board and silicon sensor) onto the honeycomp support
1109 //
1110 // DebugGuard guard("AliFMD::SetLegRadius");
1111 AliDebug(10, "AliFMD::SetLegRadius");
1112 fLegRadius = radius;
1113 fInner->SetLegRadius(fLegRadius);
1114 fOuter->SetLegRadius(fLegRadius);
4110645f 1115}
37c55dc0 1116
4347b38f 1117//__________________________________________________________________
1118void
1119AliFMD::SetModuleSpacing(Double_t spacing)
85a5290f 1120{
4347b38f 1121 // Set the distance between the front and back sensor modules
1122 // (module staggering).
1123 //
1124 // DebugGuard guard("AliFMD::SetModuleSpacing");
1125 AliDebug(10, "AliFMD::SetModuleSpacing");
1126 fModuleSpacing = spacing;
1127 fInner->SetModuleSpacing(fModuleSpacing);
1128 fOuter->SetModuleSpacing(fModuleSpacing);
1129}
1130
1131//====================================================================
1132//
1133// Utility
1134//
1135//__________________________________________________________________
1136void
1137AliFMD::Browse(TBrowser* b)
1138{
37c4363a 1139 // Browse this object.
1140 //
4347b38f 1141 AliDebug(10, "AliFMD::Browse");
1142 AliDetector::Browse(b);
1143 if (fInner) b->Add(fInner, "Inner Ring");
1144 if (fOuter) b->Add(fOuter, "Outer Ring");
1145 if (fFMD1) b->Add(fFMD1, "FMD1 SubDetector");
1146 if (fFMD2) b->Add(fFMD2, "FMD2 SubDetector");
1147 if (fFMD3) b->Add(fFMD3, "FMD3 SubDetector");
1148}
1149
1150
4347b38f 1151//___________________________________________________________________
1152//
1153// EOF
1154//