1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //____________________________________________________________________
20 // 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.
25 // This is the base class for all FMD manager classes.
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
32 // +----------+ +----------+
33 // | AliFMDv1 | | AliFMDv0 |
34 // +----------+ +----------+
35 // | | +-----------------+
36 // +----+--------------+ +--| AliFMDDigitizer |
37 // | | +-----------------+
38 // | +---------------------+ |
39 // | +--| AliFMDBaseDigitizer |<--+
40 // V 1 | +---------------------+ |
41 // +--------+<>--+ | +------------------+
42 // | AliFMD | +--| AliFMDSDigitizer |
43 // +--------+<>--+ +------------------+
44 // 1 | +-----------------+
45 // +--| AliFMDSimulator |
46 // +-----------------+
49 // +-------------+-------------+
51 // +--------------------+ +-------------------+
52 // | AliFMDGeoSimulator | | AliFMDG3Simulator |
53 // +--------------------+ +-------------------+
56 // +-----------------------+ +----------------------+
57 // | AliFMDGeoOldSimulator | | AliFMDG3OldSimulator |
58 // +-----------------------+ +----------------------+
62 // This defines the interface for the various parts of AliROOT that
63 // uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
64 // AliFMDReconstructor, and so on.
67 // This is a concrete implementation of the AliFMD interface.
68 // It is the responsibility of this class to create the FMD
72 // This is a concrete implementation of the AliFMD interface.
73 // It is the responsibility of this class to create the FMD
74 // geometry, process hits in the FMD, and serve hits and digits to
75 // the various clients.
78 // This is the base class for the FMD simulation tasks. The
79 // simulator tasks are responsible to implment the geoemtry, and
82 // * AliFMDGeoSimulator
83 // This is a concrete implementation of the AliFMDSimulator that
84 // uses the TGeo classes directly only.
86 // * AliFMDG3Simulator
87 // This is a concrete implementation of the AliFMDSimulator that
88 // uses the TVirtualMC interface with GEANT 3.21-like messages.
91 // These files are not in the same directory, so there's no reason to
92 // ask the preprocessor to search in the current directory for these
93 // files by including them with `#include "..."'
94 #include <math.h> // __CMATH__
95 #include <TClonesArray.h> // ROOT_TClonesArray
96 #include <TGeometry.h> // ROOT_TGeomtry
97 #include <TNode.h> // ROOT_TNode
98 #include <TXTRU.h> // ROOT_TXTRU
99 #include <TRotMatrix.h> // ROOT_TRotMatrix
100 #include <TTUBE.h> // ROOT_TTUBE
101 #include <TTree.h> // ROOT_TTree
102 #include <TBrowser.h> // ROOT_TBrowser
103 #include <TMath.h> // ROOT_TMath
104 #include <TVirtualMC.h> // ROOT_TVirtualMC
105 #include <TVector2.h>
106 #include <TVector3.h>
107 #include <TMarker3DBox.h>
109 #include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
110 #include <AliLoader.h> // ALILOADER_H
111 #include <AliRun.h> // ALIRUN_H
112 #include <AliMC.h> // ALIMC_H
113 #include "AliMagF.h" // ALIMAGF_H
114 #include <AliLog.h> // ALILOG_H
115 #include "AliFMD.h" // ALIFMD_H
116 #include "AliFMDDigit.h" // ALIFMDDIGIG_H
117 #include "AliFMDHit.h" // ALIFMDHIT_H
118 #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
119 #include "AliFMDDetector.h" // ALIFMDDETECTOR_H
120 #include "AliFMDRing.h" // ALIFMDRING_H
121 #include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
122 #include "AliPoints.h" // ALIPOINTS_H
123 #include "AliFMDGeometryBuilder.h"
124 #include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H
127 class AliFMDPoints : public AliPoints
130 AliFMDPoints(AliFMDHit* hit, UInt_t color)
131 : AliPoints(1), fMarker(0)
134 Float_t size = TMath::Min(TMath::Max(hit->Edep() * .1, .1), 1.);
135 TVector3 p(hit->Px(), hit->Py(), hit->Pz());
136 fMarker = new TMarker3DBox(hit->X(), hit->Y(), hit->Z(), size, size, size,
138 fMarker->SetLineColor(color);
139 fMarker->SetRefObject(this);
146 // if (fMarker) delete fMarker;
148 void SetXYZ(Double_t x, Double_t y, Double_t z)
150 if (fMarker) fMarker->SetPosition(x, y, z);
152 Int_t DistancetoPrimitive(Int_t px, Int_t py)
154 return fMarker->DistancetoPrimitive(px, py);
156 void Draw(Option_t* option)
158 if (fMarker) fMarker->Draw(option);
160 void Paint(Option_t* option)
162 if (fMarker) fMarker->Paint(option);
164 void SetMarkerColor(Color_t colour)
166 if (fMarker) fMarker->SetLineColor(colour);
169 TMarker3DBox* fMarker;
173 //____________________________________________________________________
176 ; // This is to keep Emacs from indenting the next line
179 //____________________________________________________________________
188 // Default constructor for class AliFMD
190 AliDebug(10, "\tDefault CTOR");
195 fUseAssembly = kTRUE;
196 fBad = new TClonesArray("AliFMDHit");
199 //____________________________________________________________________
200 AliFMD::AliFMD(const AliFMD& other)
201 : AliDetector(other),
202 fSDigits(other.fSDigits),
203 fNsdigits(other.fNsdigits),
204 fDetailed(other.fDetailed),
208 fUseOld = other.fUseOld;
209 fUseAssembly = other.fUseAssembly;
212 //____________________________________________________________________
213 AliFMD::AliFMD(const char *name, const char *title)
214 : AliDetector (name, title),
221 // Standard constructor for Forward Multiplicity Detector
223 AliDebug(10, "\tStandard CTOR");
225 fUseAssembly = kFALSE;
226 fBad = new TClonesArray("AliFMDHit");
228 // Initialise Hit array
230 gAlice->GetMCApp()->AddHitList(fHits);
232 // (S)Digits for the detectors disk
236 // CHC: What is this?
238 SetMarkerColor(kRed);
239 SetLineColor(kYellow);
242 //____________________________________________________________________
245 // Destructor for base class AliFMD
268 //____________________________________________________________________
270 AliFMD::operator=(const AliFMD& other)
272 // Assignment operator
273 AliDetector::operator=(other);
274 fSDigits = other.fSDigits;
275 fNsdigits = other.fNsdigits;
276 fDetailed = other.fDetailed;
281 //====================================================================
283 // GEometry ANd Traking
285 //____________________________________________________________________
287 AliFMD::CreateGeometry()
290 // Create the geometry of Forward Multiplicity Detector. The actual
291 // construction of the geometry is delegated to the class AliFMDRing
292 // and AliFMDSubDetector and the relevant derived classes.
294 // The flow of this member function is:
296 // FOR rings fInner and fOuter DO
297 // AliFMDRing::Init();
300 // Set up hybrud card support (leg) volume shapes
302 // FOR rings fInner and fOuter DO
303 // AliFMDRing::SetupGeometry();
306 // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO
307 // AliFMDSubDetector::SetupGeomtry();
310 // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO
311 // AliFMDSubDetector::Geomtry();
314 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
315 fmd->SetDetailed(fDetailed);
316 fmd->UseAssembly(fUseAssembly);
320 //____________________________________________________________________
321 void AliFMD::CreateMaterials()
323 // Define the materials and tracking mediums needed by the FMD
324 // simulation. These mediums are made by sending the messages
325 // AliMaterial, AliMixture, and AliMedium to the passed AliModule
326 // object module. The defined mediums are
328 // FMD Si$ Silicon (active medium in sensors)
329 // FMD C$ Carbon fibre (support cone for FMD3 and vacuum pipe)
330 // FMD Al$ Aluminium (honeycomb support plates)
331 // FMD PCB$ Printed Circuit Board (FEE board with VA1_3)
332 // FMD Chip$ Electronics chips (currently not used)
333 // FMD Air$ Air (Air in the FMD)
334 // FMD Plastic$ Plastic (Support legs for the hybrid cards)
336 // Pointers to TGeoMedium objects are retrived from the TGeoManager
337 // singleton. These pointers are later used when setting up the
339 AliDebug(10, "\tCreating materials");
340 // Get pointer to geometry singleton object.
341 AliFMDGeometry* geometry = AliFMDGeometry::Instance();
344 if (gGeoManager && gGeoManager->GetMedium("FMD Si$")) {
345 // We need to figure out the some stuff about the geometry
346 fmd->ExtractGeomInfo();
353 Double_t density = 0;
354 Double_t radiationLength = 0;
355 Double_t absorbtionLength = 999;
356 Int_t fieldType = gAlice->Field()->Integ(); // Field type
357 Double_t maxField = gAlice->Field()->Max(); // Field max.
358 Double_t maxBending = 0; // Max Angle
359 Double_t maxStepSize = 0.001; // Max step size
360 Double_t maxEnergyLoss = 1; // Max Delta E
361 Double_t precision = 0.001; // Precision
362 Double_t minStepSize = 0.001; // Minimum step size
367 density = geometry->GetSiDensity();
368 radiationLength = 9.36;
374 AliMaterial(id, "Si$", a, z, density, radiationLength, absorbtionLength);
375 AliMedium(kSiId, "Si$", id,1,fieldType,maxField,maxBending,
376 maxStepSize,maxEnergyLoss,precision,minStepSize);
383 radiationLength = 18.8;
389 AliMaterial(id, "Carbon$", a, z, density, radiationLength, absorbtionLength);
390 AliMedium(kCarbonId, "Carbon$", id,0,fieldType,maxField,maxBending,
391 maxStepSize,maxEnergyLoss,precision,minStepSize);
397 radiationLength = 8.9;
399 AliMaterial(id, "Aluminum$",a,z, density, radiationLength, absorbtionLength);
400 AliMedium(kAlId, "Aluminum$", id, 0, fieldType, maxField, maxBending,
401 maxStepSize, maxEnergyLoss, precision, minStepSize);
408 radiationLength = 1.43;
410 AliMaterial(id, "Copper$",
411 a, z, density, radiationLength, absorbtionLength);
412 AliMedium(kCopperId, "Copper$", id, 0, fieldType, maxField, maxBending,
413 maxStepSize, maxEnergyLoss, precision, minStepSize);
418 Float_t as[] = { 12.0107, 14.0067, 15.9994,
419 1.00794, 28.0855, 107.8682 };
420 Float_t zs[] = { 6., 7., 8.,
422 Float_t ws[] = { 0.039730642, 0.001396798, 0.01169634,
423 0.004367771, 0.844665, 0.09814344903 };
430 AliMixture(id, "Si Chip$", as, zs, density, 6, ws);
431 AliMedium(kSiChipId, "Si Chip$", id, 0, fieldType, maxField, maxBending,
432 maxStepSize, maxEnergyLoss, precision, minStepSize);
437 Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994};
438 Float_t zs[] = { 1., 6., 7., 8.};
439 Float_t ws[] = { 0.026362, 0.69113, 0.07327, 0.209235};
446 AliMixture(id, "Kaption$", as, zs, density, 4, ws);
447 AliMedium(kKaptonId, "Kaption$", id,0,fieldType,maxField,maxBending,
448 maxStepSize,maxEnergyLoss,precision,minStepSize);
453 Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 };
454 Float_t zs[] = { 6., 7., 8., 18. };
455 Float_t ws[] = { 0.000124, 0.755267, 0.231781, 0.012827 };
462 AliMixture(id, "Air$", as, zs, density, 4, ws);
463 AliMedium(kAirId, "Air$", id,0,fieldType,maxField,maxBending,
464 maxStepSize,maxEnergyLoss,precision,minStepSize);
469 Float_t zs[] = { 14., 20., 13., 12.,
473 Float_t as[] = { 28.0855, 40.078, 26.981538, 24.305,
474 10.811, 47.867, 22.98977, 39.0983,
475 55.845, 18.9984, 15.9994, 12.0107,
477 Float_t ws[] = { 0.15144894, 0.08147477, 0.04128158, 0.00904554,
478 0.01397570, 0.00287685, 0.00445114, 0.00498089,
479 0.00209828, 0.00420000, 0.36043788, 0.27529426,
480 0.01415852, 0.03427566};
487 AliMixture(id, "PCB$", as, zs, density, 14, ws);
488 AliMedium(kPcbId, "PCB$", id,0,fieldType,maxField,maxBending,
489 maxStepSize,maxEnergyLoss,precision,minStepSize);
494 Float_t as[] = { 1.01, 12.01 };
495 Float_t zs[] = { 1., 6. };
496 Float_t ws[] = { 1., 1. };
503 AliMixture(id, "Plastic$", as, zs, density, -2, ws);
504 AliMedium(kPlasticId, "Plastic$", id,0,fieldType,maxField,maxBending,
505 maxStepSize,maxEnergyLoss,precision,minStepSize);
509 //____________________________________________________________________
513 AliDebug(1, "Initialising FMD detector object");
514 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
515 fmd->InitTransformations();
518 //____________________________________________________________________
520 AliFMD::FinishEvent()
522 if (AliLog::GetDebugLevel("FMD", "AliFMD") < 10) return;
523 if (fBad && fBad->GetEntries() > 0) {
524 AliWarning((Form("EndEvent", "got %d 'bad' hits", fBad->GetEntries())));
527 while ((hit = static_cast<AliFMDHit*>(next()))) hit->Print("D");
533 //====================================================================
535 // Graphics and event display
537 //____________________________________________________________________
539 AliFMD::BuildGeometry()
542 // Build simple ROOT TNode geometry for event display
544 // Build a simplified geometry of the FMD used for event display
546 // The actual building of the TNodes is done by
547 // AliFMDSubDetector::SimpleGeometry.
548 AliDebug(10, "\tCreating a simplified geometry");
550 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
552 static TXTRU* innerShape = 0;
553 static TXTRU* outerShape = 0;
554 static TObjArray* innerRot = 0;
555 static TObjArray* outerRot = 0;
557 if (!innerShape || !outerShape) {
558 // Make the shapes for the modules
559 for (Int_t i = 0; i < 2; i++) {
562 case 0: r = fmd->GetRing('I'); break;
563 case 1: r = fmd->GetRing('O'); break;
566 AliError(Form("no ring found for i=%d", i));
569 Double_t siThick = r->GetSiThickness();
570 const Int_t nv = r->GetNVerticies();
571 Double_t theta = r->GetTheta();
572 Int_t nmod = r->GetNModules();
574 TXTRU* shape = new TXTRU(r->GetName(), r->GetTitle(), "void", nv, 2);
575 for (Int_t j = 0; j < nv; j++) {
576 TVector2* vv = r->GetVertex(nv - 1 - j);
577 shape->DefineVertex(j, vv->X(), vv->Y());
579 shape->DefineSection(0, -siThick / 2, 1, 0, 0);
580 shape->DefineSection(1, +siThick / 2, 1, 0, 0);
581 shape->SetLineColor(GetLineColor());
583 TObjArray* rots = new TObjArray(nmod);
584 for (Int_t j = 0; j < nmod; j++) {
585 Double_t th = (j + .5) * theta * 2;
586 TString name(Form("FMD_ring_%c_rot_%02d", r->GetId(), j));
587 TString title(Form("FMD Ring %c Rotation # %d", r->GetId(), j));
588 TRotMatrix* rot = new TRotMatrix(name.Data(), title.Data(),
589 90, th, 90, fmod(90+th,360), 0, 0);
593 switch (r->GetId()) {
595 case 'I': innerShape = shape; innerRot = rots; break;
597 case 'O': outerShape = shape; outerRot = rots; break;
602 TNode* top = gAlice->GetGeometry()->GetNode("alice");
604 for (Int_t i = 1; i <= 3; i++) {
605 AliFMDDetector* det = fmd->GetDetector(i);
607 Warning("BuildGeometry", "FMD%d seems to be disabled", i);
611 Double_t rh = det->GetRing('I')->GetHighR();
613 if (det->GetRing('O')) {
614 w = TMath::Abs(det->GetRingZ('O') - det->GetRingZ('I'));
615 id = (TMath::Abs(det->GetRingZ('O'))
616 > TMath::Abs(det->GetRingZ('I')) ? 'O' : 'I');
617 rh = det->GetRing('O')->GetHighR();
619 w += (det->GetRing(id)->GetModuleSpacing() +
620 det->GetRing(id)->GetSiThickness());
621 TShape* shape = new TTUBE(det->GetName(), det->GetTitle(), "void",
622 det->GetRing('I')->GetLowR(), rh, w / 2);
623 Double_t z = (det->GetRingZ('I') - w / 2);
624 if (z > 0) z += det->GetRing(id)->GetModuleSpacing();
626 TNode* node = new TNode(det->GetName(), det->GetTitle(), shape,
630 for (Int_t j = 0; j < 2; j++) {
636 r = det->GetRing('I'); rshape = innerShape; rots = innerRot; break;
638 r = det->GetRing('O'); rshape = outerShape; rots = outerRot; break;
642 Double_t siThick = r->GetSiThickness();
643 Int_t nmod = r->GetNModules();
644 Double_t modspace = r->GetModuleSpacing();
645 Double_t rz = - (z - det->GetRingZ(r->GetId()));
647 for (Int_t k = 0; k < nmod; k++) {
649 Double_t offz = (k % 2 == 1 ? modspace : 0);
650 TRotMatrix* rot = static_cast<TRotMatrix*>(rots->At(k));
651 TString name(Form("%s%c_module_%02d", det->GetName(), r->GetId(),k));
652 TString title(Form("%s%c Module %d", det->GetName(), r->GetId(),k));
653 TNode* mnod = new TNode(name.Data(), title.Data(), rshape,
654 0, 0, rz - siThick / 2
655 + TMath::Sign(offz,z), rot);
656 mnod->SetLineColor(GetLineColor());
658 } // for (Int_t k = 0 ; ...)
659 } // for (Int_t j = 0 ; ...)
660 } // for (Int_t i = 1 ; ...)
663 //____________________________________________________________________
665 AliFMD::LoadPoints(Int_t /* track */)
668 // Store x, y, z of all hits in memory
671 AliError(Form("fHits == 0. Name is %s",GetName()));
674 Int_t nHits = fHits->GetEntriesFast();
678 Int_t tracks = gAlice->GetMCApp()->GetNtrack();
679 if (fPoints == 0) fPoints = new TObjArray(2 * tracks);
682 AliFMDGeometry* geom = AliFMDGeometry::Instance();
684 geom->InitTransformations();
686 // Now make markers for each hit
687 // AliInfo(Form("Drawing %d hits (have %d points) for track %d",
688 // nHits, fPoints->GetEntriesFast(), track));
689 for (Int_t ihit = 0; ihit < nHits; ihit++) {
690 AliFMDHit* hit = static_cast<AliFMDHit*>(fHits->At(ihit));
692 Double_t edep = hit->Edep();
693 Double_t m = hit->M();
694 Double_t poverm = (m == 0 ? 0 : hit->P());
695 Double_t absQ = TMath::Abs(hit->Q());
697 // This `if' is to debug abnormal energy depositions. We trigger on
698 // p/m approx larger than or equal to a MIP, and a large edep - more
699 // than 1 keV - a MIP is 100 eV.
700 if (edep > absQ * absQ && poverm > 1) bad = kTRUE;
702 AliFMDPoints* p1 = new AliFMDPoints(hit, GetMarkerColor());
703 // AliPoints* p1 = new AliPoints();
704 // p1->SetMarkerColor(GetMarkerColor());
705 // p1->SetMarkerSize(GetMarkerSize());
706 // p1->SetPoint(0, hit->X(), hit->Y(), hit->Z());
707 p1->SetDetector(this);
708 p1->SetParticle(hit->GetTrack());
709 fPoints->AddAt(p1, hit->GetTrack());
711 p1->SetMarkerColor(4);
712 // p1->SetMarkerSize(2 * GetMarkerSize());
716 geom->Detector2XYZ(hit->Detector(), hit->Ring(), hit->Sector(),
717 hit->Strip(), x, y, z);
718 AliFMDPoints* p = new AliFMDPoints(hit, 3);
719 // AliPoints* p = new AliPoints();
720 // p->SetMarkerColor(3);
721 // p->SetMarkerSize(GetMarkerSize());
722 // p->SetPoint(0, x, y, z);
723 p->SetDetector(this);
724 p->SetParticle(hit->GetTrack());
726 p->SetMarkerColor(3);
727 fPoints->AddAt(p, tracks+hit->GetTrack());
729 p->SetMarkerColor(5);
730 // p->SetMarkerSize(2 * GetMarkerSize());
732 // AliInfo(Form("Adding point at %d", tracks+hit->GetTrack()));
736 //____________________________________________________________________
738 AliFMD::DrawDetector()
741 // Draw a shaded view of the Forward multiplicity detector
743 // DebugGuard guard("AliFMD::DrawDetector");
744 AliDebug(10, "\tDraw detector");
747 //Set ALIC mother transparent
748 gMC->Gsatt("ALIC","SEEN",0);
750 gMC->Gdopt("hide", "on");
751 gMC->Gdopt("shad", "on");
752 gMC->Gsatt("*", "fill", 7);
753 gMC->SetClipBox(".");
754 gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
756 gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055);
757 gMC->Gdhead(1111, "Forward Multiplicity Detector");
758 gMC->Gdman(16, 10, "MAN");
759 gMC->Gdopt("hide", "off");
763 //____________________________________________________________________
765 AliFMD::DistanceToPrimitive(Int_t, Int_t)
768 // Calculate the distance from the mouse to the FMD on the screen
774 //====================================================================
776 // Hit and Digit managment
778 //____________________________________________________________________
780 AliFMD::MakeBranch(Option_t * option)
782 // Create Tree branches for the FMD.
786 // H Make a branch of TClonesArray of AliFMDHit's
787 // D Make a branch of TClonesArray of AliFMDDigit's
788 // S Make a branch of TClonesArray of AliFMDSDigit's
790 const Int_t kBufferSize = 16000;
791 TString branchname(GetName());
794 if (opt.Contains("H", TString::kIgnoreCase)) {
796 AliDetector::MakeBranch(option);
798 if (opt.Contains("D", TString::kIgnoreCase)) {
800 MakeBranchInTree(fLoader->TreeD(), branchname.Data(),
801 &fDigits, kBufferSize, 0);
803 if (opt.Contains("S", TString::kIgnoreCase)) {
805 MakeBranchInTree(fLoader->TreeS(), branchname.Data(),
806 &fSDigits, kBufferSize, 0);
810 //____________________________________________________________________
812 AliFMD::SetTreeAddress()
814 // Set branch address for the Hits, Digits, and SDigits Tree.
815 if (fLoader->TreeH()) HitsArray();
816 AliDetector::SetTreeAddress();
818 TTree *treeD = fLoader->TreeD();
821 TBranch* branch = treeD->GetBranch ("FMD");
822 if (branch) branch->SetAddress(&fDigits);
825 TTree *treeS = fLoader->TreeS();
828 TBranch* branch = treeS->GetBranch ("FMD");
829 if (branch) branch->SetAddress(&fSDigits);
835 //____________________________________________________________________
837 AliFMD::SetHitsAddressBranch(TBranch *b)
839 // Set the TClonesArray to read hits into.
840 b->SetAddress(&fHits);
843 //____________________________________________________________________
845 AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
847 // Add a hit to the hits tree
849 // The information of the two arrays are decoded as
853 // ivol[0] [UShort_t ] Detector #
854 // ivol[1] [Char_t ] Ring ID
855 // ivol[2] [UShort_t ] Sector #
856 // ivol[3] [UShort_t ] Strip #
857 // hits[0] [Float_t ] Track's X-coordinate at hit
858 // hits[1] [Float_t ] Track's Y-coordinate at hit
859 // hits[3] [Float_t ] Track's Z-coordinate at hit
860 // hits[4] [Float_t ] X-component of track's momentum
861 // hits[5] [Float_t ] Y-component of track's momentum
862 // hits[6] [Float_t ] Z-component of track's momentum
863 // hits[7] [Float_t ] Energy deposited by track
864 // hits[8] [Int_t ] Track's particle Id #
865 // hits[9] [Float_t ] Time when the track hit
868 AddHitByFields(track,
869 UShort_t(vol[0]), // Detector #
870 Char_t(vol[1]), // Ring ID
871 UShort_t(vol[2]), // Sector #
872 UShort_t(vol[3]), // Strip #
879 hits[6], // Energy loss
880 Int_t(hits[7]), // PDG
884 //____________________________________________________________________
886 AliFMD::AddHitByFields(Int_t track,
904 // Add a hit to the list
909 // detector Detector # (1, 2, or 3)
910 // ring Ring ID ('I' or 'O')
911 // sector Sector # (For inner/outer rings: 0-19/0-39)
912 // strip Strip # (For inner/outer rings: 0-511/0-255)
913 // x Track's X-coordinate at hit
914 // y Track's Y-coordinate at hit
915 // z Track's Z-coordinate at hit
916 // px X-component of track's momentum
917 // py Y-component of track's momentum
918 // pz Z-component of track's momentum
919 // edep Energy deposited by track
920 // pdg Track's particle Id #
921 // t Time when the track hit
922 // l Track length through the material.
923 // stop Whether track was stopped or disappeared
925 TClonesArray& a = *(HitsArray());
926 // Search through the list of already registered hits, and see if we
927 // find a hit with the same parameters. If we do, then don't create
928 // a new hit, but rather update the energy deposited in the hit.
929 // This is done, so that a FLUKA based simulation will get the
930 // number of hits right, not just the enerrgy deposition.
932 for (Int_t i = 0; i < fNhits; i++) {
933 if (!a.At(i)) continue;
934 hit = static_cast<AliFMDHit*>(a.At(i));
935 if (hit->Detector() == detector
936 && hit->Ring() == ring
937 && hit->Sector() == sector
938 && hit->Strip() == strip
939 && hit->Track() == track) {
940 AliDebug(1, Form("already had a hit in FMD%d%c[%2d,%3d] for track # %d,"
941 " adding energy (%f) to that hit (%f) -> %f",
942 detector, ring, sector, strip, track, edep, hit->Edep(),
943 hit->Edep() + edep));
944 hit->SetEdep(hit->Edep() + edep);
948 // If hit wasn't already registered, do so know.
949 hit = new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector,
950 strip, x, y, z, px, py, pz, edep, pdg, t,
956 //____________________________________________________________________
958 AliFMD::AddDigit(Int_t* digits, Int_t*)
960 // Add a digit to the Digit tree
964 // digits[0] [UShort_t] Detector #
965 // digits[1] [Char_t] Ring ID
966 // digits[2] [UShort_t] Sector #
967 // digits[3] [UShort_t] Strip #
968 // digits[4] [UShort_t] ADC Count
969 // digits[5] [Short_t] ADC Count, -1 if not used
970 // digits[6] [Short_t] ADC Count, -1 if not used
972 AddDigitByFields(UShort_t(digits[0]), // Detector #
973 Char_t(digits[1]), // Ring ID
974 UShort_t(digits[2]), // Sector #
975 UShort_t(digits[3]), // Strip #
976 UShort_t(digits[4]), // ADC Count1
977 Short_t(digits[5]), // ADC Count2
978 Short_t(digits[6])); // ADC Count3
981 //____________________________________________________________________
983 AliFMD::AddDigitByFields(UShort_t detector,
991 // add a real digit - as coming from data
995 // detector Detector # (1, 2, or 3)
996 // ring Ring ID ('I' or 'O')
997 // sector Sector # (For inner/outer rings: 0-19/0-39)
998 // strip Strip # (For inner/outer rings: 0-511/0-255)
999 // count1 ADC count (a 10-bit word)
1000 // count2 ADC count (a 10-bit word), or -1 if not used
1001 // count3 ADC count (a 10-bit word), or -1 if not used
1002 TClonesArray& a = *(DigitsArray());
1005 AliFMDDigit(detector, ring, sector, strip, count1, count2, count3);
1008 //____________________________________________________________________
1010 AliFMD::AddSDigit(Int_t* digits)
1012 // Add a digit to the SDigit tree
1016 // digits[0] [UShort_t] Detector #
1017 // digits[1] [Char_t] Ring ID
1018 // digits[2] [UShort_t] Sector #
1019 // digits[3] [UShort_t] Strip #
1020 // digits[4] [Float_t] Total energy deposited
1021 // digits[5] [UShort_t] ADC Count
1022 // digits[6] [Short_t] ADC Count, -1 if not used
1023 // digits[7] [Short_t] ADC Count, -1 if not used
1025 AddSDigitByFields(UShort_t(digits[0]), // Detector #
1026 Char_t(digits[1]), // Ring ID
1027 UShort_t(digits[2]), // Sector #
1028 UShort_t(digits[3]), // Strip #
1029 Float_t(digits[4]), // Edep
1030 UShort_t(digits[5]), // ADC Count1
1031 Short_t(digits[6]), // ADC Count2
1032 Short_t(digits[7])); // ADC Count3
1035 //____________________________________________________________________
1037 AliFMD::AddSDigitByFields(UShort_t detector,
1046 // add a summable digit
1050 // detector Detector # (1, 2, or 3)
1051 // ring Ring ID ('I' or 'O')
1052 // sector Sector # (For inner/outer rings: 0-19/0-39)
1053 // strip Strip # (For inner/outer rings: 0-511/0-255)
1054 // edep Total energy deposited
1055 // count1 ADC count (a 10-bit word)
1056 // count2 ADC count (a 10-bit word), or -1 if not used
1057 // count3 ADC count (a 10-bit word), or -1 if not used
1059 TClonesArray& a = *(SDigitsArray());
1061 new (a[fNsdigits++])
1062 AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3);
1065 //____________________________________________________________________
1067 AliFMD::ResetSDigits()
1070 // Reset number of digits and the digits array for this detector
1073 if (fSDigits) fSDigits->Clear();
1077 //____________________________________________________________________
1081 // Initialize hit array if not already, and return pointer to it.
1083 fHits = new TClonesArray("AliFMDHit", 1000);
1089 //____________________________________________________________________
1091 AliFMD::DigitsArray()
1093 // Initialize digit array if not already, and return pointer to it.
1095 fDigits = new TClonesArray("AliFMDDigit", 1000);
1101 //____________________________________________________________________
1103 AliFMD::SDigitsArray()
1105 // Initialize digit array if not already, and return pointer to it.
1107 fSDigits = new TClonesArray("AliFMDSDigit", 1000);
1113 //====================================================================
1117 //____________________________________________________________________
1119 AliFMD::Hits2Digits()
1121 // Create AliFMDDigit's from AliFMDHit's. This is done by making a
1122 // AliFMDDigitizer, and executing that code.
1124 Warning("Hits2Digits", "Try not to use this method.\n"
1125 "Instead, use AliSimulator");
1126 AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
1127 manager->SetInputStream(0, "galice.root");
1128 manager->SetOutputFile("H2Dfile");
1130 /* AliDigitizer* dig =*/ CreateDigitizer(manager);
1135 //____________________________________________________________________
1137 AliFMD::Hits2SDigits()
1139 // Create AliFMDSDigit's from AliFMDHit's. This is done by creating
1140 // an AliFMDSDigitizer object, and executing it.
1142 AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root");
1143 digitizer->Exec("");
1148 //____________________________________________________________________
1150 AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
1152 // Create a digitizer object
1153 AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager);
1157 //====================================================================
1159 // Raw data simulation
1161 //__________________________________________________________________
1163 AliFMD::Digits2Raw()
1165 // Turn digits into raw data.
1167 // This uses the class AliFMDRawWriter to do the job. Please refer
1168 // to that class for more information.
1169 AliFMDRawWriter writer(this);
1174 //====================================================================
1178 //__________________________________________________________________
1180 AliFMD::Browse(TBrowser* b)
1182 // Browse this object.
1184 AliDebug(30, "\tBrowsing the FMD");
1185 AliDetector::Browse(b);
1186 b->Add(AliFMDGeometry::Instance());
1189 //___________________________________________________________________