]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - FMD/AliFMD.cxx
Added various ROOT and Shell scripts used for development of the FMD code
[u/mrichter/AliRoot.git] / FMD / AliFMD.cxx
... / ...
CommitLineData
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 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//
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//
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//
98
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
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
125
126//____________________________________________________________________
127ClassImp(AliFMD);
128
129//____________________________________________________________________
130AliFMD::AliFMD()
131 : fInner(0),
132 fOuter(0),
133 fFMD1(0),
134 fFMD2(0),
135 fFMD3(0),
136 fSDigits(0),
137 fNsdigits(0),
138 fPrintboardRotationId(0),
139 fIdentityRotationId(0),
140 fShortLegId(0),
141 fLongLegId(0),
142 fLegLength(0),
143 fLegRadius(0),
144 fModuleSpacing(0),
145 fSiDensity(0),
146 fSiThickness(0),
147 fSiDeDxMip(1.664),
148 fVA1MipRange(0),
149 fAltroChannelSize(0),
150 fSampleRate(0)
151{
152 //
153 // Default constructor for class AliFMD
154 //
155 AliDebug(0, "Default CTOR");
156 fHits = 0;
157 fDigits = 0;
158 fIshunt = 0;
159}
160
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
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),
195 fFMD3(0),
196 fSDigits(0),
197 fNsdigits(0),
198 fPrintboardRotationId(0),
199 fIdentityRotationId(0),
200 fShortLegId(0),
201 fLongLegId(0),
202 fLegLength(0),
203 fLegRadius(0),
204 fModuleSpacing(0),
205 fSiDensity(0),
206 fSiThickness(0),
207 fSiDeDxMip(1.664),
208 fVA1MipRange(0),
209 fAltroChannelSize(0),
210 fSampleRate(0)
211{
212 //
213 // Standard constructor for Forward Multiplicity Detector
214 //
215 AliDebug(0, "Standard CTOR");
216
217 // Initialise Hit array
218 HitsArray();
219 gAlice->GetMCApp()->AddHitList(fHits);
220
221 // (S)Digits for the detectors disk
222 DigitsArray();
223 SDigitsArray();
224
225 // CHC: What is this?
226 fIshunt = 0;
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();
252 SetSiThickness();
253 SetSiDensity();
254 SetVA1MipRange();
255 SetAltroChannelSize();
256 SetSampleRate();
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);
263 fInner->SetSiThickness(fSiThickness);
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);
271 fOuter->SetNStrips(256);
272 fOuter->SetSiThickness(fSiThickness);
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);
287}
288
289//____________________________________________________________________
290AliFMD::~AliFMD ()
291{
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
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
339//====================================================================
340//
341// GEometry ANd Traking
342//
343//____________________________________________________________________
344void
345AliFMD::CreateGeometry()
346{
347 //
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
373 // DebugGuard guard("AliFMD::CreateGeometry");
374 AliDebug(10, "Creating geometry");
375
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;
385 name = "FSL";
386 fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
387
388 par[2] += fModuleSpacing / 2;
389 name = "FLL";
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
403 fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
404 fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
405 fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
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
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
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
506#if 0
507 // Kaption
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;
517 id = KaptionId;
518 AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
519 AliMedium(kAlId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
520 maxStepSize,maxEnergyLoss,precision,minStepSize);
521 }
522#endif
523
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);
582}
583
584//____________________________________________________________________
585void
586AliFMD::Init()
587{
588 //
589 // Initialis the FMD after it has been built
590 Int_t i;
591 //
592 if (fDebug) {
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;
598 //
599 // Here the FMD initialisation code (if any!)
600 for (i = 0; i < 80; i++) cout << "*";
601 cout << endl;
602 }
603 //
604 //
605}
606
607//====================================================================
608//
609// Graphics and event display
610//
611//____________________________________________________________________
612void
613AliFMD::BuildGeometry()
614{
615 //
616 // Build simple ROOT TNode geometry for event display
617 //
618 // Build a simplified geometry of the FMD used for event display
619 //
620 // The actual building of the TNodes is done by
621 // AliFMDSubDetector::SimpleGeometry.
622 AliDebug(10, "Creating a simplified geometry");
623
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);
629}
630
631//____________________________________________________________________
632void
633AliFMD::DrawDetector()
634{
635 //
636 // Draw a shaded view of the Forward multiplicity detector
637 //
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");
662}
663
664//____________________________________________________________________
665Int_t
666AliFMD::DistanceToPrimitive(Int_t, Int_t)
667{
668 //
669 // Calculate the distance from the mouse to the FMD on the screen
670 // Dummy routine
671 //
672 return 9999;
673}
674
675//====================================================================
676//
677// Hit and Digit managment
678//
679//____________________________________________________________________
680void
681AliFMD::MakeBranch(Option_t * option)
682{
683 // Create Tree branches for the FMD.
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 //
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{
715 // Set branch address for the Hits, Digits, and SDigits Tree.
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)
739{
740 // Set the TClonesArray to read hits into.
741 b->SetAddress(&fHits);
742}
743
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 #
766 // hits[9] [Float_t ] Time when the track hit
767 //
768 //
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)
801{
802 //
803 // Add a hit to the list
804 //
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) {
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);
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++;
848}
849
850//____________________________________________________________________
851void
852AliFMD::AddDigit(Int_t* digits)
853{
854 // Add a digit to the Digit tree
855 //
856 // Paramters
857 //
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
888 //
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
909 //
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
943 //
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
952 //
953 TClonesArray& a = *(SDigitsArray());
954
955 new (a[fNsdigits++])
956 AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3);
957}
958
959//____________________________________________________________________
960void
961AliFMD::ResetSDigits()
962{
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{
1015 // Create AliFMDDigit's from AliFMDHit's. This is done by making a
1016 // AliFMDDigitizer, and executing that code.
1017 //
1018 AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
1019 manager->SetInputStream(0, "galice.root");
1020 manager->SetOutputFile("H2Dfile");
1021
1022 /* AliDigitizer* dig =*/ CreateDigitizer(manager);
1023 manager->Exec("");
1024}
1025
1026//____________________________________________________________________
1027void
1028AliFMD::Hits2SDigits()
1029{
1030 // Create AliFMDSDigit's from AliFMDHit's. This is done by creating
1031 // an AliFMDSDigitizer object, and executing it.
1032 //
1033 AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root");
1034 digitizer->SetSampleRate(fSampleRate);
1035 digitizer->SetVA1MipRange(fVA1MipRange);
1036 digitizer->SetAltroChannelSize(fAltroChannelSize);
1037 digitizer->Exec("");
1038}
1039
1040
1041//____________________________________________________________________
1042AliDigitizer*
1043AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
1044{
1045 // Create a digitizer object
1046 AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager);
1047 digitizer->SetSampleRate(fSampleRate);
1048 digitizer->SetVA1MipRange(fVA1MipRange);
1049 digitizer->SetAltroChannelSize(fAltroChannelSize);
1050 return digitizer;
1051}
1052
1053//====================================================================
1054//
1055// Raw data simulation
1056//
1057//__________________________________________________________________
1058void
1059AliFMD::Digits2Raw()
1060{
1061 // Turn digits into raw data.
1062 //
1063 // This uses the class AliFMDRawWriter to do the job. Please refer
1064 // to that class for more information.
1065 AliFMDRawWriter writer(this);
1066 writer.SetSampleRate(fSampleRate);
1067 writer.Exec();
1068}
1069
1070//==================================================================
1071//
1072// Various setter functions for the common paramters
1073//
1074
1075//__________________________________________________________________
1076void
1077AliFMD::SetLegLength(Double_t length)
1078{
1079 // Set lenght of plastic legs that hold the hybrid (print board and
1080 // silicon sensor) onto the honeycomp support
1081 //
1082 // DebugGuard guard("AliFMD::SetLegLength");
1083 AliDebug(10, "AliFMD::SetLegLength");
1084 fLegLength = length;
1085 fInner->SetLegLength(fLegLength);
1086 fOuter->SetLegLength(fLegLength);
1087}
1088
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}
1102
1103//__________________________________________________________________
1104void
1105AliFMD::SetLegRadius(Double_t radius)
1106{
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);
1115}
1116
1117//__________________________________________________________________
1118void
1119AliFMD::SetModuleSpacing(Double_t spacing)
1120{
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{
1139 // Browse this object.
1140 //
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
1151//___________________________________________________________________
1152//
1153// EOF
1154//