--- /dev/null
+semantic.cache
+html
+tgt_*
+
/* $Id$ */
- //////////////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity Detector based on Silicon plates //
-// This class contains the base procedures for the Forward Multiplicity //
-// detector //
-// Detector consists of 5 Si volumes covered pseudorapidity interval //
-// from 1.7 to 5.1. //
-// //
+//////////////////////////////////////////////////////////////////////////////
+//
+// Forward Multiplicity Detector based on Silicon wafers This class
+// contains the base procedures for the Forward Multiplicity detector
+// Detector consists of 5 Si volumes covered pseudorapidity interval
+// from 1.7 to 5.1.
+//
+// The actual code is done by various separate classes. Below is
+// diagram showing the relationship between the various FMD classes
+// that handles the geometry
+//
+//
+// +----------+ +----------+
+// | AliFMDv1 | | AliFMDv1 |
+// +----------+ +----------+
+// | |
+// +----+--------------+
+// |
+// | +------------+ 1 +---------------+
+// | +- | AliFMDRing |<>--| AliFMDPolygon |
+// V 2 | +------------+ +---------------+
+// +--------+<>--+ |
+// | AliFMD | ^
+// +--------+<>--+ V 1..2
+// 3 | +-------------------+
+// +-| AliFMDSubDetector |
+// +-------------------+
+// ^
+// |
+// +-------------+-------------+
+// | | |
+// +---------+ +---------+ +---------+
+// | AliFMD1 | | AliFMD2 | | AliFMD3 |
+// +---------+ +---------+ +---------+
+//
+//
+// * AliFMD
+// This defines the interface for the various parts of AliROOT that
+// uses the FMD, like AliFMDDigitizer, AliFMDReconstructor, and so
+// on.
+//
+// * AliFMDv1
+// This is a concrete implementation of the AliFMD interface.
+// It is the responsibility of this class to create the FMD
+// geometry, process hits in the FMD, and serve hits and digits to
+// the various clients.
+//
+// It uses the objects of class AliFMDSubDetector to do the various
+// stuff for FMD1, 2, and 3
+//
+// * AliFMDRing
+// This class contains all stuff needed to do with a ring. It's
+// used by the AliFMDSubDetector objects to instantise inner and
+// outer rings. The AliFMDRing objects are shared by the
+// AliFMDSubDetector objects, and owned by the AliFMDv1 object.
+//
+// * AliFMDPolygon
+// The code I lifted from TGeoPolygon to help with the geometry of
+// the modules, as well as to decide wether a hit is actually with
+// in the real module shape. The point is, that the shape of the
+// various ring modules are really polygons (much like the lid of a
+// coffin), but it's segmented at constant radius. That is very
+// hard to implement using GEANT 3.21 shapes, so instead the
+// modules are implemented as TUBS (tube sections), and in the step
+// procedure we do the test whether the track was inside the real
+// shape of the module.
+//
+// * AliFMD1, AliFMD2, and AliFMD3
+// These are specialisation of AliFMDSubDetector, that contains the
+// particularities of each of the sub-detector system. It is
+// envisioned that the classes should also define the support
+// volumes and material for each of the detectors.
+//
//Begin_Html
/*
-<img src="gif/AliFMDClass.gif">
-</pre>
-<br clear=left>
-<font size=+2 color=red>
-<p>The responsible person for this module is
-<a href="mailto:Alla.Maevskaia@cern.ch">Alla Maevskaia</a>.
-</font>
-<pre>
+ <img src="gif/AliFMDClass.gif">
+ </pre>
+ <br clear=left>
+ <p>
+ The responsible person for this module is
+ <a href="mailto:Alla.Maevskaia@cern.ch">Alla Maevskaia</a>.
+ </p>
+ <p>
+ Many modifications by <a href="mailto:cholm@nbi.dk">Christian
+ Holm Christensen</a>.
+ </p>
+ <pre>
*/
//End_Html
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-#define DEBUG
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+#ifndef ROOT_TGeomtry
+# include <TGeometry.h>
+#endif
+#ifndef ROOT_TNode
+# include <TNode.h>
+#endif
+#ifndef ROOT_TTUBE
+# include <TTUBE.h>
+#endif
+#ifndef ROOT_TTree
+# include <TTree.h>
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ROOT_TBrowser
+# include <TBrowser.h>
+#endif
+#ifndef ROOT_TMath
+# include <TMath.h>
+#endif
-#include <Riostream.h>
-#include <stdlib.h>
+#ifndef ALIRUNDIGITIZER_H
+# include "AliRunDigitizer.h"
+#endif
+#ifndef ALILOADER_H
+# include "AliLoader.h"
+#endif
+#ifndef ALIRUN_H
+# include "AliRun.h"
+#endif
+#ifndef ALIMC_H
+# include "AliMC.h"
+#endif
+#ifndef ALILog_H
+# include "AliLog.h"
+#endif
+#ifndef ALIMAGF_H
+# include "AliMagF.h"
+#endif
+#ifndef ALIFMD_H
+# include "AliFMD.h"
+#endif
+#ifndef ALIFMDDIGIG_H
+# include "AliFMDDigit.h"
+#endif
+#ifndef ALIFMDHIT_H
+# include "AliFMDHit.h"
+#endif
+#ifndef ALIFMDDIGITIZER_H
+# include "AliFMDDigitizer.h"
+#endif
+#ifndef ALIFMD1_H
+# include "AliFMD1.h"
+#endif
+#ifndef ALIFMD2_H
+# include "AliFMD2.h"
+#endif
+#ifndef ALIFMD3_H
+# include "AliFMD3.h"
+#endif
+#ifndef ALIALTROBUFFER_H
+# include "AliAltroBuffer.h"
+#endif
-#include <TClonesArray.h>
-#include <TFile.h>
-#include <TGeometry.h>
-#include <TNode.h>
-#include <TTUBE.h>
-#include <TTree.h>
-#include <TVirtualMC.h>
-
-#include "AliDetector.h"
-#include "AliFMDdigit.h"
-#include "AliFMDhit.h"
-#include "AliFMDv1.h"
-#include "AliLoader.h"
-#include "AliRun.h"
-#include "AliMC.h"
-#include "AliFMDDigitizer.h"
-
-ClassImp (AliFMD)
- //_____________________________________________________________________________
-AliFMD::AliFMD ():AliDetector ()
+//____________________________________________________________________
+ClassImp(AliFMD);
+
+//____________________________________________________________________
+AliFMD::AliFMD()
+ : fInner(0),
+ fOuter(0),
+ fFMD1(0),
+ fFMD2(0),
+ fFMD3(0)
{
//
// Default constructor for class AliFMD
//
- fIshunt = 0;
+ AliDebug(0, "Default CTOR");
fHits = 0;
fDigits = 0;
+ fSDigits = 0;
+ fNsdigits = 0;
+ fIshunt = 0;
}
-//_____________________________________________________________________________
-AliFMD::AliFMD (const char *name, const char *title):
-AliDetector (name, title)
+//____________________________________________________________________
+AliFMD::AliFMD(const char *name, const char *title, bool detailed)
+ : AliDetector (name, title),
+ fInner(0),
+ fOuter(0),
+ fFMD1(0),
+ fFMD2(0),
+ fFMD3(0)
{
//
// Standard constructor for Forward Multiplicity Detector
//
+ AliDebug(0, "Standard CTOR");
- //
// Initialise Hit array
- fHits = new TClonesArray ("AliFMDhit", 1000);
- // Digits for each Si disk
- fDigits = new TClonesArray ("AliFMDdigit", 1000);
- gAlice->GetMCApp()->AddHitList (fHits);
+ HitsArray();
+ gAlice->GetMCApp()->AddHitList(fHits);
+ // (S)Digits for the detectors disk
+ DigitsArray();
+ SDigitsArray();
+
+ // CHC: What is this?
fIshunt = 0;
- // fMerger = 0;
- SetMarkerColor (kRed);
+ SetMarkerColor(kRed);
+ SetLineColor(kYellow);
+ SetSiDensity();
+
+ // Create sub-volume managers
+ fInner = new AliFMDRing('I', detailed);
+ fOuter = new AliFMDRing('O', detailed);
+ fFMD1 = new AliFMD1();
+ fFMD2 = new AliFMD2();
+ fFMD3 = new AliFMD3();
+
+ // Specify parameters of sub-volume managers
+ fFMD1->SetInner(fInner);
+ fFMD1->SetOuter(0);
+
+ fFMD2->SetInner(fInner);
+ fFMD2->SetOuter(fOuter);
+
+ fFMD3->SetInner(fInner);
+ fFMD3->SetOuter(fOuter);
+
+ SetLegLength();
+ SetLegRadius();
+ SetLegOffset();
+ SetModuleSpacing();
+
+ fInner->SetLowR(4.3);
+ fInner->SetHighR(17.2);
+ fInner->SetWaferRadius(13.4/2);
+ fInner->SetTheta(36/2);
+ fInner->SetNStrips(512);
+ fInner->SetSiThickness(.03);
+ fInner->SetPrintboardThickness(.11);
+ fInner->SetBondingWidth(.5);
+
+ fOuter->SetLowR(15.6);
+ fOuter->SetHighR(28.0);
+ fOuter->SetWaferRadius(13.4/2);
+ fOuter->SetTheta(18/2);
+ fOuter->SetNStrips( 256);
+ fOuter->SetSiThickness(.03);
+ fOuter->SetPrintboardThickness(.1);
+ fOuter->SetBondingWidth(.5);
+
+
+ fFMD1->SetHoneycombThickness(1);
+ fFMD1->SetInnerZ(340.0);
+
+ fFMD2->SetHoneycombThickness(1);
+ fFMD2->SetInnerZ(83.4);
+ fFMD2->SetOuterZ(75.2);
+
+ fFMD3->SetHoneycombThickness(1);
+ fFMD3->SetInnerZ(-62.8);
+ fFMD3->SetOuterZ(-75.2);
}
-//-----------------------------------------------------------------------------
+//____________________________________________________________________
AliFMD::~AliFMD ()
{
- //destructor for base class AliFMD
- if (fHits)
- {
- fHits->Delete ();
- delete fHits;
- fHits = 0;
- }
- if (fDigits)
- {
- fDigits->Delete ();
- delete fDigits;
- fDigits = 0;
- }
+ // Destructor for base class AliFMD
+ if (fHits) {
+ fHits->Delete();
+ delete fHits;
+ fHits = 0;
+ }
+ if (fDigits) {
+ fDigits->Delete();
+ delete fDigits;
+ fDigits = 0;
+ }
+ if (fSDigits) {
+ fSDigits->Delete();
+ delete fSDigits;
+ fSDigits = 0;
+ }
+}
+
+//====================================================================
+//
+// GEometry ANd Traking
+//
+//____________________________________________________________________
+void
+AliFMD::CreateGeometry()
+{
+ //
+ // Create the geometry of Forward Multiplicity Detector version 0
+ //
+ // DebugGuard guard("AliFMD::CreateGeometry");
+ AliDebug(10, "Creating geometry");
+ fInner->Init();
+ fOuter->Init();
+
+ TString name;
+ Double_t par[3];
+
+ par[0] = fLegRadius - .1;
+ par[1] = fLegRadius;
+ par[2] = fLegLength / 2;
+ name = "SLEG";
+ fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
+
+ par[2] += fModuleSpacing / 2;
+ name = "LLEG";
+ fLongLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
+
+ fInner->SetupGeometry((*fIdtmed)[kAirId],
+ (*fIdtmed)[kSiId],
+ (*fIdtmed)[kPcbId],
+ fPrintboardRotationId,
+ fIdentityRotationId);
+ fOuter->SetupGeometry((*fIdtmed)[kAirId],
+ (*fIdtmed)[kSiId],
+ (*fIdtmed)[kPcbId],
+ fPrintboardRotationId,
+ fIdentityRotationId);
+
+ fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
+ fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
+ fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
+
+ fFMD1->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
+ fFMD2->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
+ fFMD3->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
+}
+
+//____________________________________________________________________
+void AliFMD::CreateMaterials()
+{
+ // Register various materials and tracking mediums with the
+ // backend.
+ //
+ // Currently defined materials and mediums are
+ //
+ // FMD Air Normal air
+ // FMD Si Active silicon of sensors
+ // FMD Carbon Normal carbon used in support, etc.
+ // FMD Kapton Carbon used in Honeycomb
+ // FMD PCB Printed circuit board material
+ // FMD Plastic Material for support legs
+ //
+ // Also defined are two rotation matricies.
+ //
+ // DebugGuard guard("AliFMD::CreateMaterials");
+ AliDebug(10, "Creating materials");
+ Int_t id;
+ Double_t a = 0;
+ Double_t z = 0;
+ Double_t density = 0;
+ Double_t radiationLength = 0;
+ Double_t absorbtionLength = 999;
+ Int_t fieldType = gAlice->Field()->Integ(); // Field type
+ Double_t maxField = gAlice->Field()->Max(); // Field max.
+ Double_t maxBending = 0; // Max Angle
+ Double_t maxStepSize = 0.001; // Max step size
+ Double_t maxEnergyLoss = 1; // Max Delta E
+ Double_t precision = 0.001; // Precision
+ Double_t minStepSize = 0.001; // Minimum step size
+
+ // Silicon
+ a = 28.0855;
+ z = 14.;
+ density = fSiDensity;
+ radiationLength = 9.36;
+ maxBending = 1;
+ maxStepSize = .001;
+ precision = .001;
+ minStepSize = .001;
+ id = kSiId;
+ AliMaterial(id, "FMD Si$", a, z, density, radiationLength, absorbtionLength);
+ AliMedium(kSiId, "FMD Si$",id,1,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+
+
+ // Carbon
+ a = 12.011;
+ z = 6.;
+ density = 2.265;
+ radiationLength = 18.8;
+ maxBending = 10;
+ maxStepSize = .01;
+ precision = .003;
+ minStepSize = .003;
+ id = kCarbonId;
+ AliMaterial(id, "FMD Carbon$", a, z, density, radiationLength,
+ absorbtionLength);
+ AliMedium(kCarbonId, "FMD Carbon$",id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+
+ // Silicon chip
+ {
+ Float_t as[] = { 12.0107, 14.0067, 15.9994,
+ 1.00794, 28.0855, 107.8682 };
+ Float_t zs[] = { 6., 7., 8.,
+ 1., 14., 47. };
+ Float_t ws[] = { 0.039730642, 0.001396798, 0.01169634,
+ 0.004367771, 0.844665, 0.09814344903 };
+ density = 2.36436;
+ maxBending = 10;
+ maxStepSize = .01;
+ precision = .003;
+ minStepSize = .003;
+ id = kSiChipId;
+ AliMixture(id, "FMD Si Chip$", as, zs, density, 6, ws);
+ AliMedium(kSiChipId, "FMD Si Chip$", id, 0, fieldType, maxField,
+ maxBending, maxStepSize, maxEnergyLoss, precision, minStepSize);
+ }
+
+
+ // Kaption
+ {
+ Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994};
+ Float_t zs[] = { 1., 6., 7., 8.};
+ Float_t ws[] = { 0.026362, 0.69113, 0.07327, 0.209235};
+ density = 1.42;
+ maxBending = 1;
+ maxStepSize = .001;
+ precision = .001;
+ minStepSize = .001;
+ id = kKaptionId;
+ AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
+ AliMedium(kKaptionId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+
+ // Air
+ {
+ Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 };
+ Float_t zs[] = { 6., 7., 8., 18. };
+ Float_t ws[] = { 0.000124, 0.755267, 0.231781, 0.012827 };
+ density = .00120479;
+ maxBending = 1;
+ maxStepSize = .001;
+ precision = .001;
+ minStepSize = .001;
+ id = kAirId;
+ AliMixture(id, "FMD Air$", as, zs, density, 4, ws);
+ AliMedium(kAirId, "FMD Air$", id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+
+ // PCB
+ {
+ Float_t zs[] = { 14., 20., 13., 12.,
+ 5., 22., 11., 19.,
+ 26., 9., 8., 6.,
+ 7., 1.};
+ Float_t as[] = { 28.0855, 40.078, 26.981538, 24.305,
+ 10.811, 47.867, 22.98977, 39.0983,
+ 55.845, 18.9984, 15.9994, 12.0107,
+ 14.0067, 1.00794};
+ Float_t ws[] = { 0.15144894, 0.08147477, 0.04128158, 0.00904554,
+ 0.01397570, 0.00287685, 0.00445114, 0.00498089,
+ 0.00209828, 0.00420000, 0.36043788, 0.27529426,
+ 0.01415852, 0.03427566};
+ density = 1.8;
+ maxBending = 1;
+ maxStepSize = .001;
+ precision = .001;
+ minStepSize = .001;
+ id = kPcbId;
+ AliMixture(id, "FMD PCB$", as, zs, density, 14, ws);
+ AliMedium(kPcbId, "FMD PCB$", id,1,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+
+ // Plastic
+ {
+ Float_t as[] = { 1.01, 12.01 };
+ Float_t zs[] = { 1., 6. };
+ Float_t ws[] = { 1., 1. };
+ density = 1.03;
+ maxBending = 10;
+ maxStepSize = .01;
+ precision = .003;
+ minStepSize = .003;
+ id = kPlasticId;
+ AliMixture(id, "FMD Plastic$", as, zs, density, -2, ws);
+ AliMedium(kPlasticId, "FMD Plastic$", id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+ AliMatrix(fPrintboardRotationId, 90, 90, 0, 90, 90, 0);
+ AliMatrix(fIdentityRotationId, 90, 0, 90, 90, 0, 0);
}
-//_____________________________________________________________________________
-void AliFMD::AddHit (Int_t track, Int_t * vol, Float_t * hits)
+//____________________________________________________________________
+void
+AliFMD::Init()
{
//
- // Add a hit to the list
+ // Initialis the FMD after it has been built
+ Int_t i;
+ //
+ if (fDebug) {
+ std::cout << "\n" << ClassName() << ": " << std::flush;
+ for (i = 0; i < 35; i++) std::cout << "*";
+ std::cout << " FMD_INIT ";
+ for (i = 0; i < 35; i++) std::cout << "*";
+ std::cout << "\n" << ClassName() << ": " << std::flush;
+ //
+ // Here the FMD initialisation code (if any!)
+ for (i = 0; i < 80; i++) std::cout << "*";
+ std::cout << std::endl;
+ }
+ //
//
- TClonesArray & lhits = *fHits;
- new (lhits[fNhits++]) AliFMDhit (fIshunt, track, vol, hits);
}
-//_____________________________________________________________________________
-void AliFMD::AddDigit (Int_t * digits)
+//====================================================================
+//
+// Graphics and event display
+//
+//____________________________________________________________________
+void
+AliFMD::BuildGeometry()
{
- // add a real digit - as coming from data
+ //
+ // Build simple ROOT TNode geometry for event display
+ //
+ // Build a simplified geometry of the FMD used for event display
+ //
+ AliDebug(10, "Creating a simplified geometry");
- if (fDigits == 0x0) fDigits = new TClonesArray ("AliFMDdigit", 1000);
- TClonesArray & ldigits = *fDigits;
- new (ldigits[fNdigits++]) AliFMDdigit (digits);
+ TNode* top = gAlice->GetGeometry()->GetNode("alice");
+
+ fFMD1->SimpleGeometry(fNodes, top, GetLineColor(), 0);
+ fFMD2->SimpleGeometry(fNodes, top, GetLineColor(), 0);
+ fFMD3->SimpleGeometry(fNodes, top, GetLineColor(), 0);
}
-//_____________________________________________________________________________
-void AliFMD::BuildGeometry ()
+//____________________________________________________________________
+void
+AliFMD::DrawDetector()
{
//
- // Build simple ROOT TNode geometry for event display
+ // Draw a shaded view of the Forward multiplicity detector version 0
//
- TNode *node, *top;
- const int kColorFMD = 5;
- //
- top = gAlice->GetGeometry ()->GetNode ("alice");
-
- // FMD define the different volumes
- new TRotMatrix ("rot901", "rot901", 90, 0, 90, 90, 180, 0);
-
- new TTUBE ("S_FMD0", "FMD volume 0", "void", 4.2, 17.2, 1.5);
- top->cd ();
- node = new TNode ("FMD0", "FMD0", "S_FMD0", 0, 0, -62.8, "");
- node->SetLineColor (kColorFMD);
- fNodes->Add (node);
-
- new TTUBE ("S_FMD1", "FMD volume 1", "void", 15.4, 28.4, 1.5);
- top->cd ();
- node = new TNode ("FMD1", "FMD1", "S_FMD1", 0, 0, -75.2, "");
- node->SetLineColor (kColorFMD);
- fNodes->Add (node);
-
- new TTUBE ("S_FMD2", "FMD volume 2", "void", 4.2, 17.2, 1.5);
- top->cd ();
- node = new TNode ("FMD2", "FMD2", "S_FMD2", 0, 0, 83.2, "");
- node->SetLineColor (kColorFMD);
- fNodes->Add (node);
-
- new TTUBE ("S_FMD3", "FMD volume 3", "void", 15.4, 28.4, 1.5);
- top->cd ();
- node = new TNode ("FMD3", "FMD3", "S_FMD3", 0, 0, 75.2, "");
- node->SetLineColor (kColorFMD);
- fNodes->Add (node);
-
- new TTUBE ("S_FMD4", "FMD volume 4", "void", 4.2, 17.2, 1.5);
- top->cd ();
- node = new TNode ("FMD4", "FMD4", "S_FMD4", 0, 0, 340, "");
- node->SetLineColor (kColorFMD);
- fNodes->Add (node);
+ // DebugGuard guard("AliFMD::DrawDetector");
+ AliDebug(10, "Draw detector");
+
+ //Set ALIC mother transparent
+ gMC->Gsatt("ALIC","SEEN",0);
+
+ //Set volumes visible
+ fFMD1->Gsatt();
+ fFMD2->Gsatt();
+ fFMD3->Gsatt();
+ fInner->Gsatt();
+ fOuter->Gsatt();
+
+ //
+ gMC->Gdopt("hide", "on");
+ gMC->Gdopt("shad", "on");
+ gMC->Gsatt("*", "fill", 7);
+ gMC->SetClipBox(".");
+ gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
+ gMC->DefaultRange();
+ gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055);
+ gMC->Gdhead(1111, "Forward Multiplicity Detector");
+ gMC->Gdman(16, 10, "MAN");
+ gMC->Gdopt("hide", "off");
}
-//_____________________________________________________________________________
-const Int_t AliFMD::DistanceToPrimitive (Int_t /*px*/, Int_t /*py*/)
+//____________________________________________________________________
+const Int_t
+AliFMD::DistanceToPrimitive(Int_t, Int_t)
{
//
// Calculate the distance from the mouse to the FMD on the screen
return 9999;
}
-//___________________________________________
-void AliFMD::ResetHits ()
+//====================================================================
+//
+// Hit and Digit managment
+//
+//____________________________________________________________________
+void
+AliFMD::MakeBranch(Option_t * option)
+{
+ // Create Tree branches for the FMD.
+ const Int_t kBufferSize = 16000;
+ TString branchname(GetName());
+ TString opt(option);
+
+ if (opt.Contains("H", TString::kIgnoreCase)) {
+ HitsArray();
+ AliDetector::MakeBranch(option);
+ }
+ if (opt.Contains("D", TString::kIgnoreCase)) {
+ DigitsArray();
+ MakeBranchInTree(fLoader->TreeD(), branchname.Data(),
+ &fDigits, kBufferSize, 0);
+ }
+ if (opt.Contains("S", TString::kIgnoreCase)) {
+ SDigitsArray();
+ MakeBranchInTree(fLoader->TreeS(), branchname.Data(),
+ &fSDigits, kBufferSize, 0);
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMD::SetTreeAddress()
+{
+ // Set branch address for the Hits and Digits Tree.
+
+ if (fLoader->TreeH()) HitsArray();
+ AliDetector::SetTreeAddress();
+
+ TTree *treeD = fLoader->TreeD();
+ if (treeD) {
+ DigitsArray();
+ TBranch* branch = treeD->GetBranch ("FMD");
+ if (branch) branch->SetAddress(&fDigits);
+ }
+
+ TTree *treeS = fLoader->TreeS();
+ if (treeS) {
+ SDigitsArray();
+ TBranch* branch = treeS->GetBranch ("FMD");
+ if (branch) branch->SetAddress(&fSDigits);
+ }
+}
+
+
+
+//____________________________________________________________________
+void
+AliFMD::SetHitsAddressBranch(TBranch *b)
{
- // Reset number of clusters and the cluster array for this detector
- AliDetector::ResetHits ();
+ b->SetAddress(&fHits);
}
-//____________________________________________
-void AliFMD::ResetDigits ()
+//____________________________________________________________________
+void
+AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
+{
+ // Add a hit to the hits tree
+ //
+ // The information of the two arrays are decoded as
+ //
+ // Parameters
+ // track Track #
+ // ivol[0] [UShort_t ] Detector #
+ // ivol[1] [Char_t ] Ring ID
+ // ivol[2] [UShort_t ] Sector #
+ // ivol[3] [UShort_t ] Strip #
+ // hits[0] [Float_t ] Track's X-coordinate at hit
+ // hits[1] [Float_t ] Track's Y-coordinate at hit
+ // hits[3] [Float_t ] Track's Z-coordinate at hit
+ // hits[4] [Float_t ] X-component of track's momentum
+ // hits[5] [Float_t ] Y-component of track's momentum
+ // hits[6] [Float_t ] Z-component of track's momentum
+ // hits[7] [Float_t ] Energy deposited by track
+ // hits[8] [Int_t ] Track's particle Id #
+ // hits[9] [Float_t ] Time when the track hit
+ AddHit(track,
+ UShort_t(vol[0]), // Detector #
+ Char_t(vol[1]), // Ring ID
+ UShort_t(vol[2]), // Sector #
+ UShort_t(vol[3]), // Strip #
+ hits[0], // X
+ hits[1], // Y
+ hits[2], // Z
+ hits[3], // Px
+ hits[4], // Py
+ hits[5], // Pz
+ hits[6], // Energy loss
+ Int_t(hits[7]), // PDG
+ hits[8]); // Time
+}
+
+//____________________________________________________________________
+void
+AliFMD::AddHit(Int_t track,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t x,
+ Float_t y,
+ Float_t z,
+ Float_t px,
+ Float_t py,
+ Float_t pz,
+ Float_t edep,
+ Int_t pdg,
+ Float_t t)
{
//
- // Reset number of digits and the digits array for this detector
- AliDetector::ResetDigits ();
+ // Add a hit to the list
//
+ // Parameters:
+ //
+ // track Track #
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // x Track's X-coordinate at hit
+ // y Track's Y-coordinate at hit
+ // z Track's Z-coordinate at hit
+ // px X-component of track's momentum
+ // py Y-component of track's momentum
+ // pz Z-component of track's momentum
+ // edep Energy deposited by track
+ // pdg Track's particle Id #
+ // t Time when the track hit
+ //
+ TClonesArray& a = *(HitsArray());
+ // Search through the list of already registered hits, and see if we
+ // find a hit with the same parameters. If we do, then don't create
+ // a new hit, but rather update the energy deposited in the hit.
+ // This is done, so that a FLUKA based simulation will get the
+ // number of hits right, not just the enerrgy deposition.
+ for (Int_t i = 0; i < fNhits; i++) {
+ if (!a.At(i)) continue;
+ AliFMDHit* hit = static_cast<AliFMDHit*>(a.At(i));
+ if (hit->Detector() == detector
+ && hit->Ring() == ring
+ && hit->Sector() == sector
+ && hit->Strip() == strip
+ && hit->Track() == track) {
+ hit->SetEdep(hit->Edep() + edep);
+ return;
+ }
+ }
+ // If hit wasn't already registered, do so know.
+ new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, strip,
+ x, y, z, px, py, pz, edep, pdg, t);
+ fNhits++;
}
-//-------------------------------------------------------------------------
-void AliFMD::Init ()
+//____________________________________________________________________
+void
+AliFMD::AddDigit(Int_t* digits)
{
+ // Add a digit to the Digit tree
+ //
+ // Paramters
//
- // Initialis the FMD after it has been built
- Int_t i;
+ // digits[0] [UShort_t] Detector #
+ // digits[1] [Char_t] Ring ID
+ // digits[2] [UShort_t] Sector #
+ // digits[3] [UShort_t] Strip #
+ // digits[4] [UShort_t] ADC Count
+ // digits[5] [Short_t] ADC Count, -1 if not used
+ // digits[6] [Short_t] ADC Count, -1 if not used
+ //
+ AddDigit(UShort_t(digits[0]), // Detector #
+ Char_t(digits[1]), // Ring ID
+ UShort_t(digits[2]), // Sector #
+ UShort_t(digits[3]), // Strip #
+ UShort_t(digits[4]), // ADC Count1
+ Short_t(digits[5]), // ADC Count2
+ Short_t(digits[6])); // ADC Count3
+}
+
+//____________________________________________________________________
+void
+AliFMD::AddDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3)
+{
+ // add a real digit - as coming from data
+ //
+ // Parameters
//
- if (fDebug)
- {
- printf ("\n%s: ", ClassName ());
- for (i = 0; i < 35; i++)
- printf ("*");
- printf (" FMD_INIT ");
- for (i = 0; i < 35; i++)
- printf ("*");
- printf ("\n%s: ", ClassName ());
- //
- // Here the FMD initialisation code (if any!)
- for (i = 0; i < 80; i++)
- printf ("*");
- printf ("\n");
- }
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // count1 ADC count (a 10-bit word)
+ // count2 ADC count (a 10-bit word), or -1 if not used
+ // count3 ADC count (a 10-bit word), or -1 if not used
+ TClonesArray& a = *(DigitsArray());
+
+ new (a[fNdigits++])
+ AliFMDDigit(detector, ring, sector, strip, count1, count2, count3);
+}
+
+//____________________________________________________________________
+void
+AliFMD::AddSDigit(Int_t* digits)
+{
+ // Add a digit to the SDigit tree
+ //
+ // Paramters
//
+ // digits[0] [UShort_t] Detector #
+ // digits[1] [Char_t] Ring ID
+ // digits[2] [UShort_t] Sector #
+ // digits[3] [UShort_t] Strip #
+ // digits[4] [Float_t] Total energy deposited
+ // digits[5] [UShort_t] ADC Count
+ // digits[6] [Short_t] ADC Count, -1 if not used
+ // digits[7] [Short_t] ADC Count, -1 if not used
+ //
+ AddSDigit(UShort_t(digits[0]), // Detector #
+ Char_t(digits[1]), // Ring ID
+ UShort_t(digits[2]), // Sector #
+ UShort_t(digits[3]), // Strip #
+ Float_t(digits[4]), // Edep
+ UShort_t(digits[5]), // ADC Count1
+ Short_t(digits[6]), // ADC Count2
+ Short_t(digits[7])); // ADC Count3
+}
+
+//____________________________________________________________________
+void
+AliFMD::AddSDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3)
+{
+ // add a summable digit
+ //
+ // Parameters
//
-
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // edep Total energy deposited
+ // count1 ADC count (a 10-bit word)
+ // count2 ADC count (a 10-bit word), or -1 if not used
+ // count3 ADC count (a 10-bit word), or -1 if not used
+ TClonesArray& a = *(SDigitsArray());
+
+ new (a[fNsdigits++])
+ AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3);
}
-//---------------------------------------------------------------------
-void AliFMD::MakeBranch (Option_t * option)
+
+//____________________________________________________________________
+void
+AliFMD::ResetSDigits()
{
- // Create Tree branches for the FMD.
- char branchname[10];
- const Int_t kBufferSize = 16000;
- sprintf (branchname, "%s", GetName ());
+ //
+ // Reset number of digits and the digits array for this detector
+ //
+ fNsdigits = 0;
+ if (fSDigits) fSDigits->Clear();
+}
+
+
+//____________________________________________________________________
+TClonesArray*
+AliFMD::HitsArray()
+{
+ // Initialize hit array if not already, and return pointer to it.
+ if (!fHits) {
+ fHits = new TClonesArray("AliFMDHit", 1000);
+ fNhits = 0;
+ }
+ return fHits;
+}
+
+//____________________________________________________________________
+TClonesArray*
+AliFMD::DigitsArray()
+{
+ // Initialize digit array if not already, and return pointer to it.
+ if (!fDigits) {
+ fDigits = new TClonesArray("AliFMDDigit", 1000);
+ fNdigits = 0;
+ }
+ return fDigits;
+}
+
+//____________________________________________________________________
+TClonesArray*
+AliFMD::SDigitsArray()
+{
+ // Initialize digit array if not already, and return pointer to it.
+ if (!fSDigits) {
+ fSDigits = new TClonesArray("AliFMDSDigit", 1000);
+ fNsdigits = 0;
+ }
+ return fSDigits;
+}
+
+//====================================================================
+//
+// Digitization
+//
+//____________________________________________________________________
+void
+AliFMD::Hits2Digits()
+{
+ AliRunDigitizer* manager = new AliRunDigitizer(1, 1);
+ manager->SetInputStream(0, "galice.root");
+ manager->SetOutputFile("H2Dfile");
- const char *cH = strstr(option,"H");
- const char *cD = strstr(option,"D");
+ /* AliDigitizer* dig =*/ CreateDigitizer(manager);
+ manager->Exec("");
+}
+
+//____________________________________________________________________
+void
+AliFMD::Hits2SDigits()
+{
+ AliDigitizer* sdig = new AliFMDSDigitizer("galice.root");
+ sdig->Exec("");
+}
+
- if (cH && (fHits == 0x0)) fHits = new TClonesArray ("AliFMDhit", 1000);
+//____________________________________________________________________
+AliDigitizer*
+AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
+{
+ // Create a digitizer object
+ return new AliFMDDigitizer(manager);
+}
- AliDetector::MakeBranch (option);
+//====================================================================
+//
+// Raw data simulation
+//
+//__________________________________________________________________
+void
+AliFMD::Digits2Raw()
+{
+ AliFMD* fmd = static_cast<AliFMD*>(gAlice->GetDetector(GetName()));
+ fLoader->LoadDigits();
+ TTree* digitTree = fLoader->TreeD();
+ if (!digitTree) {
+ Error("Digits2Raw", "no digit tree");
+ return;
+ }
- if (cD){
- if (fDigits == 0x0) fDigits = new TClonesArray ("AliFMDdigit", 1000);
- MakeBranchInTree(fLoader->TreeD(), branchname,&fDigits, kBufferSize, 0);
+ TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000);
+ fmd->SetTreeAddress();
+ TBranch* digitBranch = digitTree->GetBranch(GetName());
+ if (!digitBranch) {
+ Error("Digits2Raw", "no branch for %s", GetName());
+ return;
}
+ digitBranch->SetAddress(&digits);
+
+ Int_t nEvents = digitTree->GetEntries();
+ for (Int_t event = 0; event < nEvents; event++) {
+ fmd->ResetDigits();
+ digitTree->GetEvent(event);
+
+ Int_t nDigits = digits->GetEntries();
+ if (nDigits < 1) continue;
-}
-//_____________________________________________________________________________
-void AliFMD::SetTreeAddress ()
-{
- // Set branch address for the Hits and Digits Tree.
+ UShort_t prevDetector = 0;
+ Char_t prevRing = '\0';
+ UShort_t prevSector = 0;
+ // UShort_t prevStrip = 0;
- if (fLoader->TreeH() && (fHits == 0x0))
- fHits = new TClonesArray ("AliFMDhit", 1000);
+ // The first seen strip number for a channel
+ UShort_t startStrip = 0;
+
+ // Which channel number in the ALTRO channel we're at
+ UShort_t offset = 0;
- AliDetector::SetTreeAddress ();
+ // How many times the ALTRO Samples one VA1_ALICE channel
+ Int_t sampleRate = 1;
- TBranch *branch;
- TTree *treeD = fLoader->TreeD();
+ // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel
+ // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate'
+ TArrayI channel(128 * sampleRate);
+
+ // The Altro buffer
+ AliAltroBuffer* altro = 0;
+
+ // Loop over the digits in the event. Note, that we assume the
+ // the digits are in order in the branch. If they were not, we'd
+ // have to cache all channels before we could write the data to
+ // the ALTRO buffer, or we'd have to set up a map of the digits.
+ for (Int_t i = 0; i < nDigits; i++) {
+ // Get the digit
+ AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
+
+ UShort_t det = digit->Detector();
+ Char_t ring = digit->Ring();
+ UShort_t sector = digit->Sector();
+ UShort_t strip = digit->Strip();
+ if (det != prevDetector) {
+ AliDebug(10, Form("FMD: New DDL, was %d, now %d",
+ kBaseDDL + prevDetector - 1,
+ kBaseDDL + det - 1));
+ // If an altro exists, delete the object, flushing the data to
+ // disk, and closing the file.
+ if (altro) {
+ // When the first argument is false, we write the real
+ // header.
+ AliDebug(10, Form("New altro: Write channel at %d Strip: %d "
+ "Sector: %d Ring: %d",
+ i, startStrip, prevSector, prevRing));
+ // TPC to FMD translations
+ //
+ // TPC FMD
+ // ----------+-----------
+ // pad | strip
+ // row | sector
+ // sector | ring
+ //
+ altro->WriteChannel(Int_t(startStrip),
+ Int_t(prevSector),
+ Int_t((prevRing == 'I' ? 0 : 1)),
+ channel.fN, channel.fArray, 0);
+ altro->Flush();
+ altro->WriteDataHeader(kFALSE, kFALSE);
+ delete altro;
+ altro = 0;
+ }
+
+ prevDetector = det;
+ // Need to open a new DDL!
+ Int_t ddlId = kBaseDDL + det - 1;
+ TString filename(Form("%s_%d.ddl", GetName(), ddlId));
+
+ AliDebug(10, Form("New altro buffer with DDL file %s",
+ filename.Data()));
+ AliDebug(10, Form("New altro at %d", i));
+ // Create a new altro buffer - a `1' as the second argument
+ // means `write mode'
+ altro = new AliAltroBuffer(filename.Data(), 1);
+
+ // Write a dummy (first argument is true) header to the DDL
+ // file - later on, when we close the file, we write the real
+ // header
+ altro->WriteDataHeader(kTRUE, kFALSE);
+
+ // Figure out the sample rate
+ if (digit->Count2() > 0) sampleRate = 2;
+ if (digit->Count3() > 0) sampleRate = 3;
+
+ channel.Set(128 * sampleRate);
+ offset = 0;
+ prevRing = ring;
+ prevSector = sector;
+ startStrip = strip;
+ }
+ else if (offset == 128
+ || digit->Ring() != prevRing
+ || digit->Sector() != prevSector) {
+ // Force a new Altro channel
+ AliDebug(10, Form("Flushing channel to disk because %s",
+ (offset == 128 ? "channel is full" :
+ (ring != prevRing ? "new ring up" :
+ "new sector up"))));
+ AliDebug(10, Form("New Channel: Write channel at %d Strip: %d "
+ "Sector: %d Ring: %d",
+ i, startStrip, prevSector, prevRing));
+ altro->WriteChannel(Int_t(startStrip),
+ Int_t(prevSector),
+ Int_t((prevRing == 'I' ? 0 : 1)),
+ channel.fN, channel.fArray, 0);
+ // Reset and update channel variables
+ channel.Reset(0);
+ offset = 0;
+ startStrip = strip;
+ prevRing = ring;
+ prevSector = sector;
+ }
- if (treeD)
- {
- if (fDigits == 0x0) fDigits = new TClonesArray ("AliFMDdigit", 1000);
- branch = treeD->GetBranch ("FMD");
- if (branch)
- branch->SetAddress (&fDigits);
+ // Store the counts of the ADC in the channel buffer
+ channel[offset * sampleRate] = digit->Count1();
+ if (sampleRate > 1)
+ channel[offset * sampleRate + 1] = digit->Count2();
+ if (sampleRate > 2)
+ channel[offset * sampleRate + 2] = digit->Count3();
+ offset++;
}
+ // Finally, we need to close the final ALTRO buffer if it wasn't
+ // already
+ if (altro) {
+ altro->Flush();
+ altro->WriteDataHeader(kFALSE, kFALSE);
+ delete altro;
+ }
+ }
+ fLoader->UnloadDigits();
}
+//==================================================================
+//
+// Various setter functions for the common paramters
+//
+//__________________________________________________________________
+void
+AliFMD::SetLegLength(Double_t length)
+{
+ // Set lenght of plastic legs that hold the hybrid (print board and
+ // silicon sensor) onto the honeycomp support
+ //
+ // DebugGuard guard("AliFMD::SetLegLength");
+ AliDebug(10, "AliFMD::SetLegLength");
+ fLegLength = length;
+ fInner->SetLegLength(fLegLength);
+ fOuter->SetLegLength(fLegLength);
+}
-//-----------------------------------------------------------------------
+//__________________________________________________________________
+void
+AliFMD::SetLegOffset(Double_t offset)
+{
+ // Set offset from edge of hybrid to plastic legs that hold the
+ // hybrid (print board and silicon sensor) onto the honeycomp
+ // support
+ //
+ // DebugGuard guard("AliFMD::SetLegOffset");
+ AliDebug(10, "AliFMD::SetLegOffset");
+ fInner->SetLegOffset(offset);
+ fOuter->SetLegOffset(offset);
+}
-void AliFMD::MakeBranchInTreeD(TTree *treeD, const char *file)
+//__________________________________________________________________
+void
+AliFMD::SetLegRadius(Double_t radius)
{
- //
- // Create TreeD branches for the FMD
- //
- const Int_t kBufferSize = 4000;
- char branchname[20];
- sprintf(branchname,"%s",GetName());
- if(treeD)
- {
- MakeBranchInTree(treeD, branchname,&fDigits, kBufferSize, file);
- }
+ // Set the diameter of the plastic legs that hold the hybrid (print
+ // board and silicon sensor) onto the honeycomp support
+ //
+ // DebugGuard guard("AliFMD::SetLegRadius");
+ AliDebug(10, "AliFMD::SetLegRadius");
+ fLegRadius = radius;
+ fInner->SetLegRadius(fLegRadius);
+ fOuter->SetLegRadius(fLegRadius);
}
-//____________________________________________________________________________
-AliDigitizer* AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
+//__________________________________________________________________
+void
+AliFMD::SetModuleSpacing(Double_t spacing)
{
- return new AliFMDDigitizer(manager);
+ // Set the distance between the front and back sensor modules
+ // (module staggering).
+ //
+ // DebugGuard guard("AliFMD::SetModuleSpacing");
+ AliDebug(10, "AliFMD::SetModuleSpacing");
+ fModuleSpacing = spacing;
+ fInner->SetModuleSpacing(fModuleSpacing);
+ fOuter->SetModuleSpacing(fModuleSpacing);
+}
+
+//====================================================================
+//
+// Utility
+//
+//__________________________________________________________________
+void
+AliFMD::Browse(TBrowser* b)
+{
+ AliDebug(10, "AliFMD::Browse");
+ AliDetector::Browse(b);
+ if (fInner) b->Add(fInner, "Inner Ring");
+ if (fOuter) b->Add(fOuter, "Outer Ring");
+ if (fFMD1) b->Add(fFMD1, "FMD1 SubDetector");
+ if (fFMD2) b->Add(fFMD2, "FMD2 SubDetector");
+ if (fFMD3) b->Add(fFMD3, "FMD3 SubDetector");
+}
+
+
+//********************************************************************
+//
+// AliFMDv0
+//
+//__________________________________________________________________
+
+ClassImp(AliFMDv0);
+
+//********************************************************************
+//
+// AliFMDv1
+//
+//__________________________________________________________________
+
+ClassImp(AliFMDv1);
+
+
+//_//____________________________________________________________________
+void
+AliFMDv1::StepManager()
+{
+ //
+ // Called for every step in the Forward Multiplicity Detector
+ //
+ // The procedure is as follows:
+ //
+ // - IF NOT track is alive THEN RETURN ENDIF
+ // - IF NOT particle is charged THEN RETURN ENDIF
+ // - IF NOT volume name is "STRI" or "STRO" THEN RETURN ENDIF
+ // - Get strip number (volume copy # minus 1)
+ // - Get phi division number (mother volume copy #)
+ // - Get module number (grand-mother volume copy #)
+ // - section # = 2 * module # + phi division # - 1
+ // - Get ring Id from volume name
+ // - Get detector # from grand-grand-grand-mother volume name
+ // - Get pointer to sub-detector object.
+ // - Get track position
+ // - IF track is entering volume AND track is inside real shape THEN
+ // - Reset energy deposited
+ // - Get track momentum
+ // - Get particle ID #
+ /// - ENDIF
+ // - IF track is inside volume AND inside real shape THEN
+ /// - Update energy deposited
+ // - ENDIF
+ // - IF track is inside real shape AND (track is leaving volume,
+ // or it died, or it is stopped THEN
+ // - Create a hit
+ // - ENDIF
+ //
+ //
+ // DebugGuard guard("AliFMDv1::StepManager");
+ AliDebug(10, "AliFMDv1::StepManager");
+ // return;
+
+ // If the track is gone, return
+ if (!gMC->IsTrackAlive()) return;
+
+ // Only process charged particles
+ if(TMath::Abs(gMC->TrackCharge()) <= 0) return;
+
+ // Only do stuff is the track is in one of the strips.
+ TString vol(gMC->CurrentVolName());
+ if (!vol.Contains("STR")) return;
+
+
+ // Get the strip number. Note, that GEANT numbers divisions from 1,
+ // so we subtract one
+ Int_t strip;
+ gMC->CurrentVolID(strip);
+ strip--;
+
+ // Get the phi division of the module
+ Int_t phiDiv; // * The phi division number (1 or 2)
+ gMC->CurrentVolOffID(1, phiDiv); // in the module
+
+ // Active volume number - not used.
+ // Int_t active;
+ // gMC->CurrentVolOffID(2, active);
+
+ // Get the module number in the ring.
+ Int_t module;
+ gMC->CurrentVolOffID(3, module);
+
+ // Ring copy number - the same as the detector number - not used
+ // Int_t ringCopy; // * Ring copy number
+ // gMC->CurrentVolOffID(4, ringCopy); // Same as detector number
+
+ // Get the detector number from the path name
+ Int_t detector = Int_t((gMC->CurrentVolOffName(5)[3]) - 48);
+
+ // The sector number, calculated from module and phi division #
+ Int_t sector = 2 * module + phiDiv - 1;
+
+ // The ring ID is encoded in the volume name
+ Char_t ring = vol[3];
+
+ // Get a pointer to the sub detector structure
+ AliFMDSubDetector* det = 0;
+ switch (detector) {
+ case 1: det = fFMD1; break;
+ case 2: det = fFMD2; break;
+ case 3: det = fFMD3; break;
+ }
+ if (!det) return;
+
+ // Get the current track position
+ TLorentzVector v;
+ gMC->TrackPosition(v);
+ // Check that the track is actually within the active area
+ Bool_t isWithin = det->CheckHit(ring, module, v.X(), v.Y());
+ Bool_t entering = gMC->IsTrackEntering() && isWithin;
+ Bool_t inside = gMC->IsTrackInside() && isWithin;
+ Bool_t out = (gMC->IsTrackExiting()
+ || gMC->IsTrackDisappeared()
+ || gMC->IsTrackStop()
+ || !isWithin);
+// Reset the energy deposition for this track, and update some of
+ // our parameters.
+ if (entering) {
+ fCurrentDeltaE = 0;
+
+ // Get production vertex and momentum of the track
+ fCurrentV = v;
+ gMC->TrackMomentum(fCurrentP);
+ fCurrentPdg = gMC->IdFromPDG(gMC->TrackPid());
+
+ // if (fAnalyser)
+ // fAnalyser->Update(detector, ring, isWithin, v.X(), v.Y());
+ }
+
+ // If the track is inside, then update the energy deposition
+ if (inside && fCurrentDeltaE >= 0)
+ fCurrentDeltaE += 1000 * gMC->Edep();
+
+ // The track exits the volume, or it disappeared in the volume, or
+ // the track is stopped because it no longer fulfills the cuts
+ // defined, then we create a hit.
+ if (out && fCurrentDeltaE >= 0) {
+ fCurrentDeltaE += 1000 * gMC->Edep();
+
+ AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),
+ detector, ring, sector, strip,
+ fCurrentV.X(), fCurrentV.Y(), fCurrentV.Z(),
+ fCurrentP.X(), fCurrentP.Y(), fCurrentP.Z(),
+ fCurrentDeltaE, fCurrentPdg, fCurrentV.T());
+ fCurrentDeltaE = -1;
+ }
}
+//___________________________________________________________________
+//
+// EOF
+//
+// -*- mode: c++ -*-
#ifndef ALIFMD_H
#define ALIFMD_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice
+ */
////////////////////////////////////////////////
// Manager and hits classes for set:Si-FMD //
////////////////////////////////////////////////
-
-#include <AliDetector.h>
-#include <TBranch.h>
-#include <AliLoader.h>
-class TClonesArray;
- class AliFMD : public AliDetector {
-
+#ifndef ALIDETECTOR_H
+# include <AliDetector.h>
+#endif
+#ifndef ALIFMDSUBDETECTOR_H
+# include "AliFMDSubDetector.h"
+#endif
+#ifndef ALIFMDRING_H
+# include "AliFMDRing.h"
+#endif
+#ifndef ROOT_TBranch
+# include <TBranch.h>
+#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+
+//____________________________________________________________________
+class AliFMD : public AliDetector
+{
public:
AliFMD();
- AliFMD(const char *name, const char *title);
- AliFMD(const AliFMD& FMD):AliDetector(FMD) {;} //copy ctor
- virtual ~AliFMD();
- AliFMD& operator=(const AliFMD&) {return *this;}
- virtual void AddHit(Int_t track, Int_t * vol, Float_t * hits);
- virtual void AddDigit(Int_t* digits);
- virtual void BuildGeometry();
- virtual void CreateGeometry() {}
- virtual void CreateMaterials()=0;
- virtual const Int_t DistanceToPrimitive(Int_t px, Int_t py);
- virtual Int_t IsVersion() const =0;
+ AliFMD(const char *name, const char *title, bool detailed);
+ AliFMD(const AliFMD& FMD) : AliDetector(FMD) {} //copy ctor
+ virtual ~AliFMD();
+ AliFMD& operator=(const AliFMD&) {return *this;}
+
+ // GEometry ANd Tracking (GEANT :-)
+ virtual void CreateGeometry();
+ virtual void CreateMaterials();
virtual void Init();
- virtual void MakeBranch(Option_t *opt=" ");
- virtual void MakeBranchInTreeD(TTree *treeD, const char *file=0);
- virtual void SetTreeAddress();
- virtual void ResetHits();
- virtual void ResetDigits();
- virtual void DrawDetector()=0;
- virtual void StepManager() {}
-
- void SetEventNumber(Int_t i) {fEvNrSig = i;}
+ virtual void StepManager() = 0;
+ AliFMDSubDetector* GetFMD1() const { return fFMD1; }
+ AliFMDSubDetector* GetFMD2() const { return fFMD2; }
+ AliFMDSubDetector* GetFMD3() const { return fFMD3; }
+ AliFMDRing* GetInner() const { return fInner; }
+ AliFMDRing* GetOuter() const { return fOuter; }
+ // Graphics and event display
+ virtual void BuildGeometry();
+ virtual void DrawDetector();
+ virtual const Int_t DistanceToPrimitive(Int_t px, Int_t py);
-
- // Digitisation
- virtual const void SetHitsAddressBranch(TBranch *b){b->SetAddress(&fHits);}
+ // Hit and digit management
+ virtual void MakeBranch(Option_t *opt=" ");
+ virtual void SetHitsAddressBranch(TBranch *b);
+ virtual void SetTreeAddress();
+ virtual TClonesArray* SDigits() { return fSDigits; }
+ virtual void ResetSDigits();
+ virtual void AddHit(Int_t track, Int_t *vol, Float_t *hits);
+ virtual void AddHit(Int_t track,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t x=0,
+ Float_t y=0,
+ Float_t z=0,
+ Float_t px=0,
+ Float_t py=0,
+ Float_t pz=0,
+ Float_t edep=0,
+ Int_t pdg=0,
+ Float_t t=0);
+ virtual void AddDigit(Int_t *digits);
+ virtual void AddDigit(UShort_t detector=0,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ UShort_t count1=0,
+ Short_t count2=-1,
+ Short_t count3=-1);
+ virtual void AddSDigit(Int_t *digits);
+ virtual void AddSDigit(UShort_t detector=0,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ Float_t edep=0,
+ UShort_t count1=0,
+ Short_t count2=-1,
+ Short_t count3=-1);
+
+ // Digitisation
virtual AliDigitizer* CreateDigitizer(AliRunDigitizer* manager) const;
+ virtual void Hits2Digits();
+ virtual void Hits2SDigits();
+
+ // Raw data
+ virtual void Digits2Raw();
+
+ // Set various parameters
+ void SetLegLength(Double_t length=1);
+ void SetLegRadius(Double_t radius=.5);
+ void SetLegOffset(Double_t offset=.5);
+ void SetModuleSpacing(Double_t spacing=1);
+
+ // Get various parameters
+ Int_t GetSiId() const { return (*fIdtmed)[kSiId]; }
+ Int_t GetAirId() const { return (*fIdtmed)[kAirId]; }
+ Int_t GetPlasticId() const { return (*fIdtmed)[kPlasticId]; }
+ Int_t GetPcbId() const { return (*fIdtmed)[kPcbId]; }
+ Int_t GetKaptionId() const { return (*fIdtmed)[kKaptionId]; }
+ Int_t GetCarbonId() const { return (*fIdtmed)[kCarbonId]; }
+ Int_t GetPrintboardRotationId() const { return fPrintboardRotationId; }
+ Int_t GetShortLegId() const { return fShortLegId; }
+ Int_t GetLongLegId() const { return fLongLegId; }
+ Double_t GetLegLength() const { return fLegLength; }
+ Double_t GetLegRadius() const { return fLegRadius; }
+ Double_t GetModuleSpacing() const { return fModuleSpacing; }
- protected:
-//Granularity
- Int_t fRingsSi1; // Number of rings
- Int_t fSectorsSi1; // Number of sectors
- Int_t fRingsSi2; // Number of rings
- Int_t fSectorsSi2; // Number of sectors
+ // Utility
+ void Browse(TBrowser* b);
+ Float_t GetSiDensity() const { return fSiDensity; }
+ enum {
+ kBaseDDL = 0x1000 // DDL offset for the FMD
+ };
+protected:
+ enum {
+ kSiId, // ID of Si medium
+ kAirId, // ID of Air medium
+ kPlasticId, // ID of Plastic medium
+ kPcbId, // ID of PCB medium
+ kSiChipId, // ID of Si Chip medium
+ kKaptionId, // ID of Kaption medium
+ kCarbonId // ID of Carbon medium
+ };
- Int_t fNevents ; // Number of events to digitize
- Int_t fEvNrSig; // signal event number
+ void SetSiDensity(Float_t r=2.33) { fSiDensity = r; }
+ TClonesArray* HitsArray();
+ TClonesArray* DigitsArray();
+ TClonesArray* SDigitsArray();
+
+ AliFMDRing* fInner; // Inner ring structure
+ AliFMDRing* fOuter; // Outer ring structure
+ AliFMDSubDetector* fFMD1; // FMD1 structure
+ AliFMDSubDetector* fFMD2; // FMD2 structure
+ AliFMDSubDetector* fFMD3; // FMD3 structure
- ClassDef(AliFMD,7) //Class for the FMD detector
+ TClonesArray* fSDigits;
+ Int_t fNsdigits;
+
+ Float_t fSiDensity; // Density of Silicon
+ Int_t fPrintboardRotationId; // ID of Rotation of print bard
+ Int_t fIdentityRotationId; // ID of identity matrix
+ Int_t fShortLegId; // ID short leg volume
+ Int_t fLongLegId; // ID long leg volume
+ Double_t fLegLength; // Leg length
+ Double_t fLegRadius; // Leg radius
+ Double_t fModuleSpacing; // Staggering offset
+
+ ClassDef(AliFMD,8) // Base class FMD entry point
};
-#endif // AliFMD_H
+//____________________________________________________________________
+class AliFMDv0 : public AliFMD
+{
+public:
+ AliFMDv0() {}
+ AliFMDv0(const char *name, const char *title="Coarse geometry")
+ : AliFMD(name, title, false)
+ {}
+ virtual ~AliFMDv0()
+ {}
+
+ // Required member functions
+ virtual Int_t IsVersion() const {return 0;}
+ virtual void StepManager() {}
+
+ ClassDef(AliFMDv0,1) // Coarse FMD geometry
+};
+
+//____________________________________________________________________
+#ifndef ROOT_TLorentzVector
+# include <TLorentzVector.h>
+#endif
+
+class AliFMDv1 : public AliFMD
+{
+public:
+ AliFMDv1() {}
+ AliFMDv1(const char *name, const char *title="Detailed geometry")
+ : AliFMD(name, title, true)
+ {}
+ virtual ~AliFMDv1() {}
+
+ // Required member functions
+ virtual Int_t IsVersion() const {return 1;}
+ virtual void StepManager();
+protected:
+ Double_t fCurrentDeltaE; // The current accumelated energy loss
+ TLorentzVector fCurrentV; // Current production vertex
+ TLorentzVector fCurrentP; // Current momentum vector
+ Int_t fCurrentPdg; // Current PDG code
+
+ ClassDef(AliFMDv1,3) // Detailed FMD geometry
+};
+#endif
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Concrete implementation of AliFMDSubDetector
+//
+// This implements the geometry for FMD1
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMD1_H
+# include "AliFMD1.h"
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+
+
+//____________________________________________________________________
+ClassImp(AliFMD1);
+
+//____________________________________________________________________
+AliFMD1::AliFMD1()
+ : AliFMDSubDetector(1)
+{}
+
+//____________________________________________________________________
+AliFMD1::~AliFMD1()
+{}
+
+//____________________________________________________________________
+void
+AliFMD1::SetupGeometry(Int_t airId, Int_t kaptionId)
+{
+ fInnerHoneyLowR = fInner->GetLowR() + 1;
+ fInnerHoneyHighR = fInner->GetHighR() + 1;
+ fOuterHoneyLowR = 0;
+ fOuterHoneyHighR = 0;
+
+ Double_t par[3];
+ par[0] = fInner->GetLowR();
+ par[1] = fInnerHoneyHighR;
+ par[2] = fDz = (fInner->GetLegLength()
+ + fInner->GetSiThickness()
+ + fInner->GetPrintboardThickness()
+ + fInner->GetModuleSpacing()
+ + fHoneycombThickness) / 2;
+ fVolumeId = gMC->Gsvolu("FMD1", "TUBE", airId, par, 3);
+
+ // Rotate the full sub-detector
+ gMC->Matrix(fRotationId, 270, 180, 90, 90, 180, 0);
+
+ AliFMDSubDetector::SetupGeometry(airId, kaptionId);
+}
+
+//____________________________________________________________________
+void
+AliFMD1::Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z)
+{
+ // The Z passed in isn't used.
+ z = fInnerZ + fDz;
+ gMC->Gspos("FMD1", 1, mother, 0, 0, z, fRotationId);
+
+ AliFMDSubDetector::Geometry("FMD1", pbRotId, idRotId, z);
+}
+
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: C++ -*-
+//
+// $Id$
+//
+#ifndef ALIFMD1_H
+#define ALIFMD1_H
+
+#ifndef ALIFMDSUBDETECTOR_H
+# include "AliFMDSubDetector.h"
+#endif
+
+class AliFMD1 : public AliFMDSubDetector
+{
+private:
+ Int_t fVolumeId;
+ Double_t fDz;
+public:
+ AliFMD1();
+ virtual ~AliFMD1();
+ virtual void SetupGeometry(Int_t airId, Int_t kaptionId);
+ virtual void Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z=0);
+ ClassDef(AliFMD1,1); // Geometry of FMD1
+};
+
+#endif
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Concrete implementation of AliFMDSubDetector
+//
+// This implements the geometry for FMD2
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMD2_H
+# include "AliFMD2.h"
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMD2);
+
+//____________________________________________________________________
+AliFMD2::AliFMD2()
+ : AliFMDSubDetector(2)
+{}
+
+//____________________________________________________________________
+AliFMD2::~AliFMD2()
+{}
+
+//____________________________________________________________________
+void
+AliFMD2::SetupGeometry(Int_t airId, Int_t kaptionId)
+{
+ fInnerHoneyLowR = fInner->GetLowR() + 1;
+ fInnerHoneyHighR = fInner->GetHighR() + 1;
+ fOuterHoneyLowR = fOuter->GetLowR() + 1;
+ fOuterHoneyHighR = fOuter->GetHighR() + 1;
+
+ Double_t par[3];
+ par[0] = fInner->GetLowR();
+ par[1] = fOuterHoneyHighR;
+ par[2] = fDz = (TMath::Abs(fInnerZ - fOuterZ)
+ + fInner->GetSiThickness()
+ + fInner->GetPrintboardThickness()
+ + fInner->GetLegLength()
+ + fInner->GetModuleSpacing()
+ + fHoneycombThickness) / 2;
+ fVolumeId = gMC->Gsvolu("FMD2", "TUBE", airId, par, 3);
+
+ // Rotate the full sub-detector
+ gMC->Matrix(fRotationId, 270, 180, 90, 90, 180, 0);
+
+ AliFMDSubDetector::SetupGeometry(airId, kaptionId);
+}
+
+//____________________________________________________________________
+void
+AliFMD2::Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z)
+{
+ z = fDz + fOuterZ;
+ AliFMDSubDetector::Geometry("FMD2", pbRotId, idRotId, z);
+ gMC->Gspos("FMD2", 1, mother, 0, 0, z, fRotationId);
+}
+
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: C++ -*-
+//
+// $Id$
+//
+#ifndef ALIFMD2_H
+#define ALIFMD2_H
+
+#ifndef ALIFMDSUBDETECTOR_H
+# include "AliFMDSubDetector.h"
+#endif
+
+class AliFMD2 : public AliFMDSubDetector
+{
+private:
+ Int_t fVolumeId;
+ Double_t fDz;
+public:
+ AliFMD2();
+ virtual ~AliFMD2();
+ virtual void SetupGeometry(Int_t airId, Int_t kaptionId);
+ virtual void Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z=0);
+ ClassDef(AliFMD2,1); // Geometry of FMD2
+};
+
+#endif
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Concrete implementation of AliFMDSubDetector
+//
+// This implements the geometry for FMD3
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMD3_H
+# include "AliFMD3.h"
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMD3);
+
+//____________________________________________________________________
+AliFMD3::AliFMD3()
+ : AliFMDSubDetector(3)
+{}
+
+//____________________________________________________________________
+AliFMD3::~AliFMD3()
+{}
+
+//____________________________________________________________________
+void
+AliFMD3::SetupGeometry(Int_t airId, Int_t kaptionId)
+{
+ fInnerHoneyLowR = fInner->GetLowR() + 1;
+ fInnerHoneyHighR = fInner->GetHighR() + 1;
+ fOuterHoneyLowR = fOuter->GetLowR() + 1;
+ fOuterHoneyHighR = fOuter->GetHighR() + 1;
+
+ Double_t par[3];
+ par[0] = fInner->GetLowR();
+ par[1] = fOuterHoneyHighR;
+ par[2] = fDz = (TMath::Abs(fInnerZ - fOuterZ)
+ + fInner->GetSiThickness()
+ + fInner->GetPrintboardThickness()
+ + fInner->GetLegLength()
+ + fInner->GetModuleSpacing()
+ + fHoneycombThickness) / 2;
+ fVolumeId = gMC->Gsvolu("FMD3", "TUBE", airId, par, 3);
+
+ gMC->Matrix(fRotationId, 90, 0, 90, 90, 0, 0);
+ //0, 180, 90, 90, 180, 0);
+
+ AliFMDSubDetector::SetupGeometry(airId, kaptionId);
+}
+
+//____________________________________________________________________
+void
+AliFMD3::Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z)
+{
+ z = fInnerZ - fDz;
+ gMC->Gspos("FMD3", 1, mother, 0, 0, z, fRotationId);
+
+ AliFMDSubDetector::Geometry("FMD3", pbRotId, idRotId, z);
+}
+
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: C++ -*-
+//
+// $Id$
+//
+#ifndef ALIFMD3_H
+#define ALIFMD3_H
+
+#ifndef ALIFMDSUBDETECTOR_H
+# include "AliFMDSubDetector.h"
+#endif
+
+class AliFMD3 : public AliFMDSubDetector
+{
+private:
+ Int_t fVolumeId;
+ Double_t fDz;
+public:
+ AliFMD3();
+ virtual ~AliFMD3();
+ virtual void SetupGeometry(Int_t airId, Int_t kaptionId);
+ virtual void Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z=0);
+ ClassDef(AliFMD3,1); // Geometry of FMD3
+};
+
+#endif
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////
+//
+// Digits classes for the FMD
+//
+// Digits consists of
+// - Detector #
+// - Ring ID
+// - Sector #
+// - Strip #
+// - ADC count in this channel
+//
+// Digits consists of
+// - Detector #
+// - Ring ID
+// - Sector #
+// - Strip #
+// - Total energy deposited in the strip
+// - ADC count in this channel
+//
+// As the Digits and SDigits have so much in common, the classes
+// AliFMDDigit and AliFMDSDigit are implemented via a base
+// class AliFMDBaseDigit.
+///
+// +-----------------+
+// | AliFMDBaseDigit |
+// +-----------------+
+// ^
+// |
+// +------------+
+// | |
+// +-------------+ +--------------+
+// | AliFMDDigit | | AliFMDSDigit |
+// +-------------+ +--------------+
+//
+// (Note, that I'd really would have liked to implement AliFMDHit as a
+// derived class from some base class - say AliFMDStrip, and the Digit
+// classes would (eventually) have derived from that as well.
+// However, ROOT doesn't do well with multiple inheritance, so I chose
+// not to anyway).
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef ALIFMDDIGIT_H
+# include "AliFMDDigit.h"
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+#ifndef __IOMANIP__
+# include <iomanip>
+#endif
+
+//====================================================================
+ClassImp(AliFMDBaseDigit);
+
+//____________________________________________________________________
+AliFMDBaseDigit::AliFMDBaseDigit()
+ : fDetector(0),
+ fRing('\0'),
+ fSector(0),
+ fStrip(0)
+{}
+
+//____________________________________________________________________
+AliFMDBaseDigit::AliFMDBaseDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip)
+ : fDetector(detector),
+ fRing(ring),
+ fSector(sector),
+ fStrip(strip)
+{
+ //
+ // Creates a base data digit object
+ //
+ // Parameters
+ //
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+}
+
+//____________________________________________________________________
+void
+AliFMDBaseDigit::Print(Option_t* /* option*/) const
+{
+ // Print digit to standard out
+ std::cout << ClassName() << ": FMD" << fDetector << fRing << "["
+ << std::setw(3) << fSector << ","
+ << std::setw(3) << fStrip << "]"
+ << std::endl;
+}
+
+//====================================================================
+ClassImp(AliFMDDigit);
+
+//____________________________________________________________________
+AliFMDDigit::AliFMDDigit()
+ : fCount1(0),
+ fCount2(-1),
+ fCount3(-1)
+{}
+
+//____________________________________________________________________
+AliFMDDigit::AliFMDDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3)
+ : AliFMDBaseDigit(detector, ring, sector, strip),
+ fCount1(count1),
+ fCount2(count2),
+ fCount3(count3)
+{
+ //
+ // Creates a real data digit object
+ //
+ // Parameters
+ //
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // count1 ADC count (a 10-bit word)
+ // count2 ADC count (a 10-bit word) -1 if not used
+ // count3 ADC count (a 10-bit word) -1 if not used
+}
+
+//____________________________________________________________________
+void
+AliFMDDigit::Print(Option_t* /* option*/) const
+{
+ // Print digit to standard out
+ AliFMDBaseDigit::Print();
+ std::cout << "\t"
+ << fCount1 << " (+ " << fCount2 << " + " << fCount2 << ") = "
+ << Counts() << std::endl;
+}
+
+//====================================================================
+ClassImp(AliFMDSDigit);
+
+//____________________________________________________________________
+AliFMDSDigit::AliFMDSDigit()
+ : fEdep(0),
+ fCount1(0),
+ fCount2(-1),
+ fCount3(-1)
+{}
+
+//____________________________________________________________________
+AliFMDSDigit::AliFMDSDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3)
+ : AliFMDBaseDigit(detector, ring, sector, strip),
+ fEdep(edep),
+ fCount1(count1),
+ fCount2(count2),
+ fCount3(count3)
+{
+ //
+ // Creates a real data digit object
+ //
+ // Parameters
+ //
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // edep Total energy deposited
+ // count1 ADC count (a 10-bit word)
+ // count2 ADC count (a 10-bit word) -1 if not used
+ // count3 ADC count (a 10-bit word) -1 if not used
+}
+
+//____________________________________________________________________
+void
+AliFMDSDigit::Print(Option_t* /* option*/) const
+{
+ // Print digit to standard out
+ AliFMDBaseDigit::Print();
+ std::cout << "\t" << fEdep << " -> "
+ << fCount1 << " (+ " << fCount2 << " + " << fCount2 << ") = "
+ << Counts() << std::endl;
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+#ifndef ALIFMDDIGIT_H
+#define ALIFMDDIGIT_H
+
+//////////////////////////////////////////////////////////////////////
+//
+// Digits classes for the FMD
+//
+//////////////////////////////////////////////////////////////////////
+#ifndef ROOT_TObject
+# include <TObject.h>
+#endif
+
+//____________________________________________________________________
+class AliFMDBaseDigit : public TObject
+{
+protected:
+ UShort_t fDetector; // (Sub) Detector # (1,2, or 3)
+ Char_t fRing; // Ring ID ('I' or 'O')
+ UShort_t fSector; // Sector # (phi division)
+ UShort_t fStrip; // Strip # (radial division)
+public:
+ AliFMDBaseDigit();
+ AliFMDBaseDigit(UShort_t detector,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0);
+ virtual ~AliFMDBaseDigit() {}
+ UShort_t Detector() const { return fDetector; }
+ Char_t Ring() const { return fRing; }
+ UShort_t Sector() const { return fSector; }
+ UShort_t Strip() const { return fStrip; }
+ virtual void Print(Option_t* opt="") const;
+ ClassDef(AliFMDBaseDigit, 1) // Base class for FMD digits
+};
+
+//____________________________________________________________________
+class AliFMDDigit : public AliFMDBaseDigit
+{
+protected:
+ UShort_t fCount1; // Digital signal
+ Short_t fCount2; // Digital signal (-1 if not used)
+ Short_t fCount3; // Digital signal (-1 if not used)
+public:
+ AliFMDDigit();
+ AliFMDDigit(UShort_t detector,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ UShort_t count=0,
+ Short_t count2=-1,
+ Short_t count3=-1);
+ virtual ~AliFMDDigit() {}
+ UShort_t Count1() const { return fCount1; }
+ Short_t Count2() const { return fCount2; }
+ Short_t Count3() const { return fCount3; }
+ UShort_t Counts() const;
+ void Print(Option_t* opt="") const;
+ ClassDef(AliFMDDigit,1) // Normal FMD digit
+};
+
+inline UShort_t
+AliFMDDigit::Counts() const
+{
+ return fCount1
+ + (fCount2 >= 0 ? fCount2 : 0)
+ + (fCount3 >= 0 ? fCount3 : 0);
+}
+
+//____________________________________________________________________
+class AliFMDSDigit : public AliFMDBaseDigit
+{
+protected:
+ Float_t fEdep; // Energy deposited
+ UShort_t fCount1; // Digital signal
+ Short_t fCount2; // Digital signal (-1 if not used)
+ Short_t fCount3; // Digital signal (-1 if not used)
+public:
+ AliFMDSDigit();
+ AliFMDSDigit(UShort_t detector,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ Float_t edep=0,
+ UShort_t count=0,
+ Short_t count2=-1,
+ Short_t count3=-1);
+ virtual ~AliFMDSDigit() {}
+ UShort_t Count1() const { return fCount1; }
+ Short_t Count2() const { return fCount2; }
+ Short_t Count3() const { return fCount3; }
+ Float_t Edep() const { return fEdep; }
+ UShort_t Counts() const;
+ void Print(Option_t* opt="") const;
+ ClassDef(AliFMDSDigit,1) // Summable FMD digit
+};
+
+inline UShort_t
+AliFMDSDigit::Counts() const
+{
+ return fCount1
+ + (fCount2 >= 0 ? fCount2 : 0)
+ + (fCount3 >= 0 ? fCount3 : 0);
+}
+
+
+#endif
+//____________________________________________________________________
+//
+// EOF
+//
- /**************************************************************************
- * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
* *
* Author: The ALICE Off-line Project. *
* Contributors are mentioned in the code where appropriate. *
* provided "as is" without express or implied warranty. *
**************************************************************************/
- //////////////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity Detector based on Silicon plates //
-// This class contains the procedures simulation ADC signal for //
-// the Forward Multiplicity detector : hits -> digits //
-// ADC signal consists //
-// - number of detector; //
-// - number of ring; //
-// - number of sector; //
-// - ADC signal in this channel //
-// //
- //////////////////////////////////////////////////////////////////////////////
-
-#include <TTree.h>
-#include <TVector.h>
-#include <TObjArray.h>
-#include <TFile.h>
-#include <TDirectory.h>
-#include <TRandom.h>
-
-
-#include "AliLog.h"
-#include "AliFMDDigitizer.h"
-#include "AliFMD.h"
-#include "AliFMDhit.h"
-#include "AliFMDdigit.h"
-#include "AliRunDigitizer.h"
-
-#include "AliRun.h"
-#include "AliLoader.h"
-#include "AliRunLoader.h"
-
-#include <stdlib.h>
-#include <Riostream.h>
-#include <Riostream.h>
-
-ClassImp(AliFMDDigitizer)
-
-//___________________________________________
- AliFMDDigitizer::AliFMDDigitizer() :AliDigitizer()
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// This class contains the procedures simulation ADC signal for the
+// Forward Multiplicity detector : Hits->Digits and Hits->SDigits
+//
+// Digits consists of
+// - Detector #
+// - Ring ID
+// - Sector #
+// - Strip #
+// - ADC count in this channel
+//
+// Digits consists of
+// - Detector #
+// - Ring ID
+// - Sector #
+// - Strip #
+// - Total energy deposited in the strip
+// - ADC count in this channel
+//
+// As the Digits and SDigits have so much in common, the classes
+// AliFMDDigitizer and AliFMDSDigitizer are implemented via a base
+// class AliFMDBaseDigitizer.
+//
+// +---------------------+
+// | AliFMDBaseDigitizer |
+// +---------------------+
+// ^
+// |
+// +----------+---------+
+// | |
+// +-----------------+ +------------------+
+// | AliFMDDigitizer | | AliFMDSDigitizer |
+// +-----------------+ +------------------+
+//
+// These classes has several paramters:
+//
+// fPedestal
+// fPedestalWidth
+// (Only AliFMDDigitizer)
+// Mean and width of the pedestal. The pedestal is simulated
+// by a Guassian, but derived classes my override MakePedestal
+// to simulate it differently (or pick it up from a database).
+//
+// fVA1MipRange
+// The dymamic MIP range of the VA1_ALICE pre-amplifier chip
+//
+// fAltroChannelSize
+// The largest number plus one that can be stored in one
+// channel in one time step in the ALTRO ADC chip.
+//
+// fSampleRate
+// How many times the ALTRO ADC chip samples the VA1_ALICE
+// pre-amplifier signal. The VA1_ALICE chip is read-out at
+// 10MHz, while it's possible to drive the ALTRO chip at
+// 25MHz. That means, that the ALTRO chip can have time to
+// sample each VA1_ALICE signal up to 2 times. Although it's
+// not certain this feature will be used in the production,
+// we'd like have the option, and so it should be reflected in
+// the code.
+//
+// The shaping function of the VA1_ALICE is given by
+//
+// f(x) = A(1 - exp(-Bx))
+//
+// Where A is a normalization constant, tuned so that the integral
+//
+// /1
+// | A(-1 + B + exp(-B))
+// | f(x) dx = ------------------- = 1
+// | B
+// / 0
+//
+// and B is the a parameter defined by the shaping time (fShapingTime).
+//
+// Solving the above equation, for A gives
+//
+// B
+// A = ----------------
+// -1 + B + exp(-B)
+//
+// So, if we define the function g: [0,1] -> [0:1] by
+//
+// / v
+// | Bu + exp(-Bu) - Bv - exp(-Bv)
+// g(u,v) = | f(x) dx = -A -----------------------------
+// | B
+// / u
+//
+// we can evaluate the ALTRO sample of the VA1_ALICE pre-amp between
+// any two times (u, v), by
+//
+//
+// B Bu + exp(-Bu) - Bv - exp(-Bv)
+// C = Q g(u,v) = - Q ---------------- -----------------------------
+// -1 + B + exp(-B) B
+//
+// Bu + exp(-Bu) - Bv - exp(-Bv)
+// = - Q -----------------------------
+// -1 + B + exp(-B)
+//
+// Where Q is the total charge collected by the VA1_ALICE
+// pre-amplifier. Q is then given by
+//
+// E S
+// Q = - -
+// e R
+//
+// where E is the total energy deposited in a silicon strip, R is the
+// dynamic range of the VA1_ALICE pre-amp (fVA1MipRange), e is the
+// energy deposited by a single MIP, and S ALTRO channel size in each
+// time step (fAltroChannelSize).
+//
+// The energy deposited per MIP is given by
+//
+// e = M * rho * w
+//
+// where M is the universal number 1.664, rho is the density of
+// silicon, and w is the depth of the silicon sensor.
+//
+// The final ADC count is given by
+//
+// C' = C + P
+//
+// where P is the (randomized) pedestal (see MakePedestal)
+//
+// This class uses the class template AliFMDMap<Type> to make an
+// internal cache of the energy deposted of the hits. The class
+// template is instantasized as
+//
+// typedef AliFMDMap<std::pair<Float_t, UShort_t> > AliFMDEdepMap;
+//
+// The first member of the values is the summed energy deposition in a
+// given strip, while the second member of the values is the number of
+// hits in a given strip. Using the second member, it's possible to
+// do some checks on just how many times a strip got hit, and what
+// kind of error we get in our reconstructed hits. Note, that this
+// information is currently not written to the digits tree. I think a
+// QA (Quality Assurance) digit tree is better suited for that task.
+// However, the information is there to be used in the future.
+//
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef ROOT_TTree
+# include <TTree.h>
+#endif
+#ifndef ROOT_TRandom
+# include <TRandom.h>
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef ALIFMDDIGITIZER_H
+# include "AliFMDDigitizer.h"
+#endif
+#ifndef ALIFMD_H
+# include "AliFMD.h"
+#endif
+#ifndef ALIFMDHIT_H
+# include "AliFMDHit.h"
+#endif
+#ifndef ALIFMDDIGIT_H
+# include "AliFMDDigit.h"
+#endif
+#ifndef ALIFMDDIGIT_H
+# include "AliFMDSDigit.h"
+#endif
+#ifndef ALIRUNDIGITIZER_H
+# include "AliRunDigitizer.h"
+#endif
+#ifndef ALIRUN_H
+# include "AliRun.h"
+#endif
+#ifndef ALILOADER_H
+# include "AliLoader.h"
+#endif
+#ifndef ALIRUNLOADER_H
+# include "AliRunLoader.h"
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDEdepMap);
+
+//====================================================================
+ClassImp(AliFMDBaseDigitizer);
+
+//____________________________________________________________________
+AliFMDBaseDigitizer::AliFMDBaseDigitizer()
+ : fRunLoader(0)
{
-// Default ctor - don't use it
- ;
+ // Default ctor - don't use it
}
-//___________________________________________
-AliFMDDigitizer::AliFMDDigitizer(AliRunDigitizer* manager)
- :AliDigitizer(manager)
+//____________________________________________________________________
+AliFMDBaseDigitizer::AliFMDBaseDigitizer(AliRunDigitizer* manager)
+ : AliDigitizer(manager, "AliFMDBaseDigitizer", "FMD Digitizer base class"),
+ fRunLoader(0),
+ fEdep(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips)
{
- // ctor which should be used
- // fDebug =0;
+ // Normal CTOR
AliDebug(1," processed");
+ SetVA1MipRange();
+ SetAltroChannelSize();
+ SetSampleRate();
+ SetShapingTime();
}
-//------------------------------------------------------------------------
-AliFMDDigitizer::~AliFMDDigitizer()
+//____________________________________________________________________
+AliFMDBaseDigitizer::AliFMDBaseDigitizer(const Char_t* name,
+ const Char_t* title)
+ : AliDigitizer(name, title),
+ fRunLoader(0),
+ fEdep(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips)
{
-// Destructor
+ // Normal CTOR
+ AliDebug(1," processed");
+ SetVA1MipRange();
+ SetAltroChannelSize();
+ SetSampleRate();
+ SetShapingTime();
+}
+//____________________________________________________________________
+AliFMDBaseDigitizer::~AliFMDBaseDigitizer()
+{
+ // Destructor
}
- //------------------------------------------------------------------------
-Bool_t AliFMDDigitizer::Init()
+//____________________________________________________________________
+Bool_t
+AliFMDBaseDigitizer::Init()
{
-// Initialization
-// cout<<"AliFMDDigitizer::Init"<<endl;
- return kTRUE;
+ // Initialization
+ return kTRUE;
}
-//---------------------------------------------------------------------
+//____________________________________________________________________
+void
+AliFMDBaseDigitizer::SumContributions(AliFMD* fmd)
+{
+ // Sum energy deposited contributions from each hit in a cache
+ // (fEdep).
+ if (!fRunLoader)
+ Fatal("SumContributions", "no run loader");
+
+ // Clear array of deposited energies
+ fEdep.Clear();
+
+ // Get the FMD loader
+ AliLoader* inFMD = fRunLoader->GetLoader("FMDLoader");
+ // And load the hits
+ inFMD->LoadHits("READ");
+
+ // Get the tree of hits
+ TTree* hitsTree = inFMD->TreeH();
+ if (!hitsTree) {
+ // Try again
+ inFMD->LoadHits("READ");
+ hitsTree = inFMD->TreeH();
+ }
+
+ // Get the FMD branch
+ TBranch* hitsBranch = hitsTree->GetBranch("FMD");
+ if (hitsBranch) fmd->SetHitsAddressBranch(hitsBranch);
+ else AliFatal("Branch FMD hit not found");
+
+ // Get a list of hits from the FMD manager
+ TClonesArray *fmdHits = fmd->Hits();
+
+ // Get number of entries in the tree
+ Int_t ntracks = Int_t(hitsTree->GetEntries());
+
+ // Loop over the tracks in the
+ for (Int_t track = 0; track < ntracks; track++) {
+ // Read in entry number `track'
+ hitsBranch->GetEntry(track);
+
+ // Get the number of hits
+ Int_t nhits = fmdHits->GetEntries ();
+ for (Int_t hit = 0; hit < nhits; hit++) {
+ // Get the hit number `hit'
+ AliFMDHit* fmdHit =
+ static_cast<AliFMDHit*>(fmdHits->UncheckedAt(hit));
+
+ // Extract parameters
+ UShort_t detector = fmdHit->Detector();
+ Char_t ring = fmdHit->Ring();
+ UShort_t sector = fmdHit->Sector();
+ UShort_t strip = fmdHit->Strip();
+ Float_t edep = fmdHit->Edep();
+ if (fEdep(detector, ring, sector, strip).first != 0)
+ AliDebug(1, Form("Double hit in %d%c(%d,%d)",
+ detector, ring, sector, strip));
+
+ fEdep(detector, ring, sector, strip).first += edep;
+ fEdep(detector, ring, sector, strip).second += 1;
+ // Add this to the energy deposited for this strip
+ } // hit loop
+ } // track loop
+}
-void AliFMDDigitizer::Exec(Option_t * /*option*/)
+//____________________________________________________________________
+void
+AliFMDBaseDigitizer::DigitizeHits(AliFMD* fmd) const
{
+ // For the stored energy contributions in the cache (fEdep), convert
+ // the energy signal to ADC counts, and store the created digit in
+ // the digits array (AliFMD::fDigits)
+ //
+ TArrayI counts(3);
+ for (UShort_t detector=1; detector <= 3; detector++) {
+ // Get pointer to subdetector
+ AliFMDSubDetector* det = 0;
+ switch (detector) {
+ case 1: det = fmd->GetFMD1(); break;
+ case 2: det = fmd->GetFMD2(); break;
+ case 3: det = fmd->GetFMD3(); break;
+ }
+ if (!det) continue;
+ for (UShort_t ringi = 0; ringi <= 1; ringi++) {
+ // Get pointer to Ring
+ AliFMDRing* r = 0;
+ switch (ringi) {
+ case 0: if (det->GetInner()) r = det->GetInner(); break;
+ case 1: if (det->GetOuter()) r = det->GetOuter(); break;
+ }
+ if (!r) continue;
+
+ // Get number of sectors
+ UShort_t nSectors = UShort_t(360. / r->GetTheta());
+ // Loop over the number of sectors
+ for (UShort_t sector = 0; sector < nSectors; sector++) {
+ // Get number of strips
+ UShort_t nStrips = r->GetNStrips();
+ // Loop over the stips
+ for (UShort_t strip = 0; strip < nStrips; strip++) {
+ counts.Reset(-1);
+ Float_t edep = fEdep(detector, r->GetId(), sector, strip).first;
+ ConvertToCount(edep, r->GetSiThickness(), fmd->GetSiDensity(),
+ counts);
+ AddDigit(fmd, detector, r->GetId(), sector, strip,
+ edep, UShort_t(counts[0]),
+ Short_t(counts[1]), Short_t(counts[2]));
+#if 0
+ // This checks if the digit created will give the `right'
+ // number of particles when reconstructed, using a naiive
+ // approach. It's here only as a quality check - nothing
+ // else.
+ CheckDigit(fEdep(detector, r->GetId(), sector, strip).first,
+ fEdep(detector, r->GetId(), sector, strip).second,
+ counts);
+#endif
+ } // Strip
+ } // Sector
+ } // Ring
+ } // Detector
+}
- /*
- Conver hits to digits:
- - number of detector;
- - number of ring;
- - number of sector;
- - ADC signal in this channel
- */
+//____________________________________________________________________
+Float_t
+AliFMDBaseDigitizer::ShapeIntegral(Float_t u, Float_t v) const
+{
+ // Calculates the integral
+ //
+ // / v
+ // | Bu + exp(-Bu) - Bv - exp(-Bv)
+ // | f(x) dx = - A -----------------------------
+ // | B
+ // / u
+ //
+ // of the shaping function of the VA1_ALICE between times u and v
+ //
+ // f(x) = A(1 - exp(-Bx))
+ //
+ // where A is a normalization constant, tuned so that the integral
+ //
+ // /1
+ // | B
+ // | f(x) dx = 1 => A = ----------------
+ // | -1 + B + exp(-B)
+ // / 0
+ //
+ // and B is the a parameter defined by the shaping time (fShapingTime).
+ //
+ // That is, the function return the value
+ //
+ // Bu + exp(-Bu) - Bv - exp(-Bv)
+ // - -----------------------------
+ // -1 + B + exp(-B)
+ //
+ // u,v should lie in the interval [0,1], and u < v
+ if (u == 0 && v == 1) return 1;
+ Float_t B = fShapingTime;
+
+ // Calculate the integral
+ Float_t res = - ((B * u + TMath::Exp(-B * u) - B * v - TMath::Exp(-B * v)) /
+ (-1 + B + TMath::Exp(-B)));
+ return res;
+}
- AliRunLoader *inRL, *outRL;//in and out Run Loaders
- AliLoader *pInFMD, *pOutFMD;// in and out ITSLoaders
+//____________________________________________________________________
+void
+AliFMDBaseDigitizer::ConvertToCount(Float_t edep,
+ Float_t siThickness,
+ Float_t siDensity,
+ TArrayI& counts) const
+{
+ // Put noise and make ADC signal
+ // This is calculated as the product
+ //
+ // DeltaEmip * SiThickness * SiDensity / Number
+ //
+ // Where
+ //
+ // DeltaEmip is the energy loss of a MIP
+ // SiThickness is the thickness of the silicon
+ // SiDensity is the Silicon density
+ // Number is # of e^- per MIP
+ //
+ // Note: Need to check this is correct.
+ //
+ const Float_t mipI = 1.664 * siThickness * siDensity;
+ // const Float_t mipI = 1.664 * 0.04 * 2.33 / 22400; // = 6.923e-6;
+
+ // Create a pedestal
+ UShort_t ped = MakePedestal();
+
+ Float_t convf = 1 / mipI * Float_t(fAltroChannelSize) / fVA1MipRange;
+ Int_t n = fSampleRate;
+ for (Ssiz_t i = 0; i < n; i++) {
+ Float_t w = ShapeIntegral(Float_t(i)/n, Float_t(i+1)/n);
+ counts[i] = UShort_t(TMath::Min(w * edep * convf + ped,
+ Float_t(fAltroChannelSize)));
+ }
+}
- outRL = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- pOutFMD = outRL->GetLoader("FMDLoader");
+//====================================================================
+ClassImp(AliFMDDigitizer);
- AliDebug(1," start...");
+//____________________________________________________________________
+AliFMDDigitizer::AliFMDDigitizer()
+ : AliFMDBaseDigitizer()
+{
+ // Default ctor - don't use it
+}
+//____________________________________________________________________
+AliFMDDigitizer::AliFMDDigitizer(AliRunDigitizer* manager)
+ : AliFMDBaseDigitizer(manager)
+{
+ // Normal CTOR
+ AliDebug(1," processed");
+ SetPedestal();
+}
- Int_t volume, sector, ring, charge;
- Float_t e;
- Float_t de[10][50][520];
- Int_t hit;
- Int_t digit[5];
- Int_t ivol, iSector, iRing;
- for (Int_t i=0; i<10; i++)
- for(Int_t j=0; j<50; j++)
- for(Int_t ij=0; ij<520; ij++)
- de[i][j][ij]=0;
- Int_t numberOfRings[5]= {512,256,512,256,512};
- Int_t numberOfSector[5] = {20,40,20,40,20};
+//____________________________________________________________________
+void
+AliFMDDigitizer::Exec(Option_t*)
+{
+ // Get the output manager
+ TString outFolder(fManager->GetOutputFolderName());
+ AliRunLoader* out =
+ AliRunLoader::GetRunLoader(outFolder.Data());
+ // Get the FMD output manager
+ AliLoader* outFMD = out->GetLoader("FMDLoader");
+
+ // Get the input loader
+ TString inFolder(fManager->GetInputFolderName(0));
+ fRunLoader =
+ AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
+ if (!fRunLoader) {
+ AliError("Can not find Run Loader for input stream 0");
+ return;
+ }
+ // Get the AliRun object
+ if (!fRunLoader->GetAliRun()) fRunLoader->LoadgAlice();
+
+ // Get the AliFMD object
+ AliFMD* fmd = static_cast<AliFMD*>(fRunLoader->GetAliRun()->GetDetector("FMD"));
+ if (!fmd) {
+ AliError("Can not get FMD from gAlice");
+ return;
+ }
+
+ Int_t nFiles= fManager->GetNinputs();
+ for (Int_t inputFile = 0; inputFile < nFiles; inputFile++) {
+ AliDebug(1,Form(" Digitizing event number %d",
+ fManager->GetOutputEventNr()));
+ // Get the current loader
+ fRunLoader =
+ AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
+ if (!fRunLoader) Fatal("Exec", "no run loader");
+ // Cache contriutions
+ SumContributions(fmd);
+ }
+ // Digitize the event
+ DigitizeHits(fmd);
+
+ // Load digits from the tree
+ outFMD->LoadDigits("update");
+ // Get the tree of digits
+ TTree* digitTree = outFMD->TreeD();
+ if (!digitTree) {
+ outFMD->MakeTree("D");
+ digitTree = outFMD->TreeD();
+ }
+ digitTree->Reset();
+ // Make a branch in the tree
+ TClonesArray* digits = fmd->Digits();
+ fmd->MakeBranchInTree(digitTree, fmd->GetName(), &(digits), 4000, 0);
+ // TBranch* digitBranch = digitTree->GetBranch(fmd->GetName());
+ // Fill the tree
+ digitTree->Fill();
- AliFMDhit *fmdHit=0;
- TTree *tH=0;
- TBranch *brHits=0;
- TBranch *brD=0;
+ // Write the digits to disk
+ outFMD->WriteDigits("OVERWRITE");
+ outFMD->UnloadHits();
+ outFMD->UnloadDigits();
- inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
+ // Reset the digits in the AliFMD object
+ fmd->ResetDigits();
+}
- if (inRL == 0x0)
- {
- AliError("Can not find Run Loader for input stream 0");
- return;
- }
- if (!inRL->GetAliRun()) inRL->LoadgAlice();
+//____________________________________________________________________
+UShort_t
+AliFMDDigitizer::MakePedestal() const
+{
+ return UShort_t(TMath::Max(gRandom->Gaus(fPedestal, fPedestalWidth), 0.));
+}
- AliFMD * fFMD = (AliFMD *) inRL->GetAliRun()->GetDetector("FMD");
+//____________________________________________________________________
+void
+AliFMDDigitizer::AddDigit(AliFMD* fmd,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t /* edep */,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3) const
+{
+ fmd->AddDigit(detector, ring, sector, strip, count1, count2, count3);
+}
- if (fFMD == 0x0)
- {
- AliError("Can not get FMD from gAlice");
- return;
- }
-// Loop over files to digitize
+//____________________________________________________________________
+void
+AliFMDDigitizer::CheckDigit(Float_t /* edep */,
+ UShort_t nhits,
+ const TArrayI& counts)
+{
+ Int_t integral = counts[0];
+ if (counts[1] >= 0) integral += counts[1];
+ if (counts[2] >= 0) integral += counts[2];
+ integral -= Int_t(fPedestal + 2 * fPedestalWidth);
+ if (integral < 0) integral = 0;
+
+ Float_t convf = Float_t(fVA1MipRange) / fAltroChannelSize;
+ Float_t mips = integral * convf;
+ if (mips > Float_t(nhits) + .5 || mips < Float_t(nhits) - .5)
+ Warning("CheckDigit", "Digit -> %4.2f MIPS != %d +/- .5 hits",
+ mips, nhits);
+}
- Int_t nFiles=GetManager()->GetNinputs();
- for (Int_t inputFile=0; inputFile<nFiles;inputFile++)
- {
+//====================================================================
+ClassImp(AliFMDSDigitizer);
- AliDebug(1,Form(" Digitizing event number %d",fManager->GetOutputEventNr()));
-
- if (fFMD)
- {
+//____________________________________________________________________
+AliFMDSDigitizer::AliFMDSDigitizer()
+{
+ // Default ctor - don't use it
+}
- inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
- pInFMD = inRL->GetLoader("FMDLoader");
- pInFMD->LoadHits("READ");
-
-
- tH = pInFMD->TreeH();
- if (tH == 0x0)
- {
- pInFMD->LoadHits("read");
- tH = pInFMD->TreeH();
- }
- brHits = tH->GetBranch("FMD");
- if (brHits) {
- fFMD->SetHitsAddressBranch(brHits);
- }else{
- AliFatal("Branch FMD hit not found");
- }
- TClonesArray *fFMDhits = fFMD->Hits ();
-
- Int_t ntracks = (Int_t) tH->GetEntries();
+//____________________________________________________________________
+AliFMDSDigitizer::AliFMDSDigitizer(const Char_t* headerFile,
+ const Char_t* /* sdigfile */)
+ : AliFMDBaseDigitizer("FMDSDigitizer", "FMD SDigitizer")
+{
+ // Normal CTOR
+ AliDebug(1," processed");
- for (Int_t track = 0; track < ntracks; track++)
- {
- brHits->GetEntry(track);
- Int_t nhits = fFMDhits->GetEntries ();
+ fRunLoader = AliRunLoader::GetRunLoader(); // Open(headerFile);
+ if (!fRunLoader)
+ Fatal("AliFMDSDigitizer", "cannot open session, header file '%s'",
+ headerFile);
+ AliLoader* loader = fRunLoader->GetLoader("FMDLoader");
+ if (!loader)
+ Fatal("AliFMDSDigitizer", "cannot find FMD loader in specified event");
- for (hit = 0; hit < nhits; hit++)
- {
- fmdHit = (AliFMDhit *) fFMDhits->UncheckedAt(hit);
+ // Add task to tasks folder
+ loader->PostSDigitizer(this);
+}
- volume = fmdHit->Volume ();
- sector = fmdHit->NumberOfSector ();
- ring = fmdHit->NumberOfRing ();
- e = fmdHit->Edep ();
- de[volume][sector][ring] += e;
+//____________________________________________________________________
+AliFMDSDigitizer::~AliFMDSDigitizer()
+{
+ AliLoader* loader = fRunLoader->GetLoader("FMDLoader");
+ loader->CleanSDigitizer();
+}
- } //hit loop
- } //track loop
- }
-//if FMD
- }
+//____________________________________________________________________
+void
+AliFMDSDigitizer::Exec(Option_t*)
+{
+ // Get the output manager
+ if (!fRunLoader) {
+ Error("Exec", "Run loader is not set");
+ return;
+ }
+ if (!fRunLoader->GetAliRun()) fRunLoader->LoadgAlice();
+ if (!fRunLoader->TreeE()) fRunLoader->LoadHeader();
+
+ AliLoader* fmdLoader = fRunLoader->GetLoader("FMDLoader");
+ if (!fmdLoader) Fatal("Exec", "no FMD loader");
+
+ // Get the AliFMD object
+ AliFMD* fmd =
+ static_cast<AliFMD*>(fRunLoader->GetAliRun()->GetDetector("FMD"));
+ if (!fmd) {
+ AliError("Can not get FMD from gAlice");
+ return;
+ }
+
+ Int_t nEvents = Int_t(fRunLoader->TreeE()->GetEntries());
+ for (Int_t event = 0; event < nEvents; event++) {
+ AliDebug(1,Form(" Digitizing event number %d", event));
+ // Get the current loader
+ fRunLoader->GetEvent(event);
+
+ if (!fmdLoader->TreeS()) fmdLoader->MakeTree("S");
+ // Make a branch
+ fmd->MakeBranch("S");
+
+ // Cache contriutions
+ SumContributions(fmd);
+
+ // Digitize the event
+ DigitizeHits(fmd);
+
+ fmdLoader->TreeS()->Reset();
+ fmdLoader->TreeS()->Fill();
+ fmdLoader->WriteSDigits("OVERWRITE");
+ }
+}
-
- // Put noise and make ADC signal
- Float_t mipI = 1.664 * 0.04 * 2.33 / 22400; // = 6.923e-6;
- for ( ivol=1; ivol<=5; ivol++){
- for ( iSector=1; iSector<=numberOfSector[ivol-1]; iSector++){
- for ( iRing=1; iRing<=numberOfRings[ivol-1]; iRing++){
- digit[0]=ivol;
- digit[1]=iSector;
- digit[2]=iRing;
- charge = Int_t (de[ivol][iSector][iRing] / mipI);
- Int_t pedestal=Int_t(gRandom->Gaus(500,250));
- // digit[3]=PutNoise(charge);
- digit[3]=charge + pedestal;
- if(digit[3]<= 500) digit[3]=500;
- //dynamic range from MIP(0.155MeV) to 30MIP(4.65MeV)
- //1024 ADC channels
- Float_t channelWidth=(22400*50)/1024;
- digit[4]=Int_t(digit[3]/channelWidth);
- if (digit[4]>1024) digit[4]=1024;
- fFMD->AddDigit(digit);
- } //ivol
- } //iSector
- } //iRing
-
- pOutFMD->LoadDigits("update");
- TTree* treeD = pOutFMD->TreeD();
-
- if (treeD == 0x0) {
- pOutFMD->MakeTree("D");
- treeD = pOutFMD->TreeD();
-
- }
-
- treeD->Reset();
- fFMD->MakeBranchInTreeD(treeD);
- brD = treeD->GetBranch("FMD");
-
-
- treeD->Fill();
-
- pOutFMD->WriteDigits("OVERWRITE");
- pOutFMD->UnloadHits();
- pOutFMD->UnloadDigits();
- fFMD->ResetDigits();
+//____________________________________________________________________
+void
+AliFMDSDigitizer::AddDigit(AliFMD* fmd,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3) const
+{
+ fmd->AddSDigit(detector, ring, sector, strip, edep, count1, count2, count3);
}
-
+
+
+
+//____________________________________________________________________
+//
+// EOF
+//
+// -*- mode: c++ -*-
#ifndef ALIFMDDIGITIZER_H
#define ALIFMDDIGITIZER_H
-/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
-#include <AliDigitizer.h>
-#include <AliRunDigitizer.h>
+/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
+#ifndef ALIDIGITIZER_H
+# include <AliDigitizer.h>
+#endif
+#ifndef ALIRUNDIGITIZER_H
+# include <AliRunDigitizer.h>
+#endif
+#ifndef ALIFMDMAP_H
+# include <AliFMDMap.h>
+#endif
+#ifndef __UTILITY__
+# include <utility>
+#endif
+// #ifndef ROOT_TArrayF
+// # include <TArrayF.h>
+// #endif
+//====================================================================
class TClonesArray;
-class AliFMDDigitizer : public AliDigitizer {
- public:
-
- AliFMDDigitizer();
- AliFMDDigitizer(AliRunDigitizer * manager);
- virtual ~AliFMDDigitizer();
- virtual Bool_t Init();
+class AliFMD;
+class AliLoader;
+class AliRunLoader;
+
+typedef AliFMDMap<std::pair<Float_t, UShort_t> > AliFMDEdepMap;
+
+//====================================================================
+class AliFMDBaseDigitizer : public AliDigitizer
+{
+public:
+ AliFMDBaseDigitizer();
+ AliFMDBaseDigitizer(AliRunDigitizer * manager);
+ AliFMDBaseDigitizer(const Char_t* name, const Char_t* title);
+ virtual ~AliFMDBaseDigitizer();
-
// Do the main work
- void Exec(Option_t* option=0) ;
- Int_t PutNoise(Int_t charge) {return (Int_t)(gRandom->Gaus(charge,500));}
- TClonesArray *Digits() const {return fDigits;}
- TClonesArray *Hits() const {return fHits;}
+ virtual Bool_t Init();
+
+ // Extra member functions
+ void SetVA1MipRange(UShort_t r=20) { fVA1MipRange = r; }
+ void SetAltroChannelSize(UShort_t s=1024) { fAltroChannelSize = s;}
+ void SetSampleRate(UShort_t r=1) { fSampleRate = (r>2 ? 2 : r); }
+ void SetShapingTime(Float_t t=10) { fShapingTime = t; }
+
+ UShort_t GetVA1MipRange() const { return fVA1MipRange; }
+ UShort_t GetAltroChannelSize() const { return fAltroChannelSize; }
+ UShort_t GetSampleRate() const { return fSampleRate; }
+ Float_t GetShapingTime() const { return fShapingTime; }
+protected:
+ virtual void SumContributions(AliFMD* fmd);
+ virtual void DigitizeHits(AliFMD* fmd) const;
+ virtual void ConvertToCount(Float_t edep,
+ Float_t siThickness,
+ Float_t siDensity,
+ TArrayI& counts) const;
+ virtual UShort_t MakePedestal() const { return 0; }
+ virtual Float_t ShapeIntegral(Float_t u, Float_t v) const;
+ virtual void AddNoise(TArrayI&) const {}
+ virtual void AddDigit(AliFMD* /* fmd */,
+ UShort_t /* detector */,
+ Char_t /* ring */,
+ UShort_t /* sector */,
+ UShort_t /* strip */,
+ Float_t /* edep */,
+ UShort_t /* count1 */,
+ Short_t /* count2 */,
+ Short_t /* count3 */) const {}
+ AliRunLoader* fRunLoader;
+ AliFMDEdepMap fEdep; // Cache of Energy from hits
+ UShort_t fVA1MipRange; // How many MIPs the pre-amp can do
+ UShort_t fAltroChannelSize; // Largest # to store in 1 ADC chan.
+ UShort_t fSampleRate; // Times the ALTRO samples pre-amp.
+ Float_t fShapingTime; // Shaping profile parameter
+
+ enum {
+ kMaxDetectors = 3,
+ kMaxRings = 2,
+ kMaxSectors = 20,
+ kMaxStrips = 512
+ };
+ ClassDef(AliFMDBaseDigitizer,0) // Base class for FMD digitizers
+};
+
+//====================================================================
+class AliFMDDigitizer : public AliFMDBaseDigitizer
+{
+public:
+ AliFMDDigitizer();
+ AliFMDDigitizer(AliRunDigitizer * manager);
+ virtual ~AliFMDDigitizer() {}
+ virtual void Exec(Option_t* option=0);
- enum {kBgTag = -1};
-
- private:
- TClonesArray *fDigits; // ! array with digits
- TClonesArray *fHits; // List of hits
- AliRunDigitizer* GetManager(){return fManager;}
-
- ClassDef(AliFMDDigitizer,0)
-};
-#endif
+ // Extra member functions
+ void SetPedestal(Float_t mean=10, Float_t width=.5);
+ void GetPedestal(Float_t& mean, Float_t& width) const;
+protected:
+ virtual void AddDigit(AliFMD* fmd,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3) const;
+ virtual UShort_t MakePedestal() const;
+ virtual void CheckDigit(Float_t edep,
+ UShort_t nhits,
+ const TArrayI& counts);
+ Float_t fPedestal; // Mean of pedestal
+ Float_t fPedestalWidth; // Width of pedestal
+ ClassDef(AliFMDDigitizer,0) // Make Digits from Hits
+};
+//____________________________________________________________________
+inline void
+AliFMDDigitizer::SetPedestal(Float_t mean, Float_t width)
+{
+ fPedestal = mean;
+ fPedestalWidth = width;
+}
+
+//____________________________________________________________________
+inline void
+AliFMDDigitizer::GetPedestal(Float_t& mean, Float_t& width) const
+{
+ mean = fPedestal;
+ width = fPedestalWidth;
+}
+//====================================================================
+class AliFMDSDigitizer : public AliFMDBaseDigitizer
+{
+public:
+ AliFMDSDigitizer();
+ AliFMDSDigitizer(const Char_t* headerFile, const Char_t* sdigFile="");
+ virtual ~AliFMDSDigitizer();
+ virtual void Exec(Option_t* option=0);
+protected:
+ virtual void AddDigit(AliFMD* fmd,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3) const;
+ ClassDef(AliFMDSDigitizer,0) // Make Summable Digits from Hits
+};
+
+#endif
+//____________________________________________________________________
+//
+// EOF
+//
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Hits in the FMD
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMDHIT_H
+# include "AliFMDHit.h"
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+#ifndef __IOMANIP__
+# include <iomanip>
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDHit);
+
+
+//____________________________________________________________________
+AliFMDHit::AliFMDHit()
+ : fDetector(0),
+ fRing(0),
+ fSector(0),
+ fStrip('\0'),
+ fPx(0),
+ fPy(0),
+ fPz(0),
+ fPdg(0),
+ fEdep(0),
+ fTime(0)
+{
+ fX = fY = fZ = 0;
+}
+
+
+//____________________________________________________________________
+AliFMDHit::AliFMDHit(Int_t shunt,
+ Int_t track,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t x,
+ Float_t y,
+ Float_t z,
+ Float_t px,
+ Float_t py,
+ Float_t pz,
+ Float_t edep,
+ Int_t pdg,
+ Float_t t)
+ : AliHit(shunt, track),
+ fDetector(detector),
+ fRing(ring),
+ fSector(sector),
+ fStrip(strip),
+ fPx(px),
+ fPy(py),
+ fPz(pz),
+ fPdg(pdg),
+ fEdep(edep),
+ fTime(t)
+{
+ // Normal FMD hit ctor
+ //
+ // Parameters:
+ //
+ // shunt ???
+ // track Track #
+ // detector Detector # (1, 2, or 3)
+ // ring Ring ID ('I' or 'O')
+ // sector Sector # (For inner/outer rings: 0-19/0-39)
+ // strip Strip # (For inner/outer rings: 0-511/0-255)
+ // x Track's X-coordinate at hit
+ // y Track's Y-coordinate at hit
+ // z Track's Z-coordinate at hit
+ // px X-component of track's momentum
+ // py Y-component of track's momentum
+ // pz Z-component of track's momentum
+ // edep Energy deposited by track
+ // pdg Track's particle Id #
+ // t Time when the track hit
+ //
+ fX = x;
+ fY = y;
+ fZ = z;
+}
+
+//____________________________________________________________________
+void
+AliFMDHit::Print(Option_t* /* option */) const
+{
+ // Print Hit to standard out
+ std::cout << "AliFMDHit: FMD"
+ << fDetector << fRing << "["
+ << std::setw(3) << fSector << ","
+ << std::setw(3) << fStrip << "] = "
+ << fEdep << std::endl;
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
+// -*- mode: c++ -*-
#ifndef AliFMDhit_H
#define AliFMDhit_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
////////////////////////////////////////////////
-// Manager and hits classes for set:FMD //
+//
+// Manager and hits classes for set:FMD
+//
////////////////////////////////////////////////
-#include "AliHit.h"
-
+#ifndef ALIHIT_H
+# include "AliHit.h"
+#endif
-class AliFMDhit : public AliHit {
+
///////////////////////////////////////////////////////////////////////
// AliFMDhit is the hit class for the FMD. Hits are the information
// that comes from a Monte Carlo at each step as a particle mass through
// The time of flight associated with the particle ending in this
// hit. The time is typically measured from the point of creation of the
// original particle (if this particle is a daughter). The units
-// are those determined by the Monte Carlo.
+// are those determined by the Monte Carlo.
-
+class AliFMDHit : public AliHit
+{
public:
- AliFMDhit() {}
- AliFMDhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits);
- virtual ~AliFMDhit() {}
- Int_t Volume() const {return fVolume;}
- Int_t NumberOfSector() const {return fNumberOfSector;}
- Int_t NumberOfRing() const {return fNumberOfRing;}
- Float_t Particle() const {return fParticle;}
- Float_t Edep() const {return fEdep;}
- Float_t Px() const {return fPx;}
- Float_t Py() const {return fPy;}
- Float_t Pz() const {return fPz;}
- Float_t Time() const {return fTime;}
+ AliFMDHit();
+ AliFMDHit(Int_t shunt,
+ Int_t track,
+ UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t x=0,
+ Float_t y=0,
+ Float_t z=0,
+ Float_t px=0,
+ Float_t py=0,
+ Float_t pz=0,
+ Float_t edep=0,
+ Int_t pdg=0,
+ Float_t t=0);
+ virtual ~AliFMDHit() {}
+
+ UShort_t Detector() const { return fDetector; }
+ Char_t Ring() const { return fRing; }
+ UShort_t Sector() const { return fSector; }
+ UShort_t Strip() const { return fStrip; }
+ Float_t Edep() const { return fEdep; }
+ Float_t Px() const { return fPx; }
+ Float_t Py() const { return fPy; }
+ Float_t Pz() const { return fPz; }
+ Int_t Pdg() const { return fPdg; }
+ Float_t Time() const { return fTime; }
+ void Print(Option_t* opt="") const;
+
+ void SetEdep(Float_t edep) { fEdep = edep; }
private:
- Int_t fVolume; //Volume copy identifier
- Int_t fNumberOfSector; //number of sector of hitted pad
- Int_t fNumberOfRing; //number of ring of hitted pad
- Int_t fParticle; //Particle identificator
- Float_t fEdep; //Energy deposition
- Float_t fPx; // Particle's momentum X
- Float_t fPy; // Particle's momentum Y
- Float_t fPz; // Particle's momentum Z
- Float_t fTime; // Particle's time of flight
+ UShort_t fDetector; // (Sub) Detector # (1,2, or 3)
+ Char_t fRing; // Ring ID ('I' or 'O')
+ UShort_t fSector; // Sector # (phi division)
+ UShort_t fStrip; // Strip # (radial division)
+ Float_t fPx; // Particle's X momentum X
+ Float_t fPy; // Particle's Y momentum Y
+ Float_t fPz; // Particle's Z momentum Z
+ Int_t fPdg; // Particles PDG code
+ Float_t fEdep; // Energy deposition
+ Float_t fTime; // Particle's time of flight
- ClassDef(AliFMDhit,1) //Hits for detector FMD
+ ClassDef(AliFMDHit,1) //Hits for detector FMD
};
#endif
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+#ifndef ALIFMDMAP_H
+#define ALIFMDMAP_H
+/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
+#ifndef __VECTOR__
+# include <vector>
+#endif
+
+template <typename Type>
+class AliFMDMap : public TObject
+{
+private:
+ typedef std::vector<Type> ValueVector; // Type of container
+ ValueVector fValues; // Contained values
+ size_t fMaxDetectors; // Maximum # of detectors
+ size_t fMaxRings; // Maximum # of rings
+ size_t fMaxSectors; // Maximum # of sectors
+ size_t fMaxStrips; // Maximum # of strips
+
+ size_t CalcIndex(size_t det, Char_t ring, size_t sec, size_t str) const;
+public:
+ AliFMDMap(size_t maxDet=3, size_t maxRing=2, size_t maxSec=40,
+ size_t maxStr=512);
+ virtual ~AliFMDMap() {}
+ void Clear();
+ Type& operator()(size_t det, Char_t ring, size_t sec, size_t str);
+ const Type& operator()(size_t det, Char_t ring, size_t sec, size_t str)const;
+ ClassDef(AliFMDMap, 0); // Map of FMD index's to values
+};
+
+
+//____________________________________________________________________
+template <typename Type>
+inline
+AliFMDMap<Type>::AliFMDMap(size_t maxDet,
+ size_t maxRing,
+ size_t maxSec,
+ size_t maxStr)
+ : fValues(maxDet * maxRing * maxSec * maxStr),
+ fMaxDetectors(maxDet),
+ fMaxRings(maxRing),
+ fMaxSectors(maxSec),
+ fMaxStrips(maxStr)
+{
+ // Construct a map
+ //
+ // Parameters:
+ // maxDet Maximum # of detectors
+ // maxRinf Maximum # of rings
+ // maxSec Maximum # of sectors
+ // maxStr Maximum # of strips
+}
+
+
+//____________________________________________________________________
+template <typename Type>
+inline size_t
+AliFMDMap<Type>::CalcIndex(size_t det, Char_t ring, size_t sec, size_t str) const
+{
+ // Calculate index into storage from arguments.
+ //
+ // Parameters:
+ // det Detector #
+ // ring Ring ID
+ // sec Sector #
+ // str Strip #
+ //
+ // Returns appropriate index into storage
+ //
+ size_t ringi = (ring == 'I' || ring == 'i' ? 0 : 1);
+ size_t idx =
+ (det + fMaxDetectors * (ringi + fMaxRings * (sec + fMaxSectors * str)));
+ if (idx >= fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips) {
+ Fatal("CalcIndex", "Index (%d,'%c',%d,%d) out of bounds, "
+ "in particular the %s index",
+ det, ring, sec, str,
+ (det >= fMaxDetectors ? "Detector" :
+ (ringi >= fMaxRings ? "Ring" :
+ (sec >= fMaxSectors ? "Sector" : "Strip"))));
+ return 0;
+ }
+ return idx;
+}
+
+//____________________________________________________________________
+template <typename Type>
+inline void
+AliFMDMap<Type>::Clear()
+{
+ // Resets stored values to the default value for that type
+ for (size_t i = 0; i < fValues.size(); ++i) fValues[i] = Type();
+}
+
+//____________________________________________________________________
+template <typename Type>
+inline Type&
+AliFMDMap<Type>::operator()(size_t det, Char_t ring, size_t sec, size_t str)
+{
+ // Parameters:
+ // det Detector #
+ // ring Ring ID
+ // sec Sector #
+ // str Strip #
+ //
+ // Returns data[det][ring][sec][str]
+ return fValues[CalcIndex(det, ring, sec, str)];
+}
+
+//____________________________________________________________________
+template <typename Type>
+inline const Type&
+AliFMDMap<Type>::operator()(size_t det, Char_t ring, size_t sec, size_t str)const
+{
+ // Parameters:
+ // det Detector #
+ // ring Ring ID
+ // sec Sector #
+ // str Strip #
+ //
+ // Returns data[det][ring][sec][str]
+ return fValues[CalcIndex(det, ring, sec, str)];
+}
+
+
+
+#endif
+//
+// EOF
+//
+
+
--- /dev/null
+//////////////////////////////////////////////////////////////////////
+//
+// Forward Multiplicity Detector have to be reconstructed number of
+// particles in fixed pseudorapidity interval from fNumOfMinRing
+// to fNumOfMaxRing and phi interval from fNumOfMinSector to
+// fNumOfMaxSector
+//
+//////////////////////////////////////////////////////////////////////
+#ifndef ALIFMDPARTICLES_H
+# include "AliFMDParticles.h"
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+#ifndef __IOMANIP__
+# include <iomanip>
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDParticles)
+
+//____________________________________________________________________
+AliFMDParticles::AliFMDParticles()
+ : fDetector(0),
+ fRing('\0'),
+ fMinSector(0),
+ fMaxSector(0),
+ fMinStrip(0),
+ fMaxStrip(0),
+ fMinEta(0),
+ fMaxEta(0),
+ fMinPhi(0),
+ fMaxPhi(0),
+ fParticles(0),
+ fMethod(kNaive)
+{}
+
+//____________________________________________________________________
+AliFMDParticles::AliFMDParticles(UShort_t detector, Char_t ring,
+ UShort_t minSector, UShort_t maxSector,
+ UShort_t minStrip, UShort_t maxStrip,
+ Float_t minEta, Float_t maxEta,
+ Float_t minPhi, Float_t maxPhi,
+ Float_t particles, UShort_t method)
+ : fDetector(detector),
+ fRing(ring),
+ fMinSector(minSector),
+ fMaxSector(maxSector),
+ fMinStrip(minStrip),
+ fMaxStrip(maxStrip),
+ fMinEta(minEta),
+ fMaxEta(maxEta),
+ fMinPhi(minPhi),
+ fMaxPhi(maxPhi),
+ fParticles(particles),
+ fMethod(method)
+{
+ switch (fMethod) {
+ case kPoission:
+ case kIterative:
+ case kNaive:
+ break;
+ default:
+ Warning("AliFMDParticles", "unknown method: %d", method);
+ break;
+ }
+}
+
+
+//____________________________________________________________________
+void
+AliFMDParticles::Print(Option_t* /* opt*/) const
+{
+ std::cout << "FMD Reconstructed particles: " << fParticles << "\n"
+ << " Detector: FMD" << fDetector << fRing << "\n"
+ << " Sector range: [" << fMinSector << "," << fMaxSector << "\n"
+ << " Strip range: [" << fMinStrip << "," << fMaxStrip << "\n"
+ << " Eta range: [" << fMinEta << "," << fMaxEta << "\n"
+ << " Phi range: [" << fMinPhi << "," << fMaxPhi << "\n"
+ << " Method: " << std::flush;
+ switch (fMethod) {
+ case kPoission: std::cout << "Poission" << std::endl; break;
+ case kIterative: std::cout << "Iterative" << std::endl; break;
+ case kNaive: std::cout << "Naive" << std::endl; break;
+ default: std::cout << "Unknown" << std::endl; break;
+ }
+}
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+#ifndef ALIFMDPARTICLES_H
+#define ALIFMDPARTICLES_H
+
+/* Reconstracted Particles Class: has number of reconstructed
+ * particles in sectors from NumOfMinSector to NumberOfMaxSector()
+ * rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
+ */
+#ifndef ROOT_TObject
+# include <TObject.h>
+#endif
+
+class AliFMDParticles: public TObject
+{
+public:
+ enum EMethod {
+ kPoission,
+ kIterative,
+ kNaive
+ };
+
+ AliFMDParticles();
+ AliFMDParticles (UShort_t detector, Char_t ring,
+ UShort_t minSector, UShort_t maxSector,
+ UShort_t minStrip, UShort_t maxStrip,
+ Float_t minEta, Float_t maxEta,
+ Float_t minPhi, Float_t maxPhi,
+ Float_t particles, UShort_t method);
+ virtual ~AliFMDParticles(){};
+
+ UShort_t Detector() const { return fDetector; }
+ Char_t Ring() const { return fRing; }
+ UShort_t MinSector() const { return fMinSector; }
+ UShort_t MaxSector() const { return fMaxSector; }
+ UShort_t MinStrip() const { return fMinStrip; }
+ UShort_t MaxStrip() const { return fMaxStrip; }
+ Float_t MinEta() const { return fMinEta; }
+ Float_t MaxEta() const { return fMaxEta; }
+ Float_t MinPhi() const { return fMinPhi; }
+ Float_t MaxPhi() const { return fMaxPhi; }
+ Float_t Particles() const { return fParticles; }
+ UShort_t Method() const { return fMethod; }
+
+ virtual void Print(Option_t* opt="") const;
+protected:
+ UShort_t fDetector; // Detector #
+ Char_t fRing; // Ring ID
+ UShort_t fMinSector; // First sector of this region
+ UShort_t fMaxSector; // Last sector of this region
+ UShort_t fMinStrip; // First strip of this region
+ UShort_t fMaxStrip; // Second strip of this region
+ Float_t fMinEta; // Least eta covered
+ Float_t fMaxEta; // Largest eta covered
+ Float_t fMinPhi; // Least phi covered
+ Float_t fMaxPhi; // Largest phi covered
+ Float_t fParticles; // Number of particles
+ UShort_t fMethod; // Method use to get fParticles
+
+ ClassDef(AliFMDParticles,2) // Reconstructed # or particles in a eta,phi region
+};
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Utility class to help implement shape of the FMD modules
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMDPOLYGON_H
+# include "AliFMDPolygon.h"
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef ROOT_TString
+# include <TString.h>
+#endif
+#ifndef ROOT_TVector2
+# include <TVector2.h>
+#endif
+#ifndef ROOT_TCanvas
+# include <TCanvas.h>
+#endif
+#ifndef ROOT_TText
+# include <TText.h>
+#endif
+#ifndef ROOT_TGraph
+# include <TGraph.h>
+#endif
+#ifndef ROOT_TError
+# include <TError.h>
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDPolygon);
+
+//____________________________________________________________________
+AliFMDPolygon::AliFMDPolygon()
+ : fState(kUnknown)
+{}
+
+//____________________________________________________________________
+AliFMDPolygon::~AliFMDPolygon()
+{
+ fVerticies.Delete();
+}
+
+//____________________________________________________________________
+bool
+AliFMDPolygon::AddVertex(double x, double y)
+{
+ // Add points in order to the polygon.
+ TVector2* c = new TVector2(x,y);
+ return AddVertex(c);
+}
+//____________________________________________________________________
+bool
+AliFMDPolygon::AddVertex(TVector2* c)
+{
+ // Add points in order to the polygon.
+ //
+ // Checks if the addition of the vertex makes the alipolygon
+ // concave, and if it does, returns false. Note, that the check
+ // isn't performed until at least 3 verticies have already been
+ // added to the alipolygon (a triangle is always convex).
+ if (!c) return false;
+ if (fVerticies.GetEntries() >= 3) {
+ if (!IsOnLeftHand(c, fVerticies.GetEntries()-2,
+ fVerticies.GetEntries()-1)) {
+ Error("AliFMDPolygon::AddVertex",
+ "Adding vertex (%f,%f) makes alipolygon concave",
+ c->X(), c->Y());
+ return false;
+ }
+ }
+ fState = kUnknown;
+ fVerticies.AddAtAndExpand(c, fVerticies.GetEntries());
+ return true;
+}
+
+//____________________________________________________________________
+const TVector2&
+AliFMDPolygon::GetVertex(size_t i) const
+{
+ // Get one of the verticies
+ if (i > size_t(fVerticies.GetEntries()))
+ Fatal("AliFMDPolygon::GetVertex", "Index %d out of range [0,%d]",
+ i, fVerticies.GetEntries());
+ return *(static_cast<TVector2*>(fVerticies.At(i)));
+}
+
+//____________________________________________________________________
+bool
+AliFMDPolygon::Contains(const TVector2* c) const
+{
+ /* This function checks if a point is inside the polygon. It does
+ * that by looping over the segments of the polygon, and decides
+ * wether the point is on the left-hand-side (LHS) of the segment.
+ *
+ * Suppose we had the polygon and point
+ *
+ * 2 x----x 1
+ * / \\
+ * 3 x P x 0
+ * \\ /
+ * 4 x----x 5
+ *
+ * Then, P is on LHS of the segment 0->1, 1->2, ..., and 5->0, and
+ * so inside the polygon.
+ *
+ * Suppose instead the point was like
+ *
+ * 2 x----x 1
+ * / \\ P
+ * 3 x x 0
+ * \\ /
+ * 4 x----x 5
+ *
+ * Then it would still be on the LHS of the segments 1->2, 2->3,
+ * 3->4, 4->5, but on the right-hand-side of 5->0, and 0->1 and
+ * hence outside the polygon.
+ */
+ if (!c) return kFALSE;
+ if (fState == kUnknown) fState = (ConvexCheck() ? kConvex : kConcave);
+ if (fState == kConcave) return false;
+ size_t n = fVerticies.GetEntries();
+ for (size_t i = 0; i < n; ++i)
+ if (!IsOnLeftHand(c, i, (i + 1) % n))
+ // If point is on the left hand side of the segment, it's
+ // outside the polygon.
+ return false;
+ return true;
+}
+
+//____________________________________________________________________
+bool
+AliFMDPolygon::Contains(double x, double y) const
+{
+ TVector2 c(x,y);
+ return Contains(&c);
+}
+
+//____________________________________________________________________
+bool
+AliFMDPolygon::ConvexCheck() const
+{
+ /*
+ * This member function loops through the verticies, and checks if
+ * the next-to-next vertex is in between the current vertex and the
+ * next vertex.
+ *
+ * Suppose we have the polygon
+ *
+ * 2 x----x 1
+ * / \\
+ * 3 x x 0
+ * \\ /
+ * 4 x----x 5
+ *
+ * Then the vertex 2 is on the left-hand-side (LHS) of the segment
+ * 0->1, 3 is on the LHS of 1->2, ..., and 0 is on the RHS of 4->5,
+ * and so the polygon is convex.
+ *
+ * If we had a polygon like
+ *
+ * 2 x----x 1
+ * \\ \\
+ * 3 x x 0
+ * / /
+ * 4 x----x 5
+ *
+ * Then, the vertex 4 is NOT on the LHS of the segment 2->3, and so
+ * the polygon is NOT convex.
+ */
+ size_t n = fVerticies.GetEntries();
+ // A triangle is always convex.
+ if (n <= 3) return true;
+ for (size_t i = 0; i < n; i++) {
+ // Get the next, and next-to-next indicies, taking care to go
+ // around the polygon.
+ size_t j = (i + 1) % n;
+ size_t k = (i + 2) % n;
+ // Check The next-to-next vertex is on the LHS of the current
+ // vertex and the next vertex
+ if (!IsOnLeftHand(static_cast<TVector2*>(fVerticies.At(k)), i, j)) {
+ Error("AliFMDPolygon::ConvexCheck",
+ "AliFMDPolygon is concave at segment %d -> %d" , i, j);
+ return false;
+ }
+ }
+ return true;
+}
+
+//____________________________________________________________________
+bool
+AliFMDPolygon::IsOnLeftHand(const TVector2* c, size_t i1, size_t i2) const
+{
+ /* Check if a point is on the left-hand-side (LHS) or
+ * right-hand-side (RHS) of the segment defined by the two indicies.
+ *
+ * Suppose we have the segment and point
+ *
+ * 1 x
+ * \\ P
+ * x 0
+ *
+ * Then, we define the vectors
+ *
+ * v: 0->P
+ * u: perpendicular to 1->0
+ *
+ * The dot product of u and v is >= 0, meaning that the
+ * angle between the two vectors is in [0,pi], and so P is on the
+ * RHS of the segment
+ *
+ * Suppose we had
+ *
+ * 1 x
+ * P \\
+ * x 0
+ *
+ * And defining the vectors u,v as above. In this case the dot
+ * product is less than 0, meaning the angle between u,v is in
+ * (pi,2pi], and so P is on the LHS of the segment
+ */
+ if (!c) return false;
+ const TVector2& v1 = GetVertex(i1);
+ const TVector2& v2 = GetVertex(i2);
+ double dot = ( (c->X() - v1.X()) * (v2.Y() - v1.Y())
+ - (c->Y() - v1.Y()) * (v2.X() - v1.X()));
+ return (dot < 0 ? true : false);
+}
+
+//____________________________________________________________________
+void
+AliFMDPolygon::Clear(Option_t*)
+{
+ fState = kUnknown;
+ fVerticies.Delete();
+ // fVerticies.Resize(0);
+}
+
+//____________________________________________________________________
+void
+AliFMDPolygon::Draw(const char* option, const char* name) const
+{
+ size_t n = fVerticies.GetEntries();
+ TGraph* g = new TGraph(n+1);
+ if (name) g->SetName(name);
+ g->SetMarkerStyle(20);
+ for (size_t i = 0; i < n; i++) {
+ const TVector2& v = GetVertex(i);
+ g->SetPoint(i, v.X(), v.Y());
+ }
+ const TVector2& v = GetVertex(0);
+ g->SetPoint(n, v.X(), v.Y());
+ g->Draw(option);
+ TString opt(option);
+ if (!opt.Contains("p", TString::kIgnoreCase))
+ return;
+ for (size_t i = 0; i < n; i++) {
+ const TVector2& v = GetVertex(i);
+ TText* t = new TText(v.X(), v.Y(), Form("%d", i));
+ t->Draw();
+ }
+}
+
+//____________________________________________________________________
+//
+// EOf
+//
--- /dev/null
+// -*- mode: C++ -*-
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice
+ */
+#ifndef ALIFMDPOLYGON_H
+#define ALIFMDPOLYGON_H
+#ifndef ROOT_TVector2
+# include <TVector2.h>
+#endif
+#ifndef ROOT_TObjArray
+# include <TObjArray.h>
+#endif
+
+class AliFMDPolygon : public TObject
+{
+private:
+ enum {
+ kUnknown,
+ kConvex,
+ kConcave
+ };
+ mutable Int_t fState;
+ // List of coordinates
+ TObjArray fVerticies;
+ // Force convexity check
+ bool ConvexCheck() const;
+ // Check if a point is at the right-hand side of a segment
+ bool IsOnLeftHand(const TVector2* c, size_t i1, size_t i2) const;
+public:
+ // Construct a alipolygon with N sides
+ AliFMDPolygon();
+ virtual ~AliFMDPolygon();
+
+ // Clear the polygon
+ void Clear(Option_t* option="");
+
+ // Add a vertex
+ bool AddVertex(TVector2* c);
+ bool AddVertex(double x, double y);
+
+ // Get a vertex point
+ const TVector2& GetVertex(size_t i) const;
+
+ // Check if a point is inside the polygon
+ bool Contains(const TVector2* c) const;
+ bool Contains(double x, double y) const;
+
+ // Get the number of verticies
+ size_t GetNVerticies() const { return fVerticies.GetEntries(); }
+ // Get the coordinates
+ const TObjArray& GetVerticies() const { return fVerticies; }
+
+ void Draw(const char* option="PL", const char* name=0) const;
+
+ ClassDef(AliFMDPolygon,1) // Polygon parameters
+};
+
+#endif
+//
+// EOF
+//
+
+
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////
+//
+// Buffer to read RAW ALTRO FMD format from a AliRawReader
+//
+// Currently, I had to overload the Next member function and introduce
+// my own members fMyData, fMyPosition, fMyCount, and fMyBunchLength.
+// The reason is, that we can use the fMyCount to determine the
+// sampling rate used in the ALTRO. However,
+// AliAltroBuffer::fCount is private, so we can not access it.
+//
+// If it wasn't I'd implement Next as
+//
+// Bool_t
+// AliFMDRawStreamer::Next()
+// {
+// if (AliAltroRawStreamer::Next()) {
+// if (fPrevPad != fPad)
+// fSampleRate = (fCount - 2) / 128;
+// return kTRUE;
+// }
+// return kFALSE;
+// }
+//
+//////////////////////////////////////////////////////////////////////
+#ifndef ALIFMDRAWSTREAM_H
+# include "AliFMDRawStream.h"
+#endif
+#ifndef ALIRAWREADER_H
+# include "AliRawReader.h"
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDRawStream);
+
+//____________________________________________________________________
+AliFMDRawStream::AliFMDRawStream(AliRawReader* reader)
+ : AliAltroRawStream(reader),
+ // fMyData(0),
+ // fMyPosition(0),
+ // fMyCount(0),
+ // fMyBunchLength(0),
+ fPrevTime(-1)
+{}
+
+
+
+//_____________________________________________________________________________
+Bool_t
+AliFMDRawStream::Next()
+{
+ // read the next raw digit
+ // returns kFALSE if there is no digit left
+ fPrevTime = fTime;
+ if (AliAltroRawStream::Next()) {
+ if (fPrevPad != fPad) {
+ fSampleRate = fTimeBunch / 128;
+#if 1
+ std::cout << "Setting Sample rate to (" << fTimeBunch << "/"
+ << 128 << "=" << fSampleRate << std::endl;
+#endif
+ }
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+#if 0
+//_____________________________________________________________________________
+Bool_t
+AliFMDRawStream::Next()
+{
+ // read the next raw digit
+ // returns kFALSE if there is no digit left
+ fPrevSector = fSector;
+ fPrevRow = fRow;
+ fPrevPad = fPad;
+ fPrevTime = fTime;
+
+ while (fMyCount == 0) { // next trailer
+ if (fMyPosition <= 0) { // next payload
+ do {
+ if (!fRawReader->ReadNextData(fMyData)) return kFALSE;
+ } while (fRawReader->GetDataSize() == 0);
+
+ fMyPosition = (fRawReader->GetDataSize() * 8) / 10;
+ while (Get10BitWord(fMyData, fMyPosition-1) == 0x2AA) fMyPosition--;
+ }
+
+ if (fMyPosition > 0) {
+ // read the trailer
+ if (fMyPosition <= 4) {
+ Error("Next", "could not read trailer");
+ return kFALSE;
+ }
+ fSector = Get10BitWord(fMyData, --fMyPosition);
+ fRow = Get10BitWord(fMyData, --fMyPosition);
+ fPad = Get10BitWord(fMyData, --fMyPosition);
+ fMyCount = Get10BitWord(fMyData, --fMyPosition);
+
+ fMyPosition -= (4 - (fMyCount % 4)) % 4; // skip fill words
+ fMyBunchLength = 0;
+
+ // Set the sample rate, based on the number of samples in the
+ // channel.
+ fSampleRate = (fMyCount - 2) / 128;
+#if 0
+ std::cout << "Setting Sample rate to (" << fMyCount << " - 2)/"
+ << 128 << "=" << fSampleRate << std::endl;
+#endif
+ }
+ }
+
+ if (fMyBunchLength == 0) {
+ if (fMyPosition <= 0) {
+ Error("Next", "could not read bunch length");
+ return kFALSE;
+ }
+ fMyBunchLength = Get10BitWord(fMyData, --fMyPosition) - 2;
+ fMyCount--;
+
+
+ if (fMyPosition <= 0) {
+ Error("Next", "could not read time bin");
+ return kFALSE;
+ }
+ fTime = Get10BitWord(fMyData, --fMyPosition);
+ fMyCount--;
+ } else {
+ fTime--;
+ }
+
+ if (fMyPosition <= 0) {
+ Error("Next", "could not read sample amplitude");
+ return kFALSE;
+ }
+ fSignal = Get10BitWord(fMyData, --fMyPosition);
+ fMyCount--;
+ fMyBunchLength--;
+
+ return kTRUE;
+}
+
+//_____________________________________________________________________________
+UShort_t
+AliFMDRawStream::Get10BitWord(UChar_t* buffer, Int_t position) const
+{
+// return a word in a 10 bit array as an UShort_t
+
+ Int_t iBit = position * 10;
+ Int_t iByte = iBit / 8;
+ Int_t shift = iBit % 8;
+// return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF;
+
+ // recalculate the byte numbers and the shift because
+ // the raw data is written as integers where the high bits are filled first
+ // -> little endian is assumed here !
+ Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
+ iByte++;
+ Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4);
+ shift = 6 - shift;
+ return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF;
+}
+#endif
+//_____________________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+//
+//
+#ifndef ALIFMDRAWSTREAM_H
+#define ALIFMDRAWSTREAM_H
+
+#ifndef ALIALTRORAWSTREAM_H
+# include <AliAltroRawStream.h>
+#endif
+
+
+// TPC to FMD translations
+//
+// TPC FMD
+// ----------+-----------
+// pad+time | strip
+// row | sector
+// sector | ring
+//
+class AliFMDRawStream : public AliAltroRawStream
+{
+private:
+ UShort_t fSampleRate; // # of ALTRO samples per VA1_ALICE clock
+ // UChar_t* fMyData;
+ // Int_t fMyPosition;
+ // Int_t fMyCount;
+ // Int_t fMyBunchLength;
+ Int_t fPrevTime;
+protected:
+ // UShort_t Get10BitWord(UChar_t* buffer, Int_t position) const;
+public:
+ AliFMDRawStream(AliRawReader* reader);
+
+ Short_t Sector() const { return fRow; }
+ Char_t Ring() const { return (fSector == 0 ? 'I' : 'O'); }
+ Short_t Strip() const { return fPad + fTime / fSampleRate; }
+ Short_t PrevSector() const { return fPrevRow; }
+ Char_t PrevRing() const { return (fPrevSector == 0 ? 'I' : 'O'); }
+ Short_t PrevStrip() const { return fPrevPad + fPrevTime/fSampleRate; }
+
+ Bool_t IsNewRing() const { return (fSector != fPrevSector); }
+ Bool_t IsNewSector() const { return (fRow != fPrevRow) || IsNewRing(); }
+ Bool_t IsNewStrip() const { return(Strip() != PrevStrip())||IsNewSector();}
+
+ Short_t Count() const { return fSignal; }
+ Short_t SampleRate() const { return fSampleRate; }
+
+ virtual Bool_t Next();
+
+ ClassDef(AliFMDRawStream, 0) // Read raw FMD Altro data
+};
+
+#endif
+++ /dev/null
-
- //////////////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity Detector have to be reconstructed //
-// number of particles in fixed pseudorapidity interval from //
-// fNumOfMinRing to fNumOfMaxRing //
-// and phi interval //
-// from fNumOfMinSector to fNumOfMaxSector //
- //////////////////////////////////////////////////////////////////////////////
-
-
-#include "AliFMDReconstParticles.h"
-
-ClassImp(AliFMDReconstParticles)
-
-AliFMDReconstParticles::AliFMDReconstParticles()
-{
- fNumOfDet=0;
- fNumOfMinSector=0;
- fNumOfMaxSector=0;
- fNumOfMinRing=0;
- fNumOfMaxRing=0;
- fNumOfReconstParticles=0;
-}
-AliFMDReconstParticles::AliFMDReconstParticles(Int_t *RecParticles)
-{
- fNumOfDet=RecParticles[0];
- fNumOfMinSector=RecParticles[1];
- fNumOfMaxSector=RecParticles[2];
- fNumOfMinRing=RecParticles[3];
- fNumOfMaxRing=RecParticles[4];
- fNumOfReconstParticles=RecParticles[5];
-}
+++ /dev/null
-#ifndef AliFMDReconstParticles_h
-#define AliFMDReconstParticles_h
-
-#include <TObject.h>
-class TClonesArray;
-
-class AliFMDReconstParticles: public TObject
-{
- /*
- Reconstracted Particles Class:
- has number of reconstructed particles in
- sectors from NumOfMinSector to NumberOfMaxSector()
- rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
- */
-
-
- public:
- AliFMDReconstParticles();
- AliFMDReconstParticles (Int_t *RecParticles);
- virtual ~AliFMDReconstParticles(){};
- Int_t GetVolume() const {return fNumOfDet;} //number of volume
- Int_t GetNumberOfMinSector() const {return fNumOfMinSector;} //number of min sector
- Int_t GetNumberOfMaxSector() const {return fNumOfMaxSector;} // number of max sector
- Int_t GetNumberOfMinRing() const {return fNumOfMinRing;} //number of min ring
- Int_t GetNumberOfMaxRing() const {return fNumOfMaxRing;} //number of max ring
- Int_t GetNumberOfReconstParticles()const {return fNumOfReconstParticles;} //number of reconstructed particles
- private:
- Int_t fNumOfDet; //Number of FMD disk;
- Int_t fNumOfMinSector; //Number of min sector
- Int_t fNumOfMaxSector; //Number of max sector
- Int_t fNumOfMinRing; //Number of min ring
- Int_t fNumOfMaxRing; //Number of max ring
- Int_t fNumOfReconstParticles; //Number of reconstructed particles
-
- ClassDef(AliFMDReconstParticles,2)
-};
-#endif
* provided "as is" without express or implied warranty. *
**************************************************************************/
-//_________________________________________________________________________
-// This is a class that constructs ReconstParticles (reconstructed particles)
-// out of Digits
+//____________________________________________________________________
+// This is a class that constructs ReconstParticles (reconstructed
+// particles) out of Digits
+//
+//
+// This class reads either digits from a TClonesArray or raw data from
+// a DDL file (or similar), and stores the read ADC counts in an
+// internal cache (fAdcs).
+//
+// From the cached values it then calculates the number of particles
+// that hit a region of the FMDs, as specified by the user.
+//
+// The reconstruction can be done in two ways: Either via counting the
+// number of empty strips (Poisson method), or by converting the ADC
+// signal to an energy deposition, and then dividing by the typical
+// energy loss of a particle.
+//
+// Currently, this class only reads the digits from a TClonesArray,
+// and the Poission method for reconstruction.
+//
//
//-- Authors: Evgeny Karpechev(INR) and Alla Maevsksia
-//////////////////////////////////////////////////////////////////////////////
+// Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+//
+//
+//____________________________________________________________________
-// --- ROOT system ---
-#include "TTask.h"
-#include "TTree.h"
-#include "TSystem.h"
-#include "TFile.h"
-#include "TROOT.h"
-#include "TFolder.h"
-#include "TH2F.h"
-#include "TRandom.h"
+#ifndef ALIFMD_H
+# include "AliFMD.h"
+#endif
+#ifndef ALIFMDDIGIT_H
+# include "AliFMDDigit.h"
+#endif
+#ifndef ALIFMDPARTICLES_H
+# include "AliFMDParticles.h"
+#endif
+#ifndef ALIFMDRECONSTRUCTOR_H
+# include "AliFMDReconstructor.h"
+#endif
+#ifndef ALIALTROBUFFER_H
+# include "AliAltroBuffer.h"
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef ALIRUN_H
+# include "AliRun.h"
+#endif
+#ifndef ALIRUNLOADER_H
+# include "AliRunLoader.h"
+#endif
+#ifndef ALILOADER_H
+# include "AliLoader.h"
+#endif
+#ifndef ALIHEADER_H
+# include "AliHeader.h"
+#endif
+#ifndef ALIGENEVENTHEADER_H
+# include "AliGenEventHeader.h"
+#endif
+#ifndef ALIRAWREADERFILE_H
+# include "AliRawReaderFile.h"
+#endif
+#ifndef ALIFMDRAWSTREAM_H
+# include "AliFMDRawStream.h"
+#endif
+
+//____________________________________________________________________
+ClassImp(AliFMDReconstructor);
-// --- Standard library ---
-#include <stdlib.h>
-#include <Riostream.h>
+//____________________________________________________________________
+AliFMDReconstructor::AliFMDReconstructor()
+ : AliReconstructor(),
+ fAdcs(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips),
+ fDeltaEta(0),
+ fDeltaPhi(0),
+ fThreshold(0),
+ fPedestal(0),
+ fPedestalWidth(0)
+{
+ SetDeltaEta();
+ SetDeltaPhi();
+ SetThreshold();
+ SetPedestal();
+
+ fParticles = new TClonesArray("AliFMDParticles", 1000);
+ fFMDLoader = 0;
+ fRunLoader = 0;
+ fFMD = 0;
+}
+
+//____________________________________________________________________
+void
+AliFMDReconstructor::SetPedestal(Float_t mean, Float_t width)
+{
+ // Set the pedestal, and pedestal width
+ fPedestal = mean;
+ fPedestalWidth = width;
+}
+
+//____________________________________________________________________
+void
+AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader,
+ AliRawReader* rawReader) const
+{
+ // Collects all digits in the same active volume into number of
+ // particles
+ //
+ // Reconstruct number of particles in given group of pads for given
+ // FMDvolume determined by numberOfVolume,
+ // numberOfMinSector, numberOfMaxSector, numberOfMinRing,
+ // numberOgMaxRing
+ //
+ // The reconstruction method is choosen based on the number of empty
+ // strips.
+ fParticles->Clear();
+ if (!runLoader) {
+ Error("Exec","Run Loader loader is NULL - Session not opened");
+ return;
+ }
+ fRunLoader = runLoader;
+ fFMDLoader = runLoader->GetLoader("FMDLoader");
+ if (!fFMDLoader)
+ Fatal("AliFMDReconstructor","Can not find FMD (loader) "
+ "in specified event");
-// --- AliRoot header files ---
+ // Get the AliRun object
+ if (!fRunLoader->GetAliRun()) fRunLoader->LoadgAlice();
+
+ // Get the AliFMD object
+ fFMD = static_cast<AliFMD*>(fRunLoader->GetAliRun()->GetDetector("FMD"));
+ if (!fFMD) {
+ AliError("Can not get FMD from gAlice");
+ return;
+ }
+ fFMDLoader->LoadRecPoints("RECREATE");
-#include "AliRunLoader.h"
-#include "AliLoader.h"
+ if (!fRunLoader->TreeE()) fRunLoader->LoadHeader();
-#include "AliFMDdigit.h"
-#include "AliFMDReconstParticles.h"
-#include "AliFMDReconstructor.h"
-#include "AliRun.h"
-#include "AliConfig.h"
-#include "AliHeader.h"
-#include "AliGenEventHeader.h"
+ TClonesArray* digits = fFMD->Digits();
+ if (rawReader) {
+ Int_t event = 0;
+ while (rawReader->NextEvent()) {
+ ProcessEvent(event, rawReader, digits);
+ event++;
+ }
+ }
+ else {
+ Int_t nEvents= Int_t(fRunLoader->TreeE()->GetEntries());
+ for(Int_t event = 0; event < nEvents; event++)
+ ProcessEvent(event, 0, digits);
+ }
-ClassImp(AliFMDReconstructor)
-
-//____________________________________________________________________________
+ fFMDLoader->UnloadRecPoints();
+ fFMDLoader = 0;
+ fRunLoader = 0;
+ fFMD = 0;
+}
-void AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader) const
+//____________________________________________________________________
+void
+AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader) const
{
- //Collects all digits in the same active volume into number of particles
- /*
- Reconstruct number of particles
- in given group of pads for given FMDvolume
- determine by numberOfVolume ,
- numberOfMinSector,numberOfMaxSector,
- numberOfMinRing, numberOgMaxRing
- Reconstructor method choose dependence on number of empty pads
- */
-
-
-#ifdef DEBUG
- Info("Exec ","Start");
-#endif
+ // Collects all digits in the same active volume into number of
+ // particles
+ //
+ // Reconstruct number of particles in given group of pads for given
+ // FMDvolume determined by numberOfVolume,
+ // numberOfMinSector, numberOfMaxSector, numberOfMinRing,
+ // numberOgMaxRing
+ //
+ // The reconstruction method is choosen based on the number of empty
+ // strips.
+ Reconstruct(runLoader, 0);
+}
+
+
+//____________________________________________________________________
+void
+AliFMDReconstructor::ProcessEvent(Int_t event,
+ AliRawReader* reader,
+ TClonesArray* digits) const
+{
+ fRunLoader->GetEvent(event) ;
+ //event z-vertex for correction eta-rad dependence
+ AliHeader *header = fRunLoader->GetHeader();
+ if (!header)
+ Warning("ProcessEvent", "no AliHeader found!");
+ AliGenEventHeader* genHeader = (header ? header->GenEventHeader() : 0);
- Int_t const knumVolumes=5;
- Int_t padADC;
- Float_t eta, etain,etaout,rad,theta;
- Int_t ivol, iSector, iRing;
- Float_t rin[5]={4.2,15.4,4.2,15.4,4.2};
- Float_t rout[5]={17.4,28.4,17.4,28.4,17.4};
- Float_t z[5]={-62.8, -75.2, 83.4, 75.2, 340.};
- Int_t numberOfRings[5]={512,256,512,256,512};
- Int_t numberOfSectors[5]= {20,40,20,40,20};
- Int_t numberOfEtaIntervals[5];
- // number of ring for boundary 0.1 eta
+ // Get the Z--coordinate from the event header
+ TArrayF o(3);
+ if (genHeader) genHeader->PrimaryVertex(o);
+ Float_t zVertex = o.At(2);
+ // If the recontruction tree isn't loaded, load it
+ if(fFMDLoader->TreeR()==0) fFMDLoader->MakeTree("R");
- if (runLoader == 0x0)
- {
- Error("Exec","Run Loader loader is NULL - Session not opened");
- return;
- }
-
- AliLoader* plFMD = runLoader->GetLoader("FMDLoader");
- if (plFMD == 0x0)
- {
- Fatal("AliFMDReconstructor","Can not find FMD (loader) in specified event");
- return;//never reached
- }
-
- if (!runLoader->GetAliRun()) runLoader->LoadgAlice();
- if (!runLoader->TreeE()) runLoader->LoadHeader();
-
- TDirectory* cwd = gDirectory;
- gDirectory = 0x0;
- Text_t buf1[20];
- TH2F* hTotal[10];
- for (Int_t j=1; j<=5; j++){
- sprintf(buf1,"hTotal%d",j);
+ //Make branches to hold the reconstructed particles
+ const Int_t kBufferSize = 16000;
+ fFMDLoader->TreeR()->Branch("FMD", &fParticles, kBufferSize);
+
+ // Load or recreate the digits
+ if (fFMDLoader->LoadDigits((reader ? "UPDATE" : "READ"))) {
+ if (!reader) {
+ Error("Exec","Error occured while loading digits. Exiting.");
+ return;
+ }
- hTotal[j] = new TH2F(buf1," Number of primary particles ",
- numberOfSectors[j-1],1,numberOfSectors[j-1],
- numberOfRings[j-1],1,numberOfRings[j-1]);
- }
- gDirectory = cwd;
-
- plFMD->LoadRecPoints("RECREATE");
- TClonesArray* reconParticles = new TClonesArray("AliFMDReconstParticles");
- TClonesArray* digits = new TClonesArray("AliFMDdigit");
-
- Int_t retval=0;
- Int_t nevents=Int_t (runLoader->TreeE()->GetEntries());
-#ifdef DEBUG
- cout<<" nevents "<<nevents<<endl;
-#endif
- for(Int_t ievent=0;ievent<nevents;ievent++)
- {
-#ifdef DEBUG
- cout<<" *** event "<<ievent<<endl;
-#endif
- runLoader->GetEvent(ievent) ;
- //event z-vertex for correction eta-rad dependence
- AliHeader *header = runLoader->GetHeader();
- AliGenEventHeader* genHeader = header->GenEventHeader();
- TArrayF *o = new TArrayF(3);
- if (genHeader) genHeader->PrimaryVertex(*o);
- Float_t zVertex=o->At(2);
-
- for (Int_t i=0; i<5; i++)
- hTotal[i+1]->Reset();
-
- retval = plFMD->LoadDigits("READ");
- if (retval)
- {
- Error("Exec","Error occured while loading digits. Exiting.");
- return;
+ }
+ // Get the digits tree
+ TTree* digitTree = fFMDLoader->TreeD();
+ if (!digitTree) {
+ if (!reader) {
+ Error("Exec","Can not get Tree with Digits. "
+ "Nothing to reconstruct - Exiting");
+ return;
+ }
+ fFMDLoader->MakeTree("D");
+ digitTree = fFMDLoader->TreeD();
+
+ }
+ // Get the FMD branch holding the digits.
+ TBranch *digitBranch = digitTree->GetBranch("FMD");
+ if (!digitBranch) {
+ if (!reader) {
+ Error("Exec", "No digit branch for the FMD found");
+ return;
+ }
+ fFMD->MakeBranchInTree(digitTree, fFMD->GetName(), &(digits), 4000, 0);
+ }
+ if (!reader) digitBranch->SetAddress(&digits);
+
+ fEmptyStrips = 0;
+ fTotalStrips = 0;
+ Bool_t ok = kFALSE;
+ if (reader) ok = ReadAdcs(reader);
+ else if (digits) ok = ReadAdcs(digits);
+ if (!ok) return;
+
+ ReconstructFromCache(zVertex);
+
+ if (reader) {
+ digitTree->Fill();
+ fFMDLoader->WriteDigits("OVERWRITE");
+ }
+ fFMDLoader->UnloadDigits();
+ fFMDLoader->TreeR()->Reset();
+ fFMDLoader->TreeR()->Fill();
+ fFMDLoader->WriteRecPoints("OVERWRITE");
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDReconstructor::ReadAdcs(TClonesArray* digits) const
+{
+ AliDebug(10, "Reading ADCs from Digits array");
+ // read Digits, and reconstruct the particles
+ if (!fFMDLoader->TreeD()->GetEvent(0)) return kFALSE;
+
+ // Reads the digits from the array, and fills up the cache (fAdcs)
+ fAdcs.Clear();
+ Int_t nDigits = digits->GetEntries();
+ for (Int_t digit = 0; digit < nDigits; digit++) {
+ AliFMDDigit* fmdDigit =
+ static_cast<AliFMDDigit*>(digits->UncheckedAt(digit));
+
+ ProcessDigit(fmdDigit);
+ } //digit loop
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDReconstructor::ReadAdcs(AliRawReader* reader) const
+{
+ AliDebug(10, "Reading ADCs from RawReader");
+ // Reads the digits from a RAW data
+ fAdcs.Clear();
+ // reader->Reset();
+
+ if (!reader->ReadHeader()) {
+ Error("ReadAdcs", "Couldn't read header");
+ return kFALSE;
+ }
+
+ // Use AliAltroRawStream to read the ALTRO format. No need to
+ // reinvent the wheel :-)
+ AliFMDRawStream input(reader);
+ // Select FMD DDL's
+ reader->Select(AliFMD::kBaseDDL >> 8);
+
+ Int_t oldDDL = -1;
+ Int_t count = 0;
+ UShort_t detector = 1; // Must be one here
+ UShort_t oldDetector = 0;
+ // Loop over data in file
+ Bool_t next = kTRUE;
+
+ // local Cache
+ TArrayI counts(10);
+ counts.Reset(-1);
+ Int_t offset = 0;
+
+ while (next) {
+ next = input.Next();
+
+
+ count++;
+ Int_t ddl = reader->GetDDLID();
+ if (ddl != oldDDL
+ || input.IsNewStrip()
+ || !next) {
+ // Make a new digit, if we have some data!
+ if (counts[0] >= 0) {
+ // Got a new strip.
+ AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
+ "(current: FMD%d%c[%2d,%3d])",
+ oldDetector, input.PrevRing(),
+ input.PrevSector() , input.PrevStrip(),
+ detector , input.Ring(), input.Sector(),
+ input.Strip()));
+ fFMD->AddDigit(oldDetector,
+ input.PrevRing(),
+ input.PrevSector(),
+ input.PrevStrip(),
+ counts[0], counts[1], counts[2]);
+ AliFMDDigit* digit =
+ static_cast<AliFMDDigit*>(fFMD->Digits()->
+ UncheckedAt(fFMD->GetNdigits()-1));
+ ProcessDigit(digit);
+ }
+
+ if (!next) {
+ AliDebug(10, Form("Read %d channels for FMD%d",
+ count + 1, detector));
+ break;
+ }
+
+
+ // If we got a new DDL, it means we have a new detector.
+ if (ddl != oldDDL) {
+ if (detector != 0)
+ AliDebug(10, Form("Read %d channels for FMD%d",
+ count + 1, detector));
+ // Reset counts, and update the DDL cache
+ count = 0;
+ oldDDL = ddl;
+ // Check that we're processing a FMD detector
+ Int_t detId = reader->GetDetectorID();
+ if (detId != (AliFMD::kBaseDDL >> 8)) {
+ Error("ReadAdcs", "Detector ID %d != %d",
+ detId, (AliFMD::kBaseDDL >> 8));
+ break;
}
-
- TTree* treeD = plFMD->TreeD();
- if (treeD == 0x0)
- {
- Error("Exec","Can not get Tree with Digits. Nothing to reconstruct - Exiting");
- return;
+ // Figure out what detector we're deling with
+ oldDetector = detector;
+ switch (ddl) {
+ case 0: detector = 1; break;
+ case 1: detector = 2; break;
+ case 2: detector = 3; break;
+ default:
+ Error("ReadAdcs", "Unknown DDL 0x%x for FMD", ddl);
+ return kFALSE;
}
-
- TBranch *brDigits=0;
-
- brDigits=treeD->GetBranch("FMD");
-
- if (brDigits) {
- brDigits->SetAddress(&digits);
- }else{
- cerr<<"EXEC Branch FMD digits not found"<<endl;
- return;
- }
-
- if(plFMD->TreeR()==0) plFMD->MakeTree("R");
+ AliDebug(10, Form("Reading ADCs for 0x%x - That is FMD%d",
+ reader->GetEquipmentId(), detector));
+ }
+ counts.Reset(-1);
+ offset = 0;
+ }
+
+ counts[offset] = input.Count();
+ offset++;
+
+ AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
+ detector, input.Ring(), input.Sector(),
+ input.Strip(), input.Count()));
+ oldDetector = detector;
+ }
+ return kTRUE;
+}
- //Make branches
- const Int_t kBufferSize = 16000;
- plFMD->TreeR()->Branch("FMD", &reconParticles, kBufferSize);
+//____________________________________________________________________
+void
+AliFMDReconstructor::ProcessDigit(AliFMDDigit* digit) const
+{
+ // Process a digit. Derived classes can overload this member
+ // function to do stuff to the digit. However, it should write the
+ // ADC count to the internal cache
+ //
+ // fAdcs(detector - 1, ring, sector, strip) = counts;
+ //
+ // In this implementation, we count the number of strips below
+ // threshold. This we do to later choose what kind of
+ // reconstruction algorithm we'd like to use.
+ //
+ UShort_t detector = digit->Detector();
+ Char_t ring = digit->Ring();
+ UShort_t sector = digit->Sector();
+ UShort_t strip = digit->Strip();
+
+ UShort_t counts = SubtractPedestal(digit);
+
+ fAdcs(detector - 1, ring, sector, strip) = counts;
+ if (counts < fThreshold) fEmptyStrips++;
+ fTotalStrips++;
+}
-
- Int_t zeroADC=6;
- // read Digits
- AliFMDdigit *fmdDigit;
- if (plFMD->TreeD()->GetEvent(0))
- {
- Int_t nDigits=digits->GetEntries();
- Int_t recParticles[6];
- Int_t nRecPart=0 ;
- Int_t zeroPads=0;
- Int_t numberOfPads=0;
- Int_t pedestal;
- Float_t channelWidth=(22400*50)/1024;
- for (Int_t digit=0;digit<nDigits;digit++)
- {
- fmdDigit=(AliFMDdigit*)digits->UncheckedAt(digit);
- ivol=fmdDigit->Volume();
- iSector=fmdDigit->NumberOfSector();
- iRing=fmdDigit->NumberOfRing();
- pedestal=Int_t(gRandom->Gaus(500,250));
- padADC= fmdDigit->ADCsignal()
- -Int_t(Float_t(pedestal)/channelWidth);
- if (padADC<0) padADC=0;
- hTotal[ivol]->Fill(iSector,iRing,padADC);
- } //digit loop
-
- //reconstruct multiplicity in 0.1 eta according Poisson distribution
-
- Int_t rmin=0; Int_t rmax=0;
- Int_t smin=0; Int_t smax=0;
- for (ivol=0; ivol<knumVolumes; ivol++)
- {
- Float_t ring2number=Float_t (numberOfRings[ivol])/
- (rout[ivol]-rin[ivol]);
- Float_t realZ=zVertex+z[ivol];
- theta=TMath::ATan(rout[ivol]/TMath::Abs(realZ));
- etain = - TMath::Log( TMath::Tan(theta/2.));
- theta=TMath::ATan(rin[ivol]/TMath::Abs(realZ));
- etaout=- TMath::Log( TMath::Tan(theta/2.));
- numberOfEtaIntervals[ivol]=Int_t((etaout-etain)*10)-1;
- eta=etain;
- for (Int_t e1=0;e1<=numberOfEtaIntervals[ivol];e1++)
- {
- theta = 2.*TMath::ATan (TMath::Exp (-eta));
- Float_t radmin = TMath::Abs(realZ) * (TMath::Tan (theta));
- rmax= Int_t ( (radmin-rin[ivol])*ring2number+0.5);
- eta=eta+0.1;
- theta = 2.*TMath::ATan (TMath::Exp (-eta));
- rad = TMath::Abs(realZ) * (TMath::Tan (theta));
- rmin=Int_t( (rad-rin[ivol])*ring2number+0.5);
-
- zeroPads=0;
- smin=0;
- smax=numberOfSectors[ivol];
- numberOfPads=(rmax-rmin)*(smax-smin);
- for (Int_t iring=rmin; iring<rmax; iring++)
- {
- for
- (Int_t isector=0;
- isector<numberOfSectors[ivol];
- isector++)
- {
- if(hTotal[ivol+1]->GetBinContent(isector+1,iring+1)
- <zeroADC) zeroPads++;}
-
- } //ring
- Float_t numberOfPads=Float_t(smax-smin)*Float_t(rmax-rmin);
-
- Double_t lambda=-TMath::Log(Double_t(zeroPads)/numberOfPads);
- Int_t fRecon=Int_t (lambda*numberOfPads+0.5);
- recParticles[0]=ivol+1;
- recParticles[1]=smin;
- recParticles[2]=smax;
- recParticles[3]=rmin;
- recParticles[4]=rmax;
- recParticles[5]= fRecon;
- new((*reconParticles)[nRecPart++]) AliFMDReconstParticles(recParticles);
-
-
- } // eta
- } // volume
-
- }//if (plFMD->TreeD()->GetEvent(0))
- plFMD->TreeR()->Reset();
- plFMD->TreeR()->Fill();
- plFMD->WriteRecPoints("OVERWRITE");
- plFMD->UnloadDigits();
- } //event loop
- plFMD->UnloadRecPoints();
-#ifdef DEBUG
- Info(" Exec"," finished");
-#endif
- // delete hTotal[10];
+//____________________________________________________________________
+UShort_t
+AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
+{
+ // Member function to subtract the pedestal from a digit
+ // This implementation does nothing, but a derived class could over
+ // load this to subtract a pedestal that was given in a database or
+ // something like that.
+ Int_t counts =
+ TMath::Max(Int_t(digit->Count1() - fPedestal - 3 * fPedestalWidth), 0);
+ if (digit->Count2() >= 0)
+ counts +=
+ TMath::Max(Int_t(digit->Count2() - fPedestal - 3 * fPedestalWidth), 0);
+ if (digit->Count3() >= 0)
+ counts +=
+ TMath::Max(Int_t(digit->Count3() - fPedestal - 3 * fPedestalWidth), 0);
+
+ if (counts < 0) counts = 0;
+ return UShort_t(counts);
}
+//____________________________________________________________________
+void
+AliFMDReconstructor::ReconstructFromCache(Float_t zVertex) const
+{
+ // Based on the information in the cache, do the reconstruction.
+ Int_t nRecon = 0;
+ // Loop over the detectors
+ for (Int_t i = 1; i <= 3; i++) {
+ AliFMDSubDetector* sub = 0;
+ switch (i) {
+ case 1: sub = fFMD->GetFMD1(); break;
+ case 2: sub = fFMD->GetFMD2(); break;
+ case 3: sub = fFMD->GetFMD3(); break;
+ }
+ if (!sub) continue;
+
+ // Loop over the rings in the detector
+ for (Int_t j = 0; j < 2; j++) {
+ Float_t rZ = 0;
+ AliFMDRing* r = 0;
+ switch (j) {
+ case 0: r = sub->GetInner(); rZ = sub->GetInnerZ(); break;
+ case 1: r = sub->GetOuter(); rZ = sub->GetOuterZ(); break;
+ }
+ if (!r) continue;
+
+ // Calculate low/high theta and eta
+ // FIXME: Is this right?
+ Float_t realZ = zVertex + rZ;
+ Float_t thetaOut = TMath::ATan2(r->GetHighR(), realZ);
+ Float_t thetaIn = TMath::ATan2(r->GetLowR(), realZ);
+ Float_t etaOut = - TMath::Log(TMath::Tan(thetaOut / 2));
+ Float_t etaIn = - TMath::Log(TMath::Tan(thetaIn / 2));
+ if (TMath::Abs(etaOut) > TMath::Abs(etaIn)) {
+ Float_t tmp = etaIn;
+ etaIn = etaOut;
+ etaOut = tmp;
+ }
+
+ //-------------------------------------------------------------
+ //
+ // Here starts poisson method
+ //
+ // Calculate eta step per strip, number of eta steps, number of
+ // phi steps, and check the sign of the eta increment
+ Float_t stripEta = (Float_t(r->GetNStrips()) / (etaIn - etaOut));
+ Int_t nEta = Int_t(TMath::Abs(etaIn - etaOut) / fDeltaEta);
+ Int_t nPhi = Int_t(360. / fDeltaPhi);
+ Float_t sign = TMath::Sign(Float_t(1.), etaIn);
-//_____________________________________________________________________________
-void AliFMDReconstructor::FillESD(AliRunLoader* /*runLoader*/,
- AliESD* /*esd*/) const
+ AliDebug(10, Form("FMD%d%c Eta range: %f, %f %d Phi steps",
+ sub->GetId(), r->GetId(), etaOut, etaIn, nPhi));
+
+ // Loop over relevant phi values
+ for (Int_t p = 0; p < nPhi; p++) {
+ Float_t minPhi = p * fDeltaPhi;
+ Float_t maxPhi = minPhi + fDeltaPhi;
+ UShort_t minSector = UShort_t(minPhi / 360) * r->GetNSectors();
+ UShort_t maxSector = UShort_t(maxPhi / 360) * r->GetNSectors();
+
+ AliDebug(10, Form(" Now in phi range %f, %f (sectors %d,%d)",
+ minPhi, maxPhi, minSector, maxSector));
+ // Loop over relevant eta values
+ for (Int_t e = nEta; e >= 0; --e) {
+ Float_t maxEta = etaIn - sign * e * fDeltaEta;
+ Float_t minEta = maxEta - sign * fDeltaEta;
+ if (sign > 0) minEta = TMath::Max(minEta, etaOut);
+ else minEta = TMath::Min(minEta, etaOut);
+ Float_t theta1 = 2 * TMath::ATan(TMath::Exp(-minEta));
+ Float_t theta2 = 2 * TMath::ATan(TMath::Exp(-maxEta));
+ Float_t minR = TMath::Abs(realZ * TMath::Tan(theta2));
+ Float_t maxR = TMath::Abs(realZ * TMath::Tan(theta1));
+ UShort_t minStrip = UShort_t((etaIn - maxEta) * stripEta + 0.5);
+ UShort_t maxStrip = UShort_t((etaIn - minEta) * stripEta + 0.5);
+
+ AliDebug(10, Form(" Now in eta range %f, %f (strips %d, %d)\n"
+ " [radii %f, %f, thetas %f, %f, sign %d]",
+ minEta, maxEta, minStrip, maxStrip,
+ minR, maxR, theta1, theta2, sign));
+
+ // Count number of empty strips
+ Int_t emptyStrips = 0;
+ for (Int_t sector = minSector; sector < maxSector; sector++)
+ for (Int_t strip = minStrip; strip < maxStrip; strip++)
+ if (fAdcs(sub->GetId() - 1, r->GetId(), sector, strip)
+ < fThreshold) emptyStrips++;
+
+ // The total number of strips
+ Float_t nTotal = (maxSector - minSector) * (maxStrip - minStrip);
+
+ // Log ratio of empty to total number of strips
+ AliDebug(10, Form("Lambda= %d / %d = %f",
+ emptyStrips, nTotal,
+ Float_t(emptyStrips) / nTotal));
+
+ Double_t lambda = (emptyStrips > 0 ?
+ - TMath::Log(Double_t(emptyStrips) / nTotal) :
+ 1);
+
+ // The reconstructed number of particles is then given by
+ Int_t reconstructed = Int_t(lambda * nTotal + 0.5);
+
+ // Add a AliFMDParticles to the reconstruction tree.
+ new((*fParticles)[nRecon])
+ AliFMDParticles(sub->GetId(), r->GetId(),
+ minSector, maxSector, minStrip, maxStrip,
+ minEta, maxEta, minPhi, maxPhi,
+ reconstructed, AliFMDParticles::kPoission);
+ nRecon++;
+ } // phi
+ } // eta
+ } // ring
+ } // detector
+}
+
+
+//____________________________________________________________________
+void
+AliFMDReconstructor::FillESD(AliRunLoader* /*fRunLoader*/,
+ AliESD* /*esd*/) const
{
// nothing to be done
-// Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved.
+// -*- mode: c++ -*-
+//
+// Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+// reserved.
+//
// See cxx source for full Copyright notice
+//
// AliFMDReconstructor.h
-// Task Class for making TreeR in FMD
+// Task Class for making TreeR for FMD
+//
//-- Authors: Evgeny Karpechev (INR) and Alla Maevskaia (INR)
+// Latest changes by Christian Holm Christensen <cholm@nbi.dk>
/*
- Reconstruct nember of particles
- in given group of pads for given FMDvolume
- determine by numberOfVolume ,
- numberOfMinSector,numberOfMaxSector,
- numberOfMinRing, numberOfMaxRing
- Reconstruction method choose dependence on number of empty pads
+ Reconstruct nember of particles in given group of pads for given
+ FMDvolume determine by numberOfVolume ,
+ numberOfMinSector,numberOfMaxSector, numberOfMinRing,
+ numberOfMaxRing Reconstruction method choose dependence on number
+ of empty pads
*/
/* $Id$ */
-
-
#ifndef ALIFMDRECONSTRUCTOR_H
#define ALIFMDRECONSTRUCTOR_H
+#ifndef ALIRECONSTRUCTOR_H
+# include <AliReconstructor.h>
+#endif
+#ifndef ALIFMDMAP_H
+# include <AliFMDMap.h>
+#endif
-#include "AliReconstructor.h"
+//____________________________________________________________________
+class TClonesArray;
+class AliFMD;
+class AliLoader;
+class AliRunLoader;
+class AliFMDDigit;
+class AliRawReader;
+typedef AliFMDMap<UShort_t> AliFMDAdcMap;
+//____________________________________________________________________
class AliFMDReconstructor: public AliReconstructor
{
- public:
- AliFMDReconstructor(): AliReconstructor() {};
- virtual ~AliFMDReconstructor() {};
-
- virtual void Reconstruct(AliRunLoader* runLoader) const;
- virtual void FillESD(AliRunLoader* runLoader, AliESD* esd) const;
+protected:
+ mutable AliFMDAdcMap fAdcs;
+ mutable AliRunLoader* fRunLoader;
+ mutable AliLoader* fFMDLoader;
+ mutable TClonesArray* fParticles;
+ mutable AliFMD* fFMD;
+ Float_t fDeltaEta;
+ Float_t fDeltaPhi;
+ UShort_t fThreshold;
+ Float_t fPedestal;
+ Float_t fPedestalWidth;
+ mutable Int_t fEmptyStrips;
+ mutable Int_t fTotalStrips;
+
+ enum {
+ kMaxDetectors = 3,
+ kMaxRings = 2,
+ kMaxSectors = 20,
+ kMaxStrips = 512
+ };
+
+public:
+ AliFMDReconstructor();
+ virtual ~AliFMDReconstructor() {}
+
+ void SetDeltaEta(Float_t deta=.1) { fDeltaEta = deta; }
+ void SetDeltaPhi(Float_t dphi=360) { fDeltaPhi = dphi; }
+ void SetThreshold(UShort_t t=6) { fThreshold = t; }
+ void SetPedestal(Float_t mean=10, Float_t width=1);
+
+ virtual void Reconstruct(AliRunLoader* runLoader) const;
+ virtual void Reconstruct(AliRunLoader* runLoader,
+ AliRawReader* rawReader) const;
+ virtual void FillESD(AliRunLoader* runLoader, AliESD* esd) const;
+
+protected:
+ virtual void ProcessEvent(Int_t event,
+ AliRawReader* rawReader,
+ TClonesArray* digits) const;
+ virtual Bool_t ReadAdcs(TClonesArray* digits) const;
+ virtual Bool_t ReadAdcs(AliRawReader* rawReader) const;
+ virtual void ProcessDigit(AliFMDDigit* digit) const;
+ virtual UShort_t SubtractPedestal(AliFMDDigit* digit) const;
+ virtual void ReconstructFromCache(Float_t zVertex) const;
ClassDef(AliFMDReconstructor, 0) // class for the FMD reconstruction
-
-
};
#endif
-
-
-
-
-
-
-
-
-
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Utility class to help implement collection of FMD modules into
+// rings. This is used by AliFMDSubDetector and AliFMD.
+//
+// The AliFMD object owns the AliFMDRing objects, and the
+// AliFMDSubDetector objects reference these. That is, the AliFMDRing
+// objects are share amoung the AliFMDSubDetector objects.
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef ALIFMDRING_H
+# include "AliFMDRing.h"
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef ROOT_TMath
+# include <TMath.h>
+#endif
+#ifndef ROOT_TH2
+# include <TH2.h>
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ROOT_TVector2
+# include <TVector2.h>
+#endif
+#ifndef ROOT_TBrowser
+# include <TBrowser.h>
+#endif
+#ifndef ROOT_TString
+# include <TString.h>
+#endif
+#ifndef ROOT_TArc
+# include <TArc.h>
+#endif
+#ifndef ROOT_TObjArray
+# include <TObjArray.h>
+#endif
+#ifndef ROOT_TXTRU
+# include <TXTRU.h>
+#endif
+#ifndef ROOT_TNode
+# include <TNode.h>
+#endif
+#ifndef ROOT_TRotMatrix
+# include <TRotMatrix.h>
+#endif
+#ifndef ROOT_TList
+# include <TList.h>
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+
+ClassImp(AliFMDRing);
+
+//____________________________________________________________________
+// Construct a alifmdring.
+//
+// id Id of the ring (either 'i' or 'o').
+// lowr Lower radius of ring (in centimeters).
+// highr Upper radius of ring (in centimeters).
+// r Radius of the silicon wafers (in centimeters).
+// theta Opening angle of the silicon wafers.
+// strips Number of strips.
+AliFMDRing::AliFMDRing(Char_t id, Bool_t detailed)
+ : fId(id),
+ fDetailed(detailed),
+ fWaferRadius(0),
+ fSiThickness(0),
+ fLowR(0),
+ fHighR(0),
+ fTheta(0),
+ fNStrips(0),
+ fShape(0),
+ fRotMatricies(0)
+{}
+
+//____________________________________________________________________
+void
+AliFMDRing::Init()
+{
+ // Initialize the ring object.
+ // DebugGuard guard("AliFMDRing::Init");
+ AliDebug(10, "AliFMDRing::Init");
+ fPolygon.Clear();
+ SetupCoordinates();
+}
+
+//____________________________________________________________________
+AliFMDRing::~AliFMDRing()
+{
+ if (fShape) delete fShape;
+ if (fRotMatricies) delete fRotMatricies;
+}
+
+
+//____________________________________________________________________
+void
+AliFMDRing::Browse(TBrowser* /* b */)
+{
+ // DebugGuard guard("AliFMDRing::Browse");
+ AliDebug(10, "AliFMDRing::Browse");
+}
+
+
+//____________________________________________________________________
+void
+AliFMDRing::SetupCoordinates()
+{
+ // Calculates the parameters of the polygon shape.
+ //
+ // DebugGuard guard("AliFMDRing::SetupCoordinates");
+ AliDebug(10, "AliFMDRing::SetupCoordinates");
+ // Get out immediately if we have already done all this
+ if (fPolygon.GetNVerticies() > 1) return;
+
+ double tan_theta = TMath::Tan(fTheta * TMath::Pi() / 180.);
+ double tan_theta2 = TMath::Power(tan_theta,2);
+ double r2 = TMath::Power(fWaferRadius,2);
+ double y_A = tan_theta * fLowR;
+ double lr2 = TMath::Power(fLowR, 2);
+ double hr2 = TMath::Power(fHighR,2);
+ double x_D = fLowR + TMath::Sqrt(r2 - tan_theta2 * lr2);
+ double x_D2 = TMath::Power(x_D,2);
+ //double x_D_2 = fLowR - TMath::Sqrt(r2 - tan_theta2 * lr2);
+ double y_B = sqrt(r2 - hr2 + 2 * fHighR * x_D - x_D2);
+ double x_C = ((x_D + TMath::Sqrt(-tan_theta2 * x_D2 + r2
+ + r2 * tan_theta2))
+ / (1 + tan_theta2));
+ double y_C = tan_theta * x_C;
+
+ fPolygon.AddVertex(fLowR, -y_A);
+ fPolygon.AddVertex(x_C, -y_C);
+ fPolygon.AddVertex(fHighR, -y_B);
+ fPolygon.AddVertex(fHighR, y_B);
+ fPolygon.AddVertex(x_C, y_C);
+ fPolygon.AddVertex(fLowR, y_A);
+}
+
+//____________________________________________________________________
+bool
+AliFMDRing::IsWithin(size_t moduleNo, double x, double y) const
+{
+ // Checks if a point (x,y) is inside the module with number moduleNo
+ //
+ // DebugGuard guard("AliFMDRing::IsWithin");
+ AliDebug(10, "AliFMDRing::IsWithin");
+ bool ret = false;
+ double r2 = x * x + y * y;
+ if (r2 < fHighR * fHighR && r2 > fLowR * fLowR) {
+ // double point_angle = TMath::ATan2(y, x);
+ // int n_modules = 360 / Int_t(fTheta * 2);
+ double m_angle = (.5 + moduleNo) * 2 * fTheta;
+ double m_radians = TMath::Pi() * m_angle / 180.;
+
+ // Rotate the point.
+ double xr = x * TMath::Cos(-m_radians) - y * TMath::Sin(-m_radians);
+ double yr = x * TMath::Sin(-m_radians) + y * TMath::Cos(-m_radians);
+
+ ret = fPolygon.Contains(xr,yr);
+ }
+ return ret;
+}
+
+
+
+
+//____________________________________________________________________
+void
+AliFMDRing::Draw(Option_t* option) const
+{
+ // Draw a the shape of the ring into a 2D histogram. Useful for
+ // superimposing the actual shape of the ring onto a scatter plot of
+ // hits in the detector.
+ //
+ // DebugGuard guard("AliFMDRing::Draw");
+ AliDebug(10, "AliFMDRing::Draw");
+ // The unrotated coordinates of the polygon verticies
+ if (fPolygon.GetNVerticies() < 1) return;
+
+ TVector2 v[6];
+ for (size_t i = 0; i < fPolygon.GetNVerticies(); i++)
+ v[i] = fPolygon.GetVertex(i);
+
+ Int_t nModules = 360 / Int_t(fTheta * 2);
+ Double_t dTheta = fTheta * 2;
+
+ TString opt(option);
+ if (opt.Contains("B", TString::kIgnoreCase)) {
+ opt.Remove(opt.Index("B", 1, TString::kIgnoreCase),1);
+ TH1* null = new TH2F("null", "Null",
+ 100, -fHighR * 1.1, fHighR * 1.1,
+ 100, -fHighR * 1.1, fHighR * 1.1);
+ null->SetStats(0);
+ null->Draw(opt.Data());
+ }
+
+ for (int i = 0; i < nModules; i++) {
+ Double_t theta = (i + .5) * dTheta;
+ AliFMDPolygon p;
+ for (int j = 0; j < 6; j++) {
+ TVector2 vr(v[j].Rotate(TMath::Pi() * theta / 180.));
+ if (!p.AddVertex(vr.X(),vr.Y())) {
+ // std::cerr << "Draw of polygon " << i << " failed" << std::endl;
+ break;
+ }
+ }
+ p.Draw(opt.Data(), Form("MOD%c_%d", fId, i));
+ }
+ if (opt.Contains("0", TString::kIgnoreCase)) {
+ TArc* arcH = new TArc(0,0, fHighR);
+ arcH->SetLineStyle(2);
+ arcH->SetLineColor(4);
+ arcH->Draw();
+
+ TArc* arcL = new TArc(0,0, fLowR);
+ arcL->SetLineStyle(2);
+ arcL->SetLineColor(4);
+ arcL->Draw();
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDRing::SetupGeometry(Int_t vacuumId, Int_t siId, Int_t pcbId,
+ Int_t pbRotId, Int_t idRotId)
+{
+ // Setup the geometry of the ring. It defines the volumes
+ // RNGI or RNGO which can later be positioned in a sub-detector
+ // volume.
+ //
+ // The hieracy of the RNGx volume is
+ //
+ // RNGx // Ring volume
+ // VFx // Container of hybrid + legs
+ // ACTx // Active volume (si sensor approx)
+ // SECx // Section division
+ // STRx // Strip division
+ // PBTx // Print board (bottom)
+ // PTTx // Print board (top)
+ // LLEG // Support leg (long version)
+ // VBx // Container of hybrid + legs
+ // ACTx // Active volume (si sensor approx)
+ // SECx // Section division
+ // STRx // Strip division
+ // PBTx // Print board (bottom)
+ // PTTx // Print board (top)
+ // SLEG // Support leg (long version)
+ //
+ // Parameters:
+ //
+ // vacuumId Medium of inactive virtual volumes
+ // siId Medium of Silicon sensor (active)
+ // pcbId Medium of print boards
+ // pbRotId Print board rotation matrix
+ // idRotId Identity rotation matrix
+ //
+ // DebugGuard guard("AliFMDRing::SetupGeometry");
+ AliDebug(10, "AliFMDRing::SetupGeometry");
+
+ const TVector2& bCorner = fPolygon.GetVertex(3); // Third corner
+ const TVector2& aCorner = fPolygon.GetVertex(5); // First corner
+ const TVector2& cCorner = fPolygon.GetVertex(4); // Second corner
+ TString name;
+ TString name2;
+ Double_t dStrip = (bCorner.Mod() - aCorner.Mod()) / fNStrips;
+ Double_t stripOff = aCorner.Mod();
+ Double_t rmin = fLowR;
+ Double_t rmax = bCorner.Mod();
+ Double_t pars[10];
+ fRingDepth = (fSiThickness
+ + fPrintboardThickness
+ + fLegLength
+ + fModuleSpacing);
+
+ // Ring virtual volume
+ pars[0] = rmin;
+ pars[1] = fHighR;
+ pars[2] = fRingDepth / 2;
+ name = Form("RNG%c", fId);
+ fRingId = gMC->Gsvolu(name.Data(), "TUBE", vacuumId, pars, 3);
+
+ // Virtual volume for modules with long legs
+ pars[1] = rmax;
+ pars[3] = -fTheta;
+ pars[4] = fTheta;
+ name = Form("VF%c", fId);
+ fVirtualFrontId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5);
+
+ // Virtual volume for modules with long legs
+ pars[2] = (fRingDepth - fModuleSpacing) / 2;
+ name = Form("VB%c", fId);
+ fVirtualBackId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5);
+
+ // Virtual mother volume for silicon
+ pars[2] = fSiThickness/2;
+ name2 = name;
+ name = Form("ACT%c",fId);
+ fActiveId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId , pars, 5);
+
+ if (fDetailed) {
+ // Virtual sector volumes
+ name2 = name;
+ name = Form("SEC%c",fId);
+ gMC->Gsdvn2(name.Data(), name2.Data(), 2, 2, -fTheta, vacuumId);
+ fSectionId = gMC->VolId(name.Data());
+
+ // Active strip volumes
+ name2 = name;
+ name = Form("STR%c", fId);
+ gMC->Gsdvt2(name.Data(), name2.Data(), dStrip, 1,
+ stripOff, siId, fNStrips);
+ fStripId = gMC->VolId(name.Data());
+ }
+
+ // Print-board on back of module
+ pars[4] = TMath::Tan(TMath::Pi() * fTheta / 180) * fBondingWidth;
+ // Top of the print board
+ pars[0] = cCorner.Y() - pars[4];
+ pars[1] = bCorner.Y() - pars[4];
+ pars[2] = fPrintboardThickness / 2; // PCB half thickness
+ pars[3] = (bCorner.X() - cCorner.X()) / 2;
+ name = Form("PBT%c", fId);
+ fPrintboardTopId = gMC->Gsvolu(name.Data(), "TRD1", pcbId, pars, 4);
+
+ // Bottom of the print board
+ pars[0] = aCorner.Y() - pars[4];
+ pars[1] = cCorner.Y() - pars[4];
+ pars[3] = (cCorner.X() - aCorner.X()) / 2;
+ name = Form("PBB%c", fId);
+ fPrintboardBottomId = gMC->Gsvolu(name.Data(), "TRD1", pcbId, pars, 4);
+
+ // Define rotation matricies
+ Int_t nModules = 360 / Int_t(fTheta * 2);
+ Double_t dTheta = fTheta * 2;
+ fRotations.Set(nModules);
+ for (int i = 0; i < nModules; i++) {
+ Double_t theta = (i + .5) * dTheta;
+ Int_t idrot = 0;
+ // Rotation matrix for virtual module volumes
+ gMC->Matrix(idrot, 90, theta, 90, fmod(90 + theta, 360), 0, 0);
+ fRotations[i] = idrot;
+ }
+
+
+ // Int_t nModules = 360 / Int_t(fTheta * 2);
+ // Double_t dTheta = fTheta * 2;
+ Double_t pbTopL = (bCorner.X() - cCorner.X());
+ Double_t pbBotL = (cCorner.X() - aCorner.X());
+ Double_t yoffset = ((TMath::Tan(TMath::Pi() * fTheta / 180)
+ * fBondingWidth));
+
+ for (int i = 0; i < nModules; i++) {
+ TString name2 = Form("RNG%c", fId);
+
+ Int_t id = i;
+ // Double_t theta = (i + .5) * dTheta;
+ Bool_t isFront = (i % 2 == 1);
+ Double_t dz = 0;
+ Double_t w = fRingDepth - (isFront ? 0 : fModuleSpacing);
+
+ // Place virtual module volume
+ name = Form("V%c%c", (isFront ? 'F' : 'B'), fId);
+ dz = (w - fRingDepth) / 2;
+ gMC->Gspos(name.Data(), id, name2.Data(), 0., 0., dz,fRotations[i]);
+
+ // We only need to place the children once, they are copied when
+ // we place the other virtual volumes.
+ if (i > 1) continue;
+ name2 = name;
+
+ // Place active silicon wafer - this is put so that the front of
+ // the silicon is on the edge of the virtual volume.
+ name = Form("ACT%c", fId);
+ dz = (w - fSiThickness) / 2;
+ gMC->Gspos(name.Data(), id, name2.Data(),0.,0.,dz,idRotId);
+
+ // Place print board. This is put immediately behind the silicon
+ name = Form("PBT%c", fId);
+ dz = w / 2 - fSiThickness - fPrintboardThickness / 2;
+ gMC->Gspos(name.Data(), id, name2.Data(),
+ fLowR + pbBotL + pbTopL / 2, 0, dz, pbRotId, "ONLY");
+ name = Form("PBB%c", fId);
+ gMC->Gspos(name.Data(), id, name2.Data(),
+ fLowR + pbBotL / 2, 0, dz, pbRotId, "ONLY");
+
+ // Support legs
+ // This is put immediately behind the pringboard.
+ dz = (w / 2 - fSiThickness - fPrintboardThickness
+ - (fLegLength + (isFront ? fModuleSpacing : 0)) /2);
+ name = (isFront ? "LLEG" : "SLEG");
+ gMC->Gspos(name.Data(), id*10 + 1, name2.Data(),
+ aCorner.X() + fLegOffset + fLegRadius, 0., dz, idRotId, "");
+ Double_t y = cCorner.Y() - yoffset - fLegOffset - fLegRadius;
+ gMC->Gspos(name.Data(),id*10+2,name2.Data(),cCorner.X(), y,dz,idRotId,"");
+ gMC->Gspos(name.Data(),id*10+3,name2.Data(),cCorner.X(), -y,dz ,idRotId,"");
+ }
+}
+//____________________________________________________________________
+void
+AliFMDRing::Geometry(const char* mother, Int_t baseId, Double_t z,
+ Int_t /* pbRotId */, Int_t idRotId)
+{
+ // Positions a RNGx volume inside a mother.
+ //
+ // Parameters
+ //
+ // mother Mother volume to position the RNGx volume in
+ // baseId Base copy number
+ // z Z coordinate where the front of the active silicon
+ // should be in the mother volume, so we need to
+ // subtract half the ring width.
+ // idRotId Identity rotation matrix
+ //
+ // DebugGuard guard("AliFMDRing::Geometry");
+ AliDebug(10, "AliFMDRing::Geometry");
+ TString name;
+ Double_t offsetZ = (fSiThickness
+ + fPrintboardThickness
+ + fLegLength + fModuleSpacing) / 2;
+ name = Form("RNG%c", fId);
+ gMC->Gspos(name.Data(), baseId, mother, 0., 0., z - offsetZ, idRotId, "");
+}
+
+//____________________________________________________________________
+void
+AliFMDRing::SimpleGeometry(TList* nodes,
+ TNode* mother,
+ Int_t colour,
+ Double_t z,
+ Int_t n)
+{
+ // Make a simple geometry of the ring for event display.
+ //
+ // The simple geometry is made from ROOT TNode and TShape objects.
+ // Note, that we cache the TShape and TRotMatrix objects used for
+ // this.
+ //
+ // Parameters
+ //
+ // nodes List of nodes to register all create nodes in
+ // mother Mother node to put the ring in.
+ // colour Colour of the nodes
+ // z Z position of the node in the mother volume
+ // n Detector number
+ //
+ // DebugGuard guard("AliFMDRing::SimpleGeometry");
+ AliDebug(10, "AliFMDRing::SimpleGeometry");
+ SetupCoordinates();
+
+ // If the shape hasn't been defined yet, we define it here.
+ if (!fShape) {
+ TString name(Form("ACT%c", fId));
+ TString title(Form("Shape of modules in %c Rings", fId));
+ Int_t n = fPolygon.GetNVerticies();
+ TXTRU* shape = new TXTRU(name.Data(), title.Data(), "void", n, 2);
+ for (Int_t i = 0; i < n; i++) {
+ const TVector2& v = fPolygon.GetVertex(i);
+ shape->DefineVertex(i, v.X(), v.Y());
+ }
+ shape->DefineSection(0, - fSiThickness / 2, 1, 0, 0);
+ shape->DefineSection(1, + fSiThickness / 2, 1, 0, 0);
+ fShape = shape;
+ fShape->SetLineColor(colour);
+ }
+
+ Int_t nModules = 360 / Int_t(fTheta * 2);
+ Double_t dTheta = fTheta * 2;
+
+ // If the roation matricies hasn't been defined yet, we do so here
+ if (!fRotMatricies) {
+ fRotMatricies = new TObjArray(nModules);
+ for (int i = 0; i < nModules; i++) {
+ Double_t theta = (i + .5) * dTheta;
+ TString name(Form("FMD_ring_%c_rot", fId));
+ TString title(Form("FMD Ring %c Rotation", fId));
+ TRotMatrix* rot =
+ new TRotMatrix(name.Data(), title.Data(),
+ 90, theta, 90, fmod(90 + theta, 360), 0, 0);
+ fRotMatricies->AddAt(rot, i);
+ }
+ }
+
+ Double_t offsetZ = (fSiThickness
+ + fPrintboardThickness
+ + fLegLength + fModuleSpacing) / 2;
+
+ // Make all the nodes
+ for (int i = 0; i < nModules; i++) {
+ Bool_t isFront = (i % 2 == 1);
+ mother->cd();
+ TRotMatrix* rot = static_cast<TRotMatrix*>(fRotMatricies->At(i));
+ TString name(Form("ACT%c_%d_%d", fId, n, i));
+ TString title(Form("Active FMD%d volume in %c Ring", n, fId));
+ TNode* node = new TNode(name.Data(), title.Data(), fShape,
+ 0, 0,
+ z - offsetZ + (isFront ? fModuleSpacing : 0),
+ rot);
+ node->SetLineColor(colour);
+ nodes->Add(node);
+ }
+}
+
+
+
+//____________________________________________________________________
+void
+AliFMDRing::Gsatt()
+{
+ // Set drawing attributes for the RING
+ //
+ // DebugGuard guard("AliFMDRing::Gsatt");
+ AliDebug(10, "AliFMDRing::Gsatt");
+ TString name;
+ name = Form("RNG%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 0);
+
+ name = Form("VF%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 0);
+
+ name = Form("VB%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 0);
+
+ name = Form("ACT%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 1);
+
+ name = Form("PBT%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 1);
+
+ name = Form("PBB%c",fId);
+ gMC->Gsatt(name.Data(), "SEEN", 1);
+}
+
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice
+ */
+#ifndef ALIFMDRING_H
+#define ALIFMDRING_H
+#ifndef ALIFMDPOLYGON_H
+# include <AliFMDPolygon.h>
+#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+
+class TBrowser;
+class TNode;
+class TObjArray;
+class TShape;
+class TList;
+
+
+//__________________________________________________________________
+struct AliFMDRing : public TObject
+{
+ Char_t fId; // ID
+ Bool_t fDetailed;
+ Int_t fActiveId; // Active volume
+ Int_t fPrintboardBottomId; // Print board bottom volume
+ Int_t fPrintboardTopId; // Print board top volume
+ Int_t fRingId; // Ring volume
+ Int_t fSectionId; // Section volumes
+ Int_t fStripId; // Strip volumes
+ Int_t fVirtualBackId; // Virtual Back volume
+ Int_t fVirtualFrontId; // Virtual Front volume
+
+ Double_t fBondingWidth; // With of bonding pad on sensor
+ Double_t fWaferRadius; // Size of wafer the sensor was made from
+ Double_t fSiThickness; // Thickness of sensor
+ Double_t fLowR; // Lower radius of ring
+ Double_t fHighR; // Upper radius of ring
+ Double_t fTheta; // Opening angle of the silicon wafers
+ Int_t fNStrips; // Number of strips
+ Double_t fRingDepth; // How far the ring extends beyond
+ // the z value given.
+ Double_t fLegRadius; // Radius of support legs
+ Double_t fLegLength; // Radius of support legs
+ Double_t fLegOffset; // Radius of support legs
+
+ Double_t fModuleSpacing; // Staggering offset
+ Double_t fPrintboardThickness; // Thickness of print board
+
+ TArrayI fRotations; // Array of rotations
+ TShape* fShape; // Shape used for event display
+ TObjArray* fRotMatricies; // Matricies used for event display
+
+ AliFMDPolygon fPolygon; // Polygon shape
+public:
+ //----------------------------------------------------------------
+ AliFMDRing(Char_t id='\0', Bool_t detailed=kTRUE);
+ virtual ~AliFMDRing();
+ void Init();
+ bool IsWithin(size_t moduleNo, double x, double y) const;
+ void SetupCoordinates();
+ void SetupGeometry(Int_t vacuumId, Int_t siId, Int_t pcbId,
+ Int_t pbRotId, Int_t idRotId);
+ void Geometry(const char* mother, Int_t baseId, Double_t z, Int_t pbRotId,
+ Int_t idRotId);
+ void SimpleGeometry(TList* nodes,
+ TNode* mother,
+ Int_t colour,
+ Double_t z,
+ Int_t n);
+ void Gsatt();
+ void Draw(Option_t* opt="HOL") const; //*MENU*
+ void Browse(TBrowser* b);
+ Bool_t IsFolder() const { return kTRUE; }
+
+ Char_t GetId() const { return fId; }
+ Int_t GetActiveId() const { return fActiveId; }
+ Int_t GetPrintboardBottomId() const { return fPrintboardBottomId; }
+ Int_t GetPrintboardTopId() const { return fPrintboardTopId; }
+ Int_t GetRingId() const { return fRingId; }
+ Int_t GetSectionId() const { return fSectionId; }
+ Int_t GetStripId() const { return fStripId; }
+ Int_t GetVirtualBackId() const { return fVirtualBackId; }
+ Int_t GetVirtualFrontId() const { return fVirtualFrontId; }
+ Double_t GetBondingWidth() const { return fBondingWidth; }
+ Double_t GetWaferRadius() const { return fWaferRadius; }
+ Double_t GetSiThickness() const { return fSiThickness; }
+ Double_t GetLowR() const { return fLowR; }
+ Double_t GetHighR() const { return fHighR; }
+ Double_t GetTheta() const { return fTheta; }
+ Int_t GetNStrips() const { return fNStrips; }
+ Int_t GetNSectors() const { return Int_t(360 / fTheta); }
+ Double_t GetLegRadius() const { return fLegRadius; }
+ Double_t GetLegLength() const { return fLegLength; }
+ Double_t GetModuleSpacing() const { return fModuleSpacing; }
+ Double_t GetPrintboardThickness() const { return fPrintboardThickness; }
+ Double_t GetRingDepth() const { return fRingDepth; }
+
+ void SetBondingWidth(Double_t width) { fBondingWidth = width; }
+ void SetWaferRadius(Double_t radius) { fWaferRadius = radius; }
+ void SetSiThickness(Double_t thickness) { fSiThickness = thickness; }
+ void SetLowR(Double_t lowR) { fLowR = lowR; }
+ void SetHighR(Double_t highR) { fHighR = highR; }
+ void SetTheta(Double_t theta) { fTheta = theta; }
+ void SetNStrips(Int_t nStrips) { fNStrips = nStrips; }
+ void SetLegRadius(Double_t radius) { fLegRadius = radius; }
+ void SetLegLength(Double_t length) { fLegLength = length; }
+ void SetLegOffset(Double_t offset) { fLegOffset = offset; }
+
+ void SetModuleSpacing(Double_t spacing) { fModuleSpacing = spacing; }
+ void SetPrintboardThickness(Double_t thickness) { fPrintboardThickness = thickness; }
+
+ ClassDef(AliFMDRing, 1) // Ring volume parameters
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Utility class to help implement the FMD geometry. This provides
+// the interface for the concrete geometry implementations of the FMD
+// sub-detectors.
+//
+// The AliFMD object owns the AliFMDSubDetector objects
+//
+// Latest changes by Christian Holm Christensen
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef ALIFMDSUBDETECTOR_H
+# include "AliFMDSubDetector.h"
+#endif
+#ifndef ALILOG_H
+# include "AliLog.h"
+#endif
+#ifndef ROOT_TVirtualMC
+# include <TVirtualMC.h>
+#endif
+#ifndef ROOT_TList
+# include <TList.h>
+#endif
+#ifndef ROOT_TString
+# include <TString.h>
+#endif
+#ifndef __IOSTREAM__
+# include <iostream>
+#endif
+
+ClassImp(AliFMDSubDetector);
+
+//____________________________________________________________________
+AliFMDSubDetector::AliFMDSubDetector(Int_t n)
+ : fId(n),
+ fInnerZ(0),
+ fOuterZ(0),
+ fInner(0),
+ fOuter(0)
+{}
+
+//____________________________________________________________________
+void
+AliFMDSubDetector::Draw(Option_t* /* opt */) const
+{
+ // DebugGuard guard("AliFMDSubDetector::Draw");
+ AliDebug(10, "AliFMDSubDetector::Draw");
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDSubDetector::CheckHit(Char_t ring, Int_t module, Double_t x, Double_t y)
+{
+ // Check if a hit (x,y) in module module of ring ring is within the
+ // actual shape.
+ Bool_t ret = kFALSE;
+ switch (ring) {
+ case 'i':
+ case 'I':
+ if (!fInner) break;
+ ret = fInner->IsWithin(module, x, y);
+ break;
+ case 'o':
+ case 'O':
+ if (!fOuter) break;
+ ret = fOuter->IsWithin(module, x, y);
+ break;
+ }
+ return ret;
+}
+
+//____________________________________________________________________
+void
+AliFMDSubDetector::SimpleGeometry(TList* nodes,
+ TNode* mother,
+ Int_t colour,
+ Double_t zMother)
+{
+ // Make a simplified geometry for event display
+ //
+ // Parameters
+ //
+ // nodes List of nodes to register all create nodes in
+ // mother Mother node to put the ring in.
+ // colour Colour of the nodes
+ // zMother Z position of the node in the mother volume
+ //
+ for (int i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ Double_t z = 0;
+ switch (i) {
+ case 0:
+ r = fInner;
+ z = fInnerZ;
+ break;
+ case 1:
+ r = fOuter;
+ z = fOuterZ;
+ break;
+ }
+ if (!r) continue;
+
+ // Make the coordinates relative to the mother volume. If we're
+ // on the positive side, then we need to flip the z-coordinate, as
+ // we'll rotate the whole sub-detector afterwards.
+ z -= zMother;
+ if (zMother > 0) z *= -1;
+
+ r->SimpleGeometry(nodes, mother, colour, z, fId);
+ }
+}
+
+
+//____________________________________________________________________
+void
+AliFMDSubDetector::SetupGeometry(Int_t airId, Int_t kaptionId)
+{
+ // Set up the geometry of this particular detector.
+ //
+ // In this class, it defines the support honey comp calls and
+ // nothing else.
+ //
+ // Parameters
+ // airId Medium of inactive virtual volumes
+ // kaptionId Medium of honeycomb
+ //
+ // DebugGuard guard("AliFMDSubDetector::SetupGeometry");
+ AliDebug(10, "AliFMDSubDetector::SetupGeometry");
+ TString name;
+ Double_t par[5];
+
+ for (int i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ char c = '\0';
+ switch (i) {
+ case 0:
+ r = fInner;
+ c = 'I';
+ par[0] = fInnerHoneyLowR;
+ par[1] = fInnerHoneyHighR;
+ break;
+ case 1:
+ r = fOuter;
+ c = 'O';
+ par[0] = fOuterHoneyLowR;
+ par[1] = fOuterHoneyHighR;
+ break;
+ }
+ if (!r) continue;
+ // Top of honeycomb, inner ring
+ par[2] = fHoneycombThickness / 2;
+ par[3] = 0;
+ par[4] = 180;
+ name = Form("HT%c%d", c, fId);
+ gMC->Gsvolu(name.Data(), "TUBS", kaptionId, par, 5);
+
+ // Bottom of honeycomb, inner ring
+ par[3] = 180;
+ par[4] = 360;
+ name = Form("HB%c%d", c, fId);
+ gMC->Gsvolu(name.Data(), "TUBS", kaptionId, par, 5);
+
+ // Air in top of honeycomb, inner ring
+ par[0] += fKaptionThickness;
+ par[1] -= fKaptionThickness;
+ par[2] -= fKaptionThickness;
+ par[3] = 0;
+ par[4] = 180;
+ name = Form("GT%c%d", c, fId);
+ gMC->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+
+ // Air in bottom of honeycomb, inner ring
+ par[3] = 180;
+ par[4] = 360;
+ name = Form("GB%c%d", c, fId);
+ gMC->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDSubDetector::Geometry(const char* mother, Int_t pbRotId, Int_t idRotId,
+ Double_t zMother)
+{
+ // Place the volume inside mother volume.
+ //
+ // Parameters
+ //
+ // mother Volume to position this detector in
+ // pbRotId Print board rotation matrix,
+ // idRotId Identity rotation matrix
+ // zMother The Z passed in, is the position of the middle
+ // point of the mother volume.
+ //
+ // In this base class, it asks the contained rings to position
+ // themselves in the mother volume, and positions the honey comb
+ // support in the mother volume
+ //
+ // DebugGuard guard("AliFMDSubDetector::Geometry");
+ AliDebug(10, "AliFMDSubDetector::Geometry");
+
+ Double_t ringW;
+ Double_t z = 0;
+ // Double_t* b = 0;
+ TString name;
+ TString name2;
+
+ for (int i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ char c = '\0';
+ switch (i) {
+ case 0:
+ r = fInner;
+ c = 'I';
+ z = fInnerZ;
+ break;
+ case 1:
+ r = fOuter;
+ c = 'O';
+ z = fOuterZ;
+ break;
+ }
+ if (!r) continue;
+
+ // Make the coordinates relative to the mother volume. If we're
+ // on the positive side, then we need to flip the z-coordinate, as
+ // we'll rotate the whole sub-detector afterwards.
+ z -= zMother;
+ if (zMother > 0) z *= -1;
+
+ r->Geometry(mother, fId, z, pbRotId, idRotId);
+ ringW = r->GetRingDepth();
+ z -= ringW + fHoneycombThickness / 2;
+
+ // Top of honeycomb
+ name = Form("HT%c%d", c, fId);
+ gMC->Gspos(name.Data(), 1, mother, 0, 0, z, idRotId);
+
+ // Air in top of honeycomb
+ name2 = name;
+ name = Form("GT%c%d", c, fId);
+ gMC->Gspos(name.Data(), 1, name2.Data(),0,fKaptionThickness,0,idRotId);
+
+ // Bottom of honeycomb
+ name = Form("HB%c%d", c, fId);
+ gMC->Gspos(name.Data(), 1, mother, 0, 0, z, idRotId);
+
+ // Air in bottom of honeycomb
+ name2 = name;
+ name = Form("GB%c%d", c, fId);
+ gMC->Gspos(name.Data(),1,name2.Data(),0,-fKaptionThickness,0,idRotId);
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDSubDetector::Gsatt()
+{
+ // Set drawing attributes for the detector
+ //
+ // DebugGuard guard("AliFMDSubDetector::Gsatt");
+ AliDebug(10, "AliFMDSubDetector::Gsatt");
+ TString name(Form("FMD%d", fId));
+ gMC->Gsatt(name.Data(), "SEEN", 0);
+}
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+// -*- mode: c++ -*-
+#ifndef ALIFMDSUBDETECTOR_H
+#define ALIFMDSUBDETECTOR_H
+#ifndef ROOT_TObject
+# include <TObject.h>
+#endif
+#ifndef ALIFMDRING_H
+# include <AliFMDRing.h>
+#endif
+
+class TNode;
+class TList;
+
+
+//__________________________________________________________________
+struct AliFMDSubDetector : public TObject
+{
+protected:
+ Int_t fId; // Detector number
+ Double_t fInnerZ; // Position of outer ring along z
+ Double_t fOuterZ; // Position of outer ring along z
+ Double_t fHoneycombThickness; // Thickness of honeycomb plate
+ Double_t fKaptionThickness; // Thickness of kaption of honeycomb
+ Double_t fInnerHoneyLowR; // Inner radius of inner honeycomb
+ Double_t fInnerHoneyHighR; // Outer radius of inner honeycomb
+ Int_t fInnerHoneyTopId; // Volume ID of top of inner honeycomb
+ Int_t fInnerHoneyBottomId; // Volume ID of bottom of inner honeycomb
+ Double_t fOuterHoneyLowR; // Inner radius of outer honeycomb
+ Double_t fOuterHoneyHighR; // Outer radius of outer honeycomb
+ Int_t fOuterHoneyTopId; // Volume ID of top of outer honeycomb
+ Int_t fOuterHoneyBottomId; // Volume ID of bottom of outer honeycomb
+
+ Int_t fRotationId;
+
+ AliFMDRing* fInner; // Reference to inner ring description
+ AliFMDRing* fOuter; // Reference to outer ring description
+public:
+ AliFMDSubDetector(Int_t n);
+ virtual ~AliFMDSubDetector() {}
+ virtual void SetupGeometry(Int_t airId, Int_t kaptionId);
+ virtual void Geometry(const char* mother, Int_t pbRotId,
+ Int_t idRotId, Double_t z=0);
+ virtual void SimpleGeometry(TList* nodes,
+ TNode* mother,
+ Int_t colour,
+ Double_t zMother);
+
+ virtual void Gsatt();
+ virtual void Draw(Option_t* option="BIOL0") const; //*MENU*
+ virtual Bool_t CheckHit(Char_t ring, Int_t module, Double_t x, Double_t y);
+
+ void SetInner(AliFMDRing* r) { fInner = r; }
+ void SetOuter(AliFMDRing* r) { fOuter = r; }
+ void SetInnerZ(Double_t z) { fInnerZ = z; }
+ void SetOuterZ(Double_t z) { fOuterZ = z; }
+ void SetHoneycombThickness(Double_t t=1) { fHoneycombThickness = t; }
+ void SetInnerHoneyLowR(Double_t r) { fInnerHoneyLowR = r; }
+ void SetInnerHoneyHighR(Double_t r) { fInnerHoneyHighR = r; }
+ void SetOuterHoneyLowR(Double_t r) { fOuterHoneyLowR = r; }
+ void SetOuterHoneyHighR(Double_t r) { fOuterHoneyHighR = r; }
+ void SetKaptionThickness(Double_t t=.1) { fKaptionThickness = t; }
+
+ Double_t GetInnerZ() const { return fInnerZ; }
+ Double_t GetOuterZ() const { return fOuterZ; }
+ AliFMDRing* GetInner() const { return fInner; }
+ AliFMDRing* GetOuter() const { return fOuter; }
+ Double_t GetHoneycombThickness() const { return fHoneycombThickness; }
+ Double_t GetInnerHoneyLowR() const { return fInnerHoneyLowR; }
+ Double_t GetInnerHoneyHighR() const { return fInnerHoneyHighR; }
+ Double_t GetOuterHoneyLowR() const { return fOuterHoneyLowR; }
+ Double_t GetOuterHoneyHighR() const { return fOuterHoneyHighR; }
+ Double_t GetKaptionThickness() const { return fKaptionThickness; }
+ Int_t GetId() const { return fId; }
+ Bool_t IsFolder() const { return kTRUE; }
+
+ ClassDef(AliFMDSubDetector, 1) // Sub detectors
+};
+
+#endif
+++ /dev/null
-////////////////////////////////////////////////
-// Digits classes for set:FMD //
-////////////////////////////////////////////////
-
-
-#include "AliFMDdigit.h"
-
-ClassImp(AliFMDdigit)
-
-AliFMDdigit::AliFMDdigit(Int_t *digits) {
- //
- // Creates a real data digit object
- //
- fNumOfDet = digits[0];
- fNumOfSector = digits[1];
- fNumOfRing = digits[2];
- fNelectrons = digits[3];
- fADC = digits[4];
-}
-
+++ /dev/null
-#ifndef ALIFMDDIGIT_H
-#define ALIFMDDIGIT_H
-
-////////////////////////////////////////////////
-// Digits classes for set:FMD //
-////////////////////////////////////////////////
-#include <TClonesArray.h>
-#include <TObject.h>
-
-
-//___________________________________________
-class AliFMDdigit: public TObject {
-
-private:
- Int_t fNumOfDet ; //Number of FMD disk
- Int_t fNumOfSector ; //Number of sector
- Int_t fNumOfRing; //Number of ring
- Int_t fNelectrons; // real charge
- Int_t fADC; // ADC signal for this charge
-
-public:
- AliFMDdigit() {
- // constructor
- fNumOfDet=fNumOfSector=fNumOfRing=fNelectrons=fADC=0;
- }
- AliFMDdigit(Int_t *digits);
- virtual ~AliFMDdigit() {
- // destructor
- }
- Int_t Volume();
- Int_t NumberOfSector();
- Int_t NumberOfRing();
- Int_t Charge();
- Int_t ADCsignal();
-
- ClassDef(AliFMDdigit,1) // Real data digit object for set:ITS
-};
-inline Int_t AliFMDdigit::Volume(){return fNumOfDet;}
-inline Int_t AliFMDdigit::NumberOfSector() {return fNumOfSector;}
-inline Int_t AliFMDdigit::NumberOfRing() {return fNumOfRing;}
-inline Int_t AliFMDdigit::Charge() {return fNelectrons;}
-inline Int_t AliFMDdigit::ADCsignal() {return fADC;}
-
-
-#endif
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
- /////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity detector based on Silicon version 0 //
-//
-//Begin Html
-/*
-<img src="gif/AliFMDv0Class.gif">
-*/
-//End Html
-// //
-// //
-//////////////////////////////////////////////////////////////////////
-
-#include <Riostream.h>
-#include <stdlib.h>
-
-#include <TGeometry.h>
-#include <TLorentzVector.h>
-#include <TMath.h>
-#include <TNode.h>
-#include <TTUBE.h>
-#include <TLorentzVector.h>
-#include <TVirtualMC.h>
-
-#include "AliFMDv0.h"
-#include "AliMagF.h"
-#include "AliRndm.h"
-#include "AliRun.h"
-#include "AliFMDhit.h"
-
-ClassImp(AliFMDv0)
-
-//--------------------------------------------------------------------
-AliFMDv0::AliFMDv0(const char *name, const char *title):
- AliFMD(name,title)
-{
- //
- // Standart constructor for Forward Multiplicity Detector version 0
- //
- fIdSens1=0;
- fIdSens2=0;
- fIdSens3=0;
- fIdSens4=0;
- fIdSens5=0;
-// setBufferSize(128000);
-}
-//-------------------------------------------------------------------------
-
-void AliFMDv0::CreateGeometry()
-{
-//
- // Create the geometry of Forward Multiplicity Detector version 0
- //
- //Detector consists of 6 volumes:
- // 1st covered pseudorapidity interval from 3.3 to 2.0
- // and placed on 65cm in Z-direction;
- // 2nd - from 2.0 to 1.6 and Z=85 cm;
- // 3d - the same pseudorapidity interval as the 1st
- // but on the other side from the interaction point z=-65cm;
- // 4th - simmetricaly with the 2nd :
- // pseudorapidity from 2.0 to 1.6, Z=-85cm
- // 5th - from 3.6 to 4.7, Z=-270cm
- // 6th - from 4.5 to 5.5 , Z=-630cm.
- // Each part has 400mkm Si (sensetive area, detector itself),
- // 0.75cm of plastic simulated electronics material,
- // Al support ring 2cm thickness and 1cm width placed on
- // the outer radius of each Si disk;
- //
- // begin Html
- /*
- <img src="gif/AliFMDv0.gif">
- */
- //
-
-
-
- Int_t *idtmed = fIdtmed->GetArray();
-
- Int_t ifmd;
- Int_t idrotm[999];
- Float_t zFMD,par[3],ppcon[15];
- Float_t z[5]={-62.8, -75.2, 83.4, 75.2, 340.};
- Float_t NylonTube[3]={0.2,0.6,0.45};
- Float_t zPCB=0.12; Float_t zHoneyComb=0.5;
- Float_t zSi=0.03;
-
- char nameFMD[5], nameSi[5], nameSector[5], nameRing[5];
- Char_t nameHoney[5], nameHoneyIn[5], nameHoneyOut[5];
- Char_t namePCB[5], nameCopper[5], nameChips[5], nameG10[5];
- Char_t nameLPCB[5], nameLCopper[5], nameLChips[5], nameGL10[5];;
- Float_t rin[5]={4.2,15.4,4.2,15.4,4.2};
- Float_t rout[5]={17.4,28.4,17.4,28.4,17.4};
- Float_t RinHoneyComb[5] ={ 5.15,16.4, 5.15,16.4, 5.15};
- Float_t RoutHoneyComb[5]={20.63,34.92,22.3, 32.02,20.63};
- Float_t zInside;
- Float_t zCooper=0.01; Float_t zChips=0.01;
- Float_t yNylonTube[5]={10,20,10,20,10};
-
-
- AliMatrix(idrotm[901], 90, 0, 90, 90, 180, 0);
-
-
- // Nylon tubes
- gMC->Gsvolu("GNYL","TUBE", idtmed[1], NylonTube, 3); //support nylon tube
- Float_t wideSupport=zSi+3*zPCB+2*NylonTube[2]+zHoneyComb;
- cout<<" wideSupport "<<wideSupport<<endl;
-
- for (ifmd=0; ifmd<5; ifmd++)
- {
- sprintf(nameFMD,"FMD%d",ifmd+1);
- ppcon[0]=0;
- ppcon[1]=360;
- ppcon[2]=4;
-
- ppcon[3]=-wideSupport;
- ppcon[4]=rin[ifmd]+0.1;
- ppcon[5]=rout[ifmd]+0.1;
-
- ppcon[6]=ppcon[3]+2*zSi+2*zPCB+2*NylonTube[2];
- ppcon[7]=rin[ifmd]+0.1;
- ppcon[8]=rout[ifmd]+0.1;
-
- ppcon[9]=ppcon[6];
- ppcon[10]=RinHoneyComb[ifmd]+0.1;
- ppcon[11]=RoutHoneyComb[ifmd]+0.1;
-
- ppcon[12]=ppcon[9]+2*zHoneyComb+zPCB;
- ppcon[13]=RinHoneyComb[ifmd]+0.1;
- ppcon[14]=RoutHoneyComb[ifmd]+0.1;
- gMC->Gsvolu(nameFMD,"PCON",idtmed[0],ppcon,15);
- if (z[ifmd] >0){
- zFMD=z[ifmd]+wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,0, "ONLY");}
- else {
- zFMD=z[ifmd]-wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,idrotm[901], "ONLY");}
- //silicon
- sprintf(nameSi,"GSI%d",ifmd+1);
- sprintf(nameSector,"GSC%d",ifmd+1);
- sprintf(nameRing,"GRN%d",ifmd+1);
-
- //honeycomb support
- sprintf(nameHoney,"GSU%d",ifmd+1);
- gMC->Gsvolu(nameHoney,"TUBE", idtmed[0], par, 0); //honeycomb
- sprintf(nameHoneyIn,"GHI%d",ifmd+1);
- gMC->Gsvolu(nameHoneyIn,"TUBE", idtmed[7], par, 0); //honey comb inside
- sprintf(nameHoneyOut,"GHO%d",ifmd+1);
- gMC->Gsvolu(nameHoneyOut,"TUBE", idtmed[6], par, 0); //honey comb skin
- //PCB
- sprintf(namePCB,"GPC%d",ifmd+1);
- gMC->Gsvolu(namePCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameCopper,"GCO%d",ifmd+1);
- gMC->Gsvolu(nameCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameChips,"GCH%d",ifmd+1);
- gMC->Gsvolu(nameChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameG10,"G10%d",ifmd+1);
- gMC->Gsvolu(nameG10,"TUBE", idtmed[2], par, 0); //G10 plate
- //last PCB
- sprintf(nameLPCB,"GPL%d",ifmd+1);
- gMC->Gsvolu(nameLPCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameLCopper,"GCL%d",ifmd+1);
- gMC->Gsvolu(nameLCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameLChips,"GHL%d",ifmd+1);
- gMC->Gsvolu(nameLChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameGL10,"G1L%d",ifmd+1);
- gMC->Gsvolu(nameGL10,"TUBE", idtmed[2], par, 0); // Last G10
- par[0]=rin[ifmd]; // pipe size
- par[1]=rout[ifmd];
- par[2]=zSi/2;
- gMC->Gsvolu(nameSi,"TUBE", idtmed[4], par, 3);
- zInside=ppcon[3]+par[2];
- gMC->Gspos(nameSi,ifmd+1,nameFMD,0,0,zInside,0, "ONLY");
- //PCB 1
- zInside += par[2]+zPCB/2;
- par[2]=zPCB/2;
- gMC->Gsposp(namePCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- zInside += zPCB;
- gMC->Gsposp(namePCB,2,nameFMD,0,0,zInside,0, "ONLY",par,3);
- Float_t NulonTubeBegin=zInside+2.5*zPCB;
- par[2]=zPCB/2-0.02;
- Float_t zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameG10,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameCopper,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameChips,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- //HoneyComb
- zHoneyComb=0.8;
- par[0] = RinHoneyComb[ifmd];
- par[1] = RoutHoneyComb[ifmd];
- par[2] = zHoneyComb/2;
- zInside += 2*NylonTube[2]+par[2];
- gMC->Gsposp(nameHoney,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- par[2]=0.1/2;
- Float_t zHoney=-zHoneyComb/2+par[2];
- gMC->Gsposp(nameHoneyOut,1,nameHoney,0,0,zHoney,0,
- "ONLY",par,3); //shkurki
- zHoney=zHoneyComb/2-par[2];
- gMC->Gsposp(nameHoneyOut,2,nameHoney,0,0,zHoney,0, "ONLY",par,3);
- par[2]=(zHoneyComb-2.*0.1)/2; //soty vnutri
- gMC->Gsposp(nameHoneyIn,1,nameHoney,0,0,0,0, "ONLY",par,3);
-
- gMC->Gspos("GNYL",1,nameFMD,0,yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
- gMC->Gspos("GNYL",2,nameFMD,0,-yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
-
- //last PCB
- par[0]=RoutHoneyComb[ifmd]-9;
- par[1]=RoutHoneyComb[ifmd];
- par[2]=zPCB/2;
- zInside += zHoneyComb/2+par[2];
- gMC->Gsposp(nameLPCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
-
- par[2]=zPCB/2-0.02;
- zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameGL10,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameLCopper,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameLChips,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
-
-
- //Granularity
- fSectorsSi1=20;
- fRingsSi1=256*2;
- // fRingsSi1=3; // for drawing only
- fSectorsSi2=40;
- fRingsSi2=128*2;
- // fRingsSi2=3; //for drawing onl
- if(ifmd==1||ifmd==3)
- {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi2, 2);
- gMC->Gsdvn(nameRing, nameSector, fRingsSi2, 1);
- }
- else
- {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi1, 2);
- gMC->Gsdvn(nameRing, nameSector , fRingsSi1, 1);
- }
-
- }
-}
-
-
-//------------------------------------------------------------------------
-void AliFMDv0::CreateMaterials()
-{
- Int_t isxfld = gAlice->Field()->Integ();
- Float_t sxmgmx = gAlice->Field()->Max();
-
- // Plastic CH
- Float_t aPlastic[2]={1.01,12.01};
- Float_t zPlastic[2]={1,6};
- Float_t wPlastic[2]={1,1};
- Float_t denPlastic=1.03;
- //
- // 60% SiO2 , 40% G10FR4
- // PC board
- Float_t apcb[3] = { 28.0855,15.9994,17.749 };
- Float_t zpcb[3] = { 14.,8.,8.875 };
- Float_t wpcb[3] = { .28,.32,.4 };
- Float_t denspcb = 1.8;
- //
-// AIR
- Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
-Float_t zAir[4]={6.,7.,8.,18.};
-Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
-Float_t dAir = 1.20479E-3;
- //*** Definition Of avaible FMD materials ***
- AliMixture(0, "FMD Air$", aAir, zAir, dAir, 4,wAir);
- AliMixture(1, "Plastic$",aPlastic,zPlastic,denPlastic,-2,wPlastic);
- AliMixture(2, "SSD PCB$", apcb, zpcb, denspcb, 3, wpcb);
- AliMaterial(3, "SSD Copper$", 63.546, 29., 8.96, 1.43, 999.);
- AliMaterial(4, "SSD Si$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(5, "SSD Si chip$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(6, "SSD C$", 12.011, 6., 2.265,18.8, 999.);
- AliMaterial(7, "SSD Kapton$", 12.011, 6., 0.01, 31.27, 999.);//honeycomb
- AliMaterial(8, "SSD G10FR4$", 17.749, 8.875, 1.8, 21.822, 999.);
-
-
-//**
- AliMedium(0, "FMD air$", 0, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(1, "Plastic$", 1, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(2, "SSD PCB$", 2, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(3, "SSD Copper$", 3, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(4, "SSD Si$", 4, 1, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(5, "SSD Si chip$", 5, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(6, "SSD C$", 6, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(7, "SSD Kapton$", 7, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(8, "SSD G10FR4$", 8, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
-
-
-
-}
-//---------------------------------------------------------------------
-void AliFMDv0::DrawDetector()
-{
-//
-// Draw a shaded view of the Forward multiplicity detector version 0
-//
-
-
-//Set ALIC mother transparent
-gMC->Gsatt("ALIC","SEEN",0);
-//
-//Set volumes visible
-gMC->Gsatt("FMD0","SEEN",1);
-gMC->Gsatt("FMD1","SEEN",1);
-gMC->Gsatt("FMD2","SEEN",1);
-gMC->Gsatt("FMD3","SEEN",1);
-gMC->Gsatt("FMD4","SEEN",1);
-gMC->Gsatt("FMD5","SEEN",1);
-
-//
-gMC->Gdopt("hide","on");
-gMC->Gdopt("shad","on");
-gMC->SetClipBox(".");
-gMC->SetClipBox("*",0,1000,-1000,1000,-1000,1000);
-gMC->DefaultRange();
-gMC->Gdraw("alic",40,30,0,12,9.5,.2,0.2);
-gMC->Gdhead(1111,"Forward multiplicity detector");
-gMC->Gdopt("hide","off");
-}
-//-------------------------------------------------------------------
-void AliFMDv0::Init()
-{
-// Initialises version 0 of the Forward Multiplicity Detector
-//
-AliFMD::Init();
-fIdSens1=gMC->VolId("GRN1");
-fIdSens2=gMC->VolId("GRN2");
-fIdSens3=gMC->VolId("GRN3");
-fIdSens4=gMC->VolId("GRN4");
-fIdSens5=gMC->VolId("GRN5");
-if (fDebug) printf("*** FMD version 0 initialized ***\n");
-}
-
-//-------------------------------------------------------------------
-
-void AliFMDv0::StepManager()
-{
- //
- // Called for every step in the Forward Multiplicity Detector
- //
-}
-
+++ /dev/null
-#ifndef ALIFMDV0_H
-#define ALIFMDV0_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
-///////////////////////////////////////////////
-// Manager and hits classes for set:FMD //
-////////////////////////////////////////////////
-
-#include "AliFMD.h"
-
-class AliFMDv0 : public AliFMD {
-
-public:
- AliFMDv0() {};
- AliFMDv0(const char *name, const char *title);
- virtual ~AliFMDv0() {}
- virtual void CreateGeometry();
- virtual void CreateMaterials();
- virtual void DrawDetector();
- virtual void Init();
- virtual Int_t IsVersion() const {return 0;}
- virtual void StepManager();
-
-protected:
- Int_t fIdSens1; // Sensetive volume in FMD
- Int_t fIdSens2; // Sensetive volume in FMD
- Int_t fIdSens3; // Sensetive volume in FMD
- Int_t fIdSens4; // Sensetive volume in FMD
- Int_t fIdSens5; // Sensetive volume in FMD
-
-
-
- ClassDef(AliFMDv0,2) //Class for FMD version 0
-};
-
-#endif
-
-
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
- /////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity detector based on Silicon version 0 //
-//
-//Begin Html
-/*
-<img src="gif/AliFMDv0Class.gif">
-*/
-//End Html
-// //
-// //
-//////////////////////////////////////////////////////////////////////
-
-#include <Riostream.h>
-#include <stdlib.h>
-
-#include <TClonesArray.h>
-#include <TDirectory.h>
-#include <TFile.h>
-#include <TGeometry.h>
-#include <TLorentzVector.h>
-#include <TMath.h>
-#include <TNode.h>
-#include <TTUBE.h>
-#include <TTree.h>
-#include <TVirtualMC.h>
-
-#include "AliFMDdigit.h"
-#include "AliFMDhit.h"
-#include "AliFMDv0.h"
-#include "AliFMDv1.h"
-#include "AliMagF.h"
-#include "AliRun.h"
-#include "AliMC.h"
-
-ClassImp(AliFMDv1)
-
-//--------------------------------------------------------------------
-AliFMDv1::AliFMDv1(const char *name, const char *title):
- AliFMD(name,title)
-{
- //
- // Standart constructor for Forward Multiplicity Detector version 0
- //
- fIdSens1=0;
- fIdSens2=0;
- fIdSens3=0;
- fIdSens4=0;
- fIdSens5=0;
-// setBufferSize(128000);
- }
-//-------------------------------------------------------------------------
-void AliFMDv1::CreateGeometry()
-{
- //
- // Create the geometry of Forward Multiplicity Detector version 0
- //
- //Detector consists of 6 volumes:
- // 1st covered pseudorapidity interval from 3.3 to 2.0
- // and placed on 65cm in Z-direction;
- // 2nd - from 2.0 to 1.6 and Z=85 cm;
- // 3d - the same pseudorapidity interval as the 1st
- // but on the other side from the interaction point z=-65cm;
- // 4th - simmetricaly with the 2nd :
- // pseudorapidity from 2.0 to 1.6, Z=-85cm
- // 5th - from 3.6 to 4.7, Z=-270cm
- // 6th - from 4.5 to 5.5 , Z=-630cm.
- // Each part has 400mkm Si (sensetive area, detector itself),
- // 0.75cm of plastic simulated electronics material,
- // Al support ring 2cm thickness and 1cm width placed on
- // the outer radius of each Si disk;
- //
- // begin Html
- /*
- <img src="gif/AliFMDv0.gif">
- */
- //
-
-
-
- Int_t *idtmed = fIdtmed->GetArray();
-
- Int_t ifmd;
- Int_t idrotm[999];
- /*<<<<<<< AliFMDv1.cxx
- Float_t zFMD,par[3],ppcon[15];
- Float_t z[5]={62.8, 75.2, -83.4, -75.2, -340.};
- Float_t NylonTube[3]={0.2,0.6,0.45};
- Float_t zPCB=0.12; Float_t zHoneyComb=0.5;
- Float_t zSi=0.03;
-
- char nameFMD[5], nameSi[5], nameSector[5], nameRing[5];
- Char_t nameHoney[5], nameHoneyIn[5], nameHoneyOut[5];
- Char_t namePCB[5], nameCopper[5], nameChips[5], nameG10[5];
- Char_t nameLPCB[5], nameLCopper[5], nameLChips[5], nameGL10[5];;
- Float_t rin[5]={4.2,15.4,4.2,15.4,4.2};
- Float_t rout[5]={17.4,28.4,17.4,28.4,17.4};
- Float_t RinHoneyComb[5] ={ 5.15,16.4, 5.15,16.4, 5.15};
- Float_t RoutHoneyComb[5]={20.63,34.92,22.3, 32.02,20.63};
- Float_t zInside;
- Float_t zCooper=0.01; Float_t zChips=0.01;
- Float_t yNylonTube[5]={10,20,10,20,10};
- =======*/
- Float_t zFMD,par[3],ppcon[15];
- Float_t z[5]={-62.8, -75.2, 83.4, 75.2, 340.};
- Float_t NylonTube[3]={0.2,0.6,0.45};
- Float_t zPCB=0.12; Float_t zHoneyComb=0.5;
- Float_t zSi=0.03;
-
- char nameFMD[5], nameSi[5], nameSector[5], nameRing[5];
- Char_t nameHoney[5], nameHoneyIn[5], nameHoneyOut[5];
- Char_t namePCB[5], nameCopper[5], nameChips[5], nameG10[5];
- Char_t nameLPCB[5], nameLCopper[5], nameLChips[5], nameGL10[5];;
- Float_t rin[5]={4.2,15.4,4.2,15.4,4.2};
- Float_t rout[5]={17.4,28.4,17.4,28.4,17.4};
- Float_t RinHoneyComb[5] ={ 5.15,16.4, 5.15,16.4, 5.15};
- Float_t RoutHoneyComb[5]={20.63,34.92,22.3, 32.02,20.63};
- Float_t zInside;
- Float_t zCooper=0.01; Float_t zChips=0.01;
- Float_t yNylonTube[5]={10,20,10,20,10};
- //>>>>>>> 1.25
-
-
- AliMatrix(idrotm[901], 90, 0, 90, 90, 180, 0);
-
-
- // Nylon tubes
- gMC->Gsvolu("GNYL","TUBE", idtmed[1], NylonTube, 3); //support nylon tube
- Float_t wideSupport=zSi+3*zPCB+2*NylonTube[2]+zHoneyComb;
- cout<<" wideSupport "<<wideSupport<<endl;
-
- for (ifmd=0; ifmd<5; ifmd++)
- {
- sprintf(nameFMD,"FMD%d",ifmd+1);
- ppcon[0]=0;
- ppcon[1]=360;
- ppcon[2]=4;
-
- ppcon[3]=-wideSupport;
- ppcon[4]=rin[ifmd]-0.1;
- ppcon[5]=rout[ifmd]+0.1;
-
- ppcon[6]=ppcon[3]+2*zSi+2*zPCB+2*NylonTube[2];
- ppcon[7]=rin[ifmd]-0.1;
- ppcon[8]=rout[ifmd]+0.1;
-
- ppcon[9]=ppcon[6];
- ppcon[10]=RinHoneyComb[ifmd]-0.1;
- ppcon[11]=RoutHoneyComb[ifmd]+0.1;
-
- ppcon[12]=ppcon[9]+2*zHoneyComb+zPCB;
- ppcon[13]=RinHoneyComb[ifmd]-0.1;
- ppcon[14]=RoutHoneyComb[ifmd]+0.1;
- gMC->Gsvolu(nameFMD,"PCON",idtmed[0],ppcon,15);
- if (z[ifmd] >0){
- zFMD=z[ifmd]+wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,0, "ONLY");}
- else {
- zFMD=z[ifmd]-wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,idrotm[901], "ONLY");}
- //silicon
- sprintf(nameSi,"GSI%d",ifmd+1);
- sprintf(nameSector,"GSC%d",ifmd+1);
- sprintf(nameRing,"GRN%d",ifmd+1);
-
- //honeycomb support
- sprintf(nameHoney,"GSU%d",ifmd+1);
- gMC->Gsvolu(nameHoney,"TUBE", idtmed[0], par, 0); //honeycomb
- sprintf(nameHoneyIn,"GHI%d",ifmd+1);
- gMC->Gsvolu(nameHoneyIn,"TUBE", idtmed[7], par, 0); //honey comb inside
- sprintf(nameHoneyOut,"GHO%d",ifmd+1);
- gMC->Gsvolu(nameHoneyOut,"TUBE", idtmed[6], par, 0); //honey comb skin
- //PCB
- sprintf(namePCB,"GPC%d",ifmd+1);
- gMC->Gsvolu(namePCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameCopper,"GCO%d",ifmd+1);
- gMC->Gsvolu(nameCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameChips,"GCH%d",ifmd+1);
- gMC->Gsvolu(nameChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameG10,"G10%d",ifmd+1);
- gMC->Gsvolu(nameG10,"TUBE", idtmed[2], par, 0); //G10 plate
- //last PCB
- sprintf(nameLPCB,"GPL%d",ifmd+1);
- gMC->Gsvolu(nameLPCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameLCopper,"GCL%d",ifmd+1);
- gMC->Gsvolu(nameLCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameLChips,"GHL%d",ifmd+1);
- gMC->Gsvolu(nameLChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameGL10,"G1L%d",ifmd+1);
- gMC->Gsvolu(nameGL10,"TUBE", idtmed[2], par, 0); // Last G10
- par[0]=rin[ifmd]; // pipe size
- par[1]=rout[ifmd];
- par[2]=zSi/2;
- gMC->Gsvolu(nameSi,"TUBE", idtmed[4], par, 3);
- zInside=ppcon[3]+par[2];
- gMC->Gspos(nameSi,ifmd+1,nameFMD,0,0,zInside,0, "ONLY");
- //PCB 1
- zInside += par[2]+zPCB/2;
- par[2]=zPCB/2;
- gMC->Gsposp(namePCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- zInside += zPCB;
- gMC->Gsposp(namePCB,2,nameFMD,0,0,zInside,0, "ONLY",par,3);
- Float_t NulonTubeBegin=zInside+2.5*zPCB;
- par[2]=zPCB/2-0.02;
- Float_t zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameG10,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameCopper,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameChips,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- //HoneyComb
- zHoneyComb=0.8;
- par[0] = RinHoneyComb[ifmd];
- par[1] = RoutHoneyComb[ifmd];
- par[2] = zHoneyComb/2;
- zInside += 2*NylonTube[2]+par[2];
- gMC->Gsposp(nameHoney,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- par[2]=0.1/2;
- Float_t zHoney=-zHoneyComb/2+par[2];
- gMC->Gsposp(nameHoneyOut,1,nameHoney,0,0,zHoney,0,
- "ONLY",par,3); //shkurki
- zHoney=zHoneyComb/2-par[2];
- gMC->Gsposp(nameHoneyOut,2,nameHoney,0,0,zHoney,0, "ONLY",par,3);
- par[2]=(zHoneyComb-2.*0.1)/2; //soty vnutri
- gMC->Gsposp(nameHoneyIn,1,nameHoney,0,0,0,0, "ONLY",par,3);
-
- gMC->Gspos("GNYL",1,nameFMD,0,yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
- gMC->Gspos("GNYL",2,nameFMD,0,-yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
-
- //last PCB
- par[0]=RoutHoneyComb[ifmd]-9;
- par[1]=RoutHoneyComb[ifmd];
- par[2]=zPCB/2;
- zInside += zHoneyComb/2+par[2];
- gMC->Gsposp(nameLPCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
-
- par[2]=zPCB/2-0.02;
- zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameGL10,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameLCopper,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameLChips,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
-
-
- //Granularity
- fSectorsSi1=20;
- fRingsSi1=256*2;
- // fRingsSi1=3; // for drawing only
- fSectorsSi2=40;
- fRingsSi2=128*2;
- // fRingsSi2=3; //for drawing onl
- if(ifmd==1||ifmd==3)
- {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi2, 2);
- gMC->Gsdvn(nameRing, nameSector, fRingsSi2, 1);
- }
- else
- {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi1, 2);
- gMC->Gsdvn(nameRing, nameSector , fRingsSi1, 1);
- }
-
- }
-}
-
-
-//------------------------------------------------------------------------
-void AliFMDv1::CreateMaterials()
-{
- Int_t isxfld = gAlice->Field()->Integ();
- Float_t sxmgmx = gAlice->Field()->Max();
-
- // Plastic CH
- Float_t aPlastic[2]={1.01,12.01};
- Float_t zPlastic[2]={1,6};
- Float_t wPlastic[2]={1,1};
- Float_t denPlastic=1.03;
- //
- // 60% SiO2 , 40% G10FR4
- // PC board
- Float_t apcb[3] = { 28.0855,15.9994,17.749 };
- Float_t zpcb[3] = { 14.,8.,8.875 };
- Float_t wpcb[3] = { .28,.32,.4 };
- Float_t denspcb = 1.8;
- //
-// AIR
- Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
-Float_t zAir[4]={6.,7.,8.,18.};
-Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
-Float_t dAir = 1.20479E-3;
- //*** Definition Of avaible FMD materials ***
- AliMixture(0, "FMD Air$", aAir, zAir, dAir, 4,wAir);
- AliMixture(1, "Plastic$",aPlastic,zPlastic,denPlastic,-2,wPlastic);
- AliMixture(2, "SSD PCB$", apcb, zpcb, denspcb, 3, wpcb);
- AliMaterial(3, "SSD Copper$", 63.546, 29., 8.96, 1.43, 999.);
- AliMaterial(4, "SSD Si$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(5, "SSD Si chip$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(6, "SSD C$", 12.011, 6., 2.265,18.8, 999.);
- AliMaterial(7, "SSD Kapton$", 12.011, 6., 0.01, 31.27, 999.);//honeycomb
- AliMaterial(8, "SSD G10FR4$", 17.749, 8.875, 1.8, 21.822, 999.);
-
-
-//**
- AliMedium(0, "FMD air$", 0, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(1, "Plastic$", 1, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(2, "SSD PCB$", 2, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(3, "SSD Copper$", 3, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(4, "SSD Si$", 4, 1, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(5, "SSD Si chip$", 5, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(6, "SSD C$", 6, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(7, "SSD Kapton$", 7, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(8, "SSD G10FR4$", 8, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
-
-
-
-}
-//---------------------------------------------------------------------
-void AliFMDv1::DrawDetector()
-{
-//
-// Draw a shaded view of the Forward multiplicity detector version 0
-//
-
-//Set ALIC mother transparent
-gMC->Gsatt("ALIC","SEEN",0);
-//
-//Set volumes visible
-gMC->Gsatt("FMD1","SEEN",1);
-gMC->Gsatt("FMD2","SEEN",1);
-gMC->Gsatt("FMD3","SEEN",1);
-gMC->Gsatt("FMD4","SEEN",1);
-gMC->Gsatt("FMD5","SEEN",1);
-
-//
-gMC->Gdopt("hide","on");
-gMC->Gdopt("shad","on");
-gMC->SetClipBox(".");
-gMC->SetClipBox("*",0,1000,-1000,1000,-1000,1000);
-gMC->DefaultRange();
-gMC->Gdraw("alic",40,30,0,12,9.5,.2,0.2);
-gMC->Gdhead(1111,"Forward multiplicity detector");
-gMC->Gdopt("hide","off");
-}
-//-------------------------------------------------------------------
-void AliFMDv1::Init()
-{
-// Initialises version 0 of the Forward Multiplicity Detector
-//
-AliFMD::Init();
-fIdSens1=gMC->VolId("GRN1");
-fIdSens2=gMC->VolId("GRN2");
-fIdSens3=gMC->VolId("GRN3");
-fIdSens4=gMC->VolId("GRN4");
-fIdSens5=gMC->VolId("GRN5");
-printf("*** FMD version 1 initialized ***\n");
-}
-
-//-------------------------------------------------------------------
-
-void AliFMDv1::StepManager()
-{
- //
- // Called for every step in the Forward Multiplicity Detector
- //
- Int_t id,copy,copy1,copy2;
- static Float_t hits[9];
- static Int_t vol[3];
- static Float_t de;
- TLorentzVector pos;
- TLorentzVector mom;
-
-
- TClonesArray &lhits = *fHits;
- if(!gMC->IsTrackAlive()) return; // particle has disappeared
-
- Float_t charge = gMC->TrackCharge();
- if(TMath::Abs(charge)<=0.) return; //take only charged particles
-
- // printf(" in StepManeger \n");
- id=gMC->CurrentVolID(copy);
- //((TGeant3*)gMC)->Gpcxyz();
-
-// Check the sensetive volume
- if(id==fIdSens1||id==fIdSens2||id==fIdSens3||id==fIdSens4||id==fIdSens5)
- {
- if(gMC->IsTrackEntering())
- {
- vol[2]=copy;
- gMC->CurrentVolOffID(1,copy1);
- vol[1]=copy1;
- gMC->CurrentVolOffID(2,copy2);
- vol[0]=copy2;
-
- gMC->TrackPosition(pos);
- hits[0]=pos[0];
- hits[1]=pos[1];
- hits[2]=pos[2];
-
- gMC->TrackMomentum(mom);
- hits[3]=mom[0];
- hits[4]=mom[1];
- hits[5]=mom[2];
-
- Int_t iPart= gMC->TrackPid();
- Int_t partId=gMC->IdFromPDG(iPart);
- hits[7]=partId;
- hits[8]=1e9*gMC->TrackTime();
- de=0.;
- }
- if(gMC->IsTrackInside()){
- de=de+1000.*gMC->Edep();
- }
-
- if(gMC->IsTrackExiting()
- ||gMC->IsTrackDisappeared()||
- gMC->IsTrackStop())
- {
- hits[6]=de+1000.*gMC->Edep();
- new(lhits[fNhits++]) AliFMDhit(fIshunt,gAlice->GetMCApp()->GetCurrentTrackNumber(),vol,hits);
- } // IsTrackExiting()
- }
- }
-//--------------------------------------------------------------------------
-
-void AliFMDv1::Response( Float_t Edep)
-{
- Float_t I=1.664*0.04*2.33/22400; // = 0.69e-6;
- Float_t chargeOnly=Edep/I;
- //Add noise ~500electrons
- Int_t charge=500;
- if (Edep>0)
- charge=Int_t(gRandom->Gaus(chargeOnly,500));
- }
-
-
-
-
-
-
+++ /dev/null
-#ifndef ALIFMDV1_H
-#define ALIFMDV1_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
-///////////////////////////////////////////////
-// Manager and hits classes for set:FMD //
-////////////////////////////////////////////////
-
-#include "AliFMD.h"
-
-class AliFMDv1 : public AliFMD {
-
-public:
- AliFMDv1() {};
- AliFMDv1(const char *name, const char *title);
- virtual ~AliFMDv1() {}
- virtual void CreateGeometry();
- virtual void CreateMaterials();
- virtual void DrawDetector();
- virtual void Init();
- virtual Int_t IsVersion() const {return 1;}
- virtual void StepManager();
- // virtual void Hit2Digits(Int_t bgrEvent, Option_t *opt1=" ",
- // Option_t *opt2=" ",Text_t *name=" "); // hit to digit for v1 :test
- virtual void Response( Float_t Edep);
-//private:
- //Int_t fCharge;
-
-
-protected:
- Int_t fIdSens1; // Sensetive volume in FMD
- Int_t fIdSens2; // Sensetive volume in FMD
- Int_t fIdSens3; // Sensetive volume in FMD
- Int_t fIdSens4; // Sensetive volume in FMD
- Int_t fIdSens5; // Sensetive volume in FMD
-
-
-// Background event for event mixing
-
- ClassDef(AliFMDv1,2) //Class for FMD version 0
-};
-
-#endif
-
-
--- /dev/null
+// One can use the configuration macro in compiled mode by
+// root [0] gSystem->Load("libgeant321");
+// root [0] gSystem->SetIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include\
+// -I$ALICE_ROOT -I$ALICE/geant3/TGeant3");
+// root [0] .x grun.C(1,"Config.C++")
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <Riostream.h>
+#include <TRandom.h>
+#include <TSystem.h>
+#include <TVirtualMC.h>
+#include <TGeant3.h>
+#include "STEER/AliRunLoader.h"
+#include "STEER/AliRun.h"
+#include "STEER/AliConfig.h"
+#include "PYTHIA6/AliDecayerPythia.h"
+#include "EVGEN/AliGenCocktail.h"
+#include "EVGEN/AliGenHIJINGpara.h"
+#include "STEER/AliMagFMaps.h"
+#include "STRUCT/AliBODY.h"
+#include "STRUCT/AliMAG.h"
+#include "STRUCT/AliABSOv0.h"
+#include "STRUCT/AliDIPOv2.h"
+#include "STRUCT/AliHALL.h"
+#include "STRUCT/AliFRAMEv2.h"
+#include "STRUCT/AliSHILv2.h"
+#include "STRUCT/AliPIPEv0.h"
+#include "ITS/AliITSvPPRasymmFMD.h"
+#include "TPC/AliTPCv2.h"
+#include "TOF/AliTOFv4T0.h"
+#include "RICH/AliRICHv1.h"
+#include "ZDC/AliZDCv2.h"
+#include "TRD/AliTRDv1.h"
+#include "FMD/AliFMDv1.h"
+#include "MUON/AliMUONv1.h"
+#include "MUON/AliMUONSt1GeometryBuilder.h"
+#include "MUON/AliMUONSt2GeometryBuilder.h"
+#include "MUON/AliMUONSlatGeometryBuilder.h"
+#include "MUON/AliMUONTriggerGeometryBuilder.h"
+#include "PHOS/AliPHOSv1.h"
+#include "PMD/AliPMDv1.h"
+#include "START/AliSTARTv1.h"
+#include "EMCAL/AliEMCALv1.h"
+#include "CRT/AliCRTv0.h"
+#include "VZERO/AliVZEROv3.h"
+#endif
+
+Float_t EtaToTheta(Float_t arg);
+static Int_t eventsPerRun = 100;
+enum PprGeo_t
+{
+ kHoles, kNoHoles
+};
+static PprGeo_t geo = kHoles;
+
+void Config()
+{
+ // ThetaRange is (0., 180.). It was (0.28,179.72) 7/12/00 09:00
+ // Theta range given through pseudorapidity limits 22/6/2001
+
+ // Set Random Number seed
+ gRandom->SetSeed(123456); // Set 0 to use the currecnt time
+ cout<<"Seed for random number generation= "<<gRandom->GetSeed()<<endl;
+
+
+ // libraries required by geant321
+#if defined(__CINT__)
+ gSystem->Load("libgeant321");
+#endif
+
+ new TGeant3("C++ Interface to Geant3");
+
+ AliRunLoader* rl = 0;
+ cout<<"Config.C: Creating Run Loader ..."<<endl;
+ rl = AliRunLoader::Open("galice.root",
+ AliConfig::GetDefaultEventFolderName(),
+ "recreate");
+ if (!rl) {
+ gAlice->Fatal("Config.C","Can not instatiate the Run Loader");
+ return;
+ }
+ rl->SetCompressionLevel(2);
+ rl->SetNumberOfEventsPerFile(3);
+ gAlice->SetRunLoader(rl);
+
+ //
+ // Set External decayer
+ TVirtualMCDecayer *decayer = new AliDecayerPythia();
+ decayer->SetForceDecay(kAll);
+ decayer->Init();
+ gMC->SetExternalDecayer(decayer);
+
+ //=======================================================================
+ // ************* STEERING parameters FOR ALICE SIMULATION **************
+ // --- Specify event type to be tracked through the ALICE setup
+ // --- All positions are in cm, angles in degrees, and P and E in GeV
+ gMC->SetProcess("DCAY",1);
+ gMC->SetProcess("PAIR",1);
+ gMC->SetProcess("COMP",1);
+ gMC->SetProcess("PHOT",1);
+ gMC->SetProcess("PFIS",0);
+ gMC->SetProcess("DRAY",0);
+ gMC->SetProcess("ANNI",1);
+ gMC->SetProcess("BREM",1);
+ gMC->SetProcess("MUNU",1);
+ gMC->SetProcess("CKOV",1);
+ gMC->SetProcess("HADR",1);
+ gMC->SetProcess("LOSS",2);
+ gMC->SetProcess("MULS",1);
+ gMC->SetProcess("RAYL",1);
+
+ Float_t cut = 1.e-3; // 1MeV cut by default
+ Float_t tofmax = 1.e10;
+
+ gMC->SetCut("CUTGAM", cut);
+ gMC->SetCut("CUTELE", cut);
+ gMC->SetCut("CUTNEU", cut);
+ gMC->SetCut("CUTHAD", cut);
+ gMC->SetCut("CUTMUO", cut);
+ gMC->SetCut("BCUTE", cut);
+ gMC->SetCut("BCUTM", cut);
+ gMC->SetCut("DCUTE", cut);
+ gMC->SetCut("DCUTM", cut);
+ gMC->SetCut("PPCUTM", cut);
+ gMC->SetCut("TOFMAX", tofmax);
+
+ int nParticles = 100;
+ if (gSystem->Getenv("CONFIG_NPARTICLES"))
+ nParticles = atoi(gSystem->Getenv("CONFIG_NPARTICLES"));
+
+ AliGenCocktail *gener = new AliGenCocktail();
+ gener->SetPhiRange(0, 360);
+ // Set pseudorapidity range from -8 to 8.
+ Float_t thmin = EtaToTheta(8); // theta min. <---> eta max
+ Float_t thmax = EtaToTheta(-8); // theta max. <---> eta min
+ gener->SetThetaRange(thmin,thmax);
+ gener->SetOrigin(0, 0, 0); //vertex position
+ gener->SetSigma(0, 0, 0); //Sigma in (X,Y,Z) (cm) on IP position
+
+ AliGenHIJINGpara *hijingparam = new AliGenHIJINGpara(nParticles);
+ hijingparam->SetMomentumRange(0.2, 999);
+ gener->AddGenerator(hijingparam,"HIJING PARAM",1);
+
+ // AliGenBox *genbox = new AliGenBox(nParticles);
+ // genbox->SetPart(22);
+ // genbox->SetPtRange(0.3, 10.00);
+ // gener->AddGenerator(genbox,"GENBOX GAMMA for PHOS",1);
+ gener->Init();
+
+ // Activate this line if you want the vertex smearing to happen
+ // track by track
+ //
+ //gener->SetVertexSmear(perTrack);
+ // Field (L3 0.4 T)
+ AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., 1);
+ gAlice->SetField(field);
+
+
+ Bool_t useABSO = kFALSE;
+ Bool_t useDIPO = kFALSE;
+ Bool_t useFMD = kTRUE;
+ Bool_t useFRAME = kFALSE;
+ Bool_t useHALL = kFALSE;
+ Bool_t useITS = kFALSE;
+ Bool_t useMAG = kFALSE;
+ Bool_t useMUON = kFALSE;
+ Bool_t usePHOS = kFALSE;
+ Bool_t usePIPE = kFALSE;
+ Bool_t usePMD = kFALSE;
+ Bool_t useRICH = kFALSE;
+ Bool_t useSHIL = kFALSE;
+ Bool_t useSTART = kFALSE;
+ Bool_t useTOF = kFALSE;
+ Bool_t useTPC = kFALSE;
+ Bool_t useTRD = kFALSE;
+ Bool_t useZDC = kFALSE;
+ Bool_t useEMCAL = kFALSE;
+ Bool_t useCRT = kFALSE;
+ Bool_t useVZERO = kFALSE;
+ rl->CdGAFile();
+
+ //=================== Alice BODY parameters =============================
+ AliBODY *BODY = new AliBODY("BODY", "Alice envelop");
+
+ if (useMAG) {
+ //=================== MAG parameters ============================
+ // Start with Magnet since detector layouts may be depending ---
+ // on the selected Magnet dimensions ---
+ AliMAG *MAG = new AliMAG("MAG", "Magnet");
+ }
+
+ if (useABSO) {
+ //=================== ABSO parameters ============================
+ AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
+ }
+
+ if (useDIPO) {
+ //=================== DIPO parameters ============================
+ AliDIPO *DIPO = new AliDIPOv2("DIPO", "Dipole version 2");
+ }
+
+ if (useHALL) {
+ //=================== HALL parameters ============================
+ AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
+ }
+
+
+ if (useFRAME) {
+ //=================== FRAME parameters ============================
+ AliFRAMEv2 *FRAME = new AliFRAMEv2("FRAME", "Space Frame");
+ if (geo == kHoles) {
+ FRAME->SetHoles(1);
+ } else {
+ FRAME->SetHoles(0);
+ }
+ }
+
+ if (useSHIL) {
+ //=================== SHIL parameters ============================
+ AliSHIL *SHIL = new AliSHILv2("SHIL", "Shielding Version 2");
+ }
+
+
+ if (usePIPE) {
+ //=================== PIPE parameters ============================
+ AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
+ }
+
+ if(useITS) {
+ //=================== ITS parameters ============================
+ //
+ // As the innermost detector in ALICE, the Inner Tracking System
+ // "impacts" on almost all other detectors. This involves the fact
+ // that the ITS geometry still has several options to be followed
+ // in parallel in order to determine the best set-up which
+ // minimizes the induced background. All the geometries available
+ // to date are described in the following. Read carefully the
+ // comments and use the default version (the only one uncommented)
+ // unless you are making comparisons and you know what you are
+ // doing. In this case just uncomment the ITS geometry you want to
+ // use and run Aliroot.
+ //
+ // Detailed geometries:
+ //
+ //
+ //
+ AliITSvPPRasymmFMD *ITS
+ = new AliITSvPPRasymmFMD("ITS", "ITS PPR detailed version "
+ "with asymmetric services");
+ // don't touch this parameter if you're not an ITS developer
+ ITS->SetMinorVersion(2);
+ // don't touch this parameter if you're not an ITS developer
+ ITS->SetReadDet(kTRUE);
+ // don't touch this parameter if you're not an ITS developer
+ // ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymm2.det");
+ // detector thickness on layer 1 must be in the range [100,300]
+ ITS->SetThicknessDet1(200.);
+ // detector thickness on layer 2 must be in the range [100,300]
+ ITS->SetThicknessDet2(200.);
+ // chip thickness on layer 1 must be in the range [150,300]
+ ITS->SetThicknessChip1(200.);
+ // chip thickness on layer 2 must be in the range [150,300]
+ ITS->SetThicknessChip2(200.);
+ // 1 --> rails in ; 0 --> rails out
+ ITS->SetRails(0);
+ // 1 --> water ; 0 --> freon
+ ITS->SetCoolingFluid(1);
+
+
+ //
+ // Coarse geometries (warning: no hits are produced with these
+ // coarse geometries and they unuseful for reconstruction !):
+ //
+ //
+ // AliITSvPPRcoarseasymm *ITS =
+ // new AliITSvPPRcoarseasymm("ITS","New ITS PPR coarse version "
+ // "with asymmetric services");
+ // 1 --> rails in ; 0 --> rails out
+ // ITS->SetRails(0);
+ // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
+ // ITS->SetSupportMaterial(0);
+ //
+ // AliITS *ITS =
+ // new AliITSvPPRcoarsesymm("ITS","New ITS PPR coarse version "
+ // "with symmetric services");
+ // 1 --> rails in ; 0 --> rails out
+ // ITS->SetRails(0);
+ // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
+ // ITS->SetSupportMaterial(0);
+ //
+ //
+ //
+ // Geant3 <-> EUCLID conversion
+ // ============================
+ //
+ // SetEUCLID is a flag to output (=1) or not to output (=0) both
+ // geometry and media to two ASCII files (called by default
+ // ITSgeometry.euc and ITSgeometry.tme) in a format understandable
+ // to the CAD system EUCLID. The default (=0) means that you dont
+ // want to use this facility.
+ //
+ ITS->SetEUCLID(0);
+ }
+
+ if (useTPC) {
+ //============================ TPC parameters ====================
+ //
+ // This allows the user to specify sectors for the SLOW (TPC
+ // geometry 2) Simulator. SecAL (SecAU) <0 means that ALL lower
+ // (upper) sectors are specified, any value other than that
+ // requires at least one sector (lower or upper)to be specified!
+ //
+ // Reminder: sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0)
+ // sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0)
+ // SecLows - number of lower sectors specified (up to 6)
+ // SecUps - number of upper sectors specified (up to 12)
+ // Sens - sensitive strips for the Slow Simulator !!!
+ //
+ // This does NOT work if all S or L-sectors are specified, i.e.
+ // if SecAL or SecAU < 0
+ //
+ //
+ //----------------------------------------------------------------
+ // gROOT->LoadMacro("SetTPCParam.C");
+ // AliTPCParam *param = SetTPCParam();
+ AliTPC *TPC = new AliTPCv2("TPC", "Default");
+
+ // All sectors included
+ TPC->SetSecAU(-1);
+ TPC->SetSecAL(-1);
+ }
+
+ if (useTOF) {
+ //=================== TOF parameters ============================
+ AliTOF *TOF = new AliTOFv4T0("TOF", "normal TOF");
+ }
+
+ if (useRICH) {
+ //=================== RICH parameters ===========================
+ AliRICH *RICH = new AliRICHv1("RICH", "normal RICH");
+
+ }
+
+ if (useZDC) {
+ //=================== ZDC parameters ============================
+ AliZDC *ZDC = new AliZDCv2("ZDC", "normal ZDC");
+ }
+
+ if (useTRD) {
+ //=================== TRD parameters ============================
+ AliTRD *TRD = new AliTRDv1("TRD", "TRD slow simulator");
+
+ // Select the gas mixture (0: 97% Xe + 3% isobutane, 1: 90% Xe +
+ // 10% CO2)
+ TRD->SetGasMix(1);
+ if (geo == kHoles) {
+ // With hole in front of PHOS
+ TRD->SetPHOShole();
+ // With hole in front of RICH
+ TRD->SetRICHhole();
+ }
+ // Switch on TR
+ AliTRDsim *TRDsim = TRD->CreateTR();
+ }
+
+ if (useFMD) {
+ //=================== FMD parameters ============================
+ AliFMD *FMD = new AliFMDv1("FMD", "Detailed FMD");
+ }
+
+ if (useMUON) {
+ //=================== MUON parameters ===========================
+ AliMUON *MUON = new AliMUONv1("MUON", "default");
+ MUON->AddGeometryBuilder(new AliMUONSt1GeometryBuilder(MUON));
+ MUON->AddGeometryBuilder(new AliMUONSt2GeometryBuilder(MUON));
+ MUON->AddGeometryBuilder(new AliMUONSlatGeometryBuilder(MUON));
+ MUON->AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(MUON));
+ }
+
+ //=================== PHOS parameters ===========================
+ if (usePHOS) {
+ AliPHOS *PHOS = new AliPHOSv1("PHOS", "IHEP");
+ }
+
+ if (usePMD) {
+ //=================== PMD parameters ============================
+ AliPMD *PMD = new AliPMDv1("PMD", "normal PMD");
+ }
+
+ if (useSTART) {
+ //=================== START parameters ============================
+ AliSTART *START = new AliSTARTv1("START", "START Detector");
+ }
+
+ if (useEMCAL) {
+ //=================== EMCAL parameters ============================
+ AliEMCAL *EMCAL = new AliEMCALv1("EMCAL", "EMCAL_55_25");
+ }
+
+ if (useCRT) {
+ //=================== CRT parameters ============================
+ AliCRT *CRT = new AliCRTv0("CRT", "normal ACORDE");
+ }
+
+ if (useVZERO) {
+ //=================== CRT parameters ============================
+ AliVZERO *VZERO = new AliVZEROv3("VZERO", "normal VZERO");
+ }
+
+ cout << "End of FMD/Config.C" << endl;
+}
+
+Float_t EtaToTheta(Float_t arg){
+ return (180./TMath::Pi())*2.*atan(exp(-arg));
+}
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+// Script to do test the FMD digitization class.
+void
+Digitize()
+{
+ // Dynamically link some shared libs
+ if (gClassTable->GetID("AliRun") < 0) {
+ gROOT->LoadMacro("loadlibs.C");
+ loadlibs();
+ }
+ if (gAlice) {
+ delete gAlice;
+ gAlice = 0;
+ }
+
+ AliRunDigitizer * manager = new AliRunDigitizer(1,1);
+ manager->SetInputStream(0,"galice.root");
+ AliFMDDigitizer *FMD = new AliFMDDigitizer(manager);
+ manager->Exec("");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+// Script to do test the FMD digitization class.
+void
+Document()
+{
+ gEnv->SetValue("Root.Html.SourceDir", "$(ALICE)/FMD");
+ gEnv->SetValue("Root.Html.OutputDir", "$(ALICE)/FMD/html");
+
+ gSystem->MakeDirectory("$(ALICE)/FMD/html");
+
+ THtml* html = new THtml;
+ html->MakeAll(kFALSE, "AliFMD*");
+ html->Convert("$(ALICE)/FMD/Digitize.C", "Digitize",
+ "FMD/html/src");
+ html->Convert("$(ALICE)/FMD/Reconstruct.C", "Reconstruct",
+ "FMD/html/src");
+ html->Convert("$(ALICE)/FMD/Simulate.C", "Simulate",
+ "FMD/html/src");
+ html->Convert("$(ALICE)/FMD/DrawFMD.C", "DrawFMD",
+ "FMD/html/src");
+ html->Convert("$(ALICE)/FMD/ViewFMD.C", "ViewFMD",
+ "FMD/html/src");
+ html->MakeIndex("AliFMD*");
+
+ std::ofstream index("FMD/html/index.html");
+ html->WriteHtmlHeader(index, "ALICE FMD Code - Index page");
+
+ index << "<h1>ALICE FMD Code</h1>\n"
+ << "<ul>\n"
+ << "<li><a href=\"USER_Index.html\">Classes</a></li>\n"
+ << "<li><a href=\"src/Digitize.C.html\">Digitize script</a></li>\n"
+ << "<li><a href=\"src/Reconstruct.C.html\">Reconstruct script</a></li>\n"
+ << "<li><a href=\"src/Simulate.C.html\">Simulate script</a></li>\n"
+ << "<li><a href=\"src/DrawFMD.C.html\">DrawFMD script</a></li>\n"
+ << "<li><a href=\"src/ViewFMD.C.html\">ViewFMD script</a></li>\n"
+ << "</ul>\n"
+ << std::endl;
+ html->WriteHtmlFooter(index, "", "", "", "");
+ index.close();
+}
+
+//
+// EOF
+//
{
gMC->Gsatt("*", "seen", -1);
gMC->Gsatt("alic", "seen", 0);
- gROOT->LoadMacro("ViewFMD.C");
+ gROOT->LoadMacro("FMD/ViewFMD.C");
gInterpreter->ProcessLine("ViewFMD()");
gMC->Gdopt("hide", "on");
gMC->Gdopt("shad", "on");
gMC->SetClipBox(".");
gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
gMC->DefaultRange();
- gMC->Gdraw("alic", 40, 30, 0, 6, 9, .08, .08);
+ gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055);
gMC->Gdhead(1111, "Forward Multiplicity Detector");
- gMC->Gdman(13, 9, "MAN");
+ gMC->Gdman(16, 10, "MAN");
+ gPad->Modified();
+ gPad->cd();
}
+++ /dev/null
-void FMDDigit ()
-{
-// Dynamically link some shared libs
-
- if (gClassTable->GetID("AliRun") < 0) {
- gROOT->LoadMacro("loadlibs.C");
- loadlibs();
- }
- if (gAlice)
- {
- delete gAlice;
- gAlice = 0x0;
- }
-
- AliRunDigitizer * manager = new AliRunDigitizer(1,1);
- manager->SetInputStream(0,"galice.root");
- AliFMDDigitizer *FMD = new AliFMDDigitizer(manager);
- manager->Exec("");
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-void FMDMerger (Int_t evNumber1=0, Int_t evNumber2=0, Int_t ibg=0, Int_t bgr=10)
-{
-// Dynamically link some shared libs
-
- if (gClassTable->GetID("AliRun") < 0) {
- gROOT->LoadMacro("loadlibs.C");
- loadlibs();
- }
-
-// Connect the Root Galice file containing Geometry, Kine and Hits
-
- TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("pipe.root");
- if (file) file->Close();
- file = new TFile("galice.root","UPDATE");
- cout<<" Just starting... file "<<file<<endl;
-
-// Get AliRun object from file or create it if not on file
-
- if (!gAlice) {
- gAlice = (AliRun*)file->Get("gAlice");
- if (gAlice) printf("AliRun object found on file\n");
- if (!gAlice) gAlice = new AliRun("gAlice","Alice test program");
- }
- AliFMD *FMD = (AliFMD*) gAlice->GetModule("FMD");
-
- if (FMD) {
-// creation
- AliFMDMerger* merger = new AliFMDMerger();
- cout<<" merger "<<merger<<endl;
- /*
- // granularity
- merger->SetRingsSi1(128);
- merger->SetRingsSi2(64);
- merger->SetSectorsSi1(20);
- merger->SetSectorsSi2(24);
- */
-// configuration
- if (ibg) {
- merger->SetMode(ibg);
- merger->SetBackgroundFileName("bg.root");
- cout<<" background"<<endl;
- }
- // pass
- FMD->SetMerger(merger);
- }
-// Action !
-//
-// Loop over events
-//
- for (int nev=evNumber1; nev<= evNumber2; nev++) {
- Int_t nparticles = gAlice->GetEvent(nev);
- cout << "nev " << nev <<endl;
- cout << "nparticles " << nparticles <<endl;
- if (nev < evNumber1) continue;
- if (nparticles <= 0) return;
- Int_t nbgr_ev = Int_t(nev*bgr/(evNumber2+1));
- cout<<" nbgr_ev "<<nbgr_ev<<endl;
-
- if (ibg) {
- merger->SetBackgroundEventNumber(nbgr_ev);
- }
-
- gAlice->SDigits2Digits("FMD");
-
- char hname[30];
- sprintf(hname,"TreeD%d",nev);
- // gAlice->TreeD()->Write(hname);
- // cout<<hname<<" was written in file"<<file<<endl;
- // gAlice->TreeD()->Print();
- //reset tree
- gAlice->TreeD()->Reset();
-
- } // event loop
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-void FMDReconstructor (Int_t evNumber=1)
-{
- if (gClassTable->GetID("AliRun") < 0)
- {
- gROOT->LoadMacro("$ALICE_ROOT/macros/loadlibs.C");
- loadlibs();
- }
- if (gSystem->Getenv("CONFIG_SPLIT_FILE"))
- cout << "SPLIT" << endl;
- else
- cout << "NO SPLIT" << endl ;
-
-
-
- //TFile * f = new TFile("galice.root","UPDATE");
- //gAlice = (AliRun*) f->Get("gAlice") ;
-
- AliRunLoader* rl = AliRunLoader::Open("galice.root",AliConfig::GetDefaultEventFolderName(),"read");
- if (rl == 0x0)
- {
- cerr<<"Can not open session for file galice.root\n";
- return;
- }
-
- rl->LoadgAlice();
- gAlice = rl->GetAliRun();
-
- AliFMD* FMD = (AliFMD *)gAlice->GetDetector("FMD");
-
- gAlice->RunReco("FMD");
-}
-
+// -*- mode: c++ -*-
#ifdef __CINT__
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
#pragma link off all classes;
#pragma link off all functions;
-#pragma link C++ class AliFMDdigit+;
+#pragma link C++ class AliFMDBaseDigit+;
+#pragma link C++ class AliFMDDigit+;
+#pragma link C++ class AliFMDSDigit+;
+#else
+# error Not for compilation
#endif
+//
+// EOF
+//
-#ifdef __CINT__
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
+// -*- mode: c++ -*-
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
/* $Id$ */
+#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
+#pragma link C++ class AliFMDMap<UShort_t>;
+#pragma link C++ typedef AliFMDAdcMap;
#pragma link C++ class AliFMDReconstructor+;
-#pragma link C++ class AliFMDReconstParticles+;
+#pragma link C++ class AliFMDParticles+;
+#pragma link C++ class AliFMDRawStream+;
+#else
+# error Not for compilation
#endif
+//
+// EOF
+//
-#ifdef __CINT__
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
+// -*- mode: c++ -*-
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
/* $Id$ */
+#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
-
+
+#pragma link C++ class std::pair<Float_t,UShort_t>;
+#pragma link C++ class AliFMDMap<std::pair<Float_t,UShort_t> >;
+#pragma link C++ typedef AliFMDEdepMap;
+#pragma link C++ class AliFMDHit+;
#pragma link C++ class AliFMD+;
#pragma link C++ class AliFMDv0+;
#pragma link C++ class AliFMDv1+;
-#pragma link C++ class AliFMDhit+;
+#pragma link C++ class AliFMDSubDetector+;
+#pragma link C++ class AliFMD1+;
+#pragma link C++ class AliFMD2+;
+#pragma link C++ class AliFMD3+;
+#pragma link C++ class AliFMDRing+;
+#pragma link C++ class AliFMDPolygon+;
+#pragma link C++ class AliFMDBaseDigitizer+;
#pragma link C++ class AliFMDDigitizer+;
+#pragma link C++ class AliFMDSDigitizer+;
+#else
+# error Not for compilation
#endif
+//
+// EOF
+//
--- /dev/null
+#include <iomanip>
+
+void
+ReadRaw(Int_t det=2, bool verbose=false, Int_t event=0)
+{
+ TString file(Form("raw%d/FMD_%d.ddl", event, AliFMD::kBaseDDL + det - 1));
+
+ std::cout << "Reading raw data file " << file << std::endl;
+
+ TH1* h = new TH1F("rawData", "Raw Data", 90, 0, 90);
+
+
+ // This method creates a text file containing the same information
+ // stored in an Altro file. The information in the text file is
+ // organized pad by pad and and for each pad it consists in a
+ // sequence of bunches (Bunch length +2, Time bin of the last
+ // amplitude sample in the bunch, amplitude values) It is used
+ // mainly //for debugging
+
+ AliAltroBuffer buff(file.Data(),0);
+ Int_t numWords,padNum,rowNum,secNum=0;
+ Int_t value = 0;
+ Int_t zero = 0;
+ // if (!buff.ReadDataHeader()) {
+ // std::cout<< file << " isn't a valid data file!" << std::endl;
+ // }
+
+ while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum)){
+ if (verbose)
+ std::cout << "Ring: " << (secNum == 0 ? 'I' : 'O')
+ << " Sector: " << std::setw(2) << rowNum
+ << " Strip: " << std::setw(3) << padNum
+ << " Words: " << std::setw(4) << numWords << std::endl;
+ if (numWords == 0) zero++;
+ if (numWords % 4){
+ if (verbose)
+ std::cout << "Skipping trailer of "
+ << (4 - numWords % 4) << " words" << std::endl;
+ for(Int_t j = 0; j < (4 - numWords % 4); j++)
+ value=buff.GetNextBackWord();
+ }//end if
+ for(Int_t i = 0; i <numWords; i++) {
+ value=buff.GetNextBackWord();
+ if (verbose) {
+ std::cout << std::setw(5) << value << std::flush;
+ if (i % 16 == 15) std::cout << std::endl;
+ }
+ h->Fill(value);
+ }//end for
+ if (verbose)
+ std::cout << std::endl;
+ if (zero > 1) {
+ std::cout << "Error: Read zero channels - should not happen"
+ << std::endl;
+ break;
+ }
+ }//end while
+ h->Draw();
+ return;
+}
* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
-#include "AliFMDhit.h"
-ClassImp(AliFMDhit)
+/* $Id$ */
-AliFMDhit::AliFMDhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits):
- AliHit(shunt, track)
+// Script to do test the FMD digitization class.
+
+void
+Reconstruct()
{
-//Normal FMD hit ctor
- fVolume = vol[0];
- fNumberOfSector=vol[1];
- fNumberOfRing=vol[2];
- fX=hits[0];
- fY=hits[1];
- fZ=hits[2];
- fPx=hits[3];
- fPy=hits[4];
- fPz=hits[5];
- fEdep=hits[6];
- fParticle=(Int_t)hits[7];
- fTime=hits[8];
+ AliReconstruction rec;
+ rec.SetRunLocalReconstruction("FMD");
+ rec.SetRunVertexFinder(kFALSE);
+ rec.SetRunTracking(kFALSE);
+ rec.SetFillESD("");
+ rec.SetInput("./");
+ rec.Run();
}
-
-
-
-
-
-
-
-
-
-
-
-
-
+//
+// EOF
+//
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+// Script to do test the FMD digitization class.
+void
+Simulate()
+{
+ AliSimulation sim;
+ sim.SetConfigFile("FMD/Config.C");
+ // sim.SetMakeSDigits("FMD");
+ // sim.SetMakeDigits("FMD");
+ sim.SetWriteRawData("FMD");
+ // sim.SetMakeDigitsFromHits("FMD");
+ sim.Run();
+}
+
+//
+// EOF
+//
void ViewFMD()
{
- gMC->Gsatt("FMD0","seen",1);
- gMC->Gsatt("FMD1","seen",1);
- gMC->Gsatt("FMD2","seen",1);
- gMC->Gsatt("FMD3","seen",1);
+ gMC->Gsatt("FMD1","seen",0);
+ gMC->Gsatt("FMD2","seen",0);
+ gMC->Gsatt("FMD3","seen",0);
+ gMC->Gsatt("RNGI","seen",0);
+ gMC->Gsatt("RNGO","seen",0);
+ gMC->Gsatt("VFI","seen",0);
+ gMC->Gsatt("VFO","seen",0);
+ gMC->Gsatt("VBI","seen",0);
+ gMC->Gsatt("VBO","seen",0);
+ gMC->Gsatt("ACTI","seen",1);
+ gMC->Gsatt("ACTO","seen",1);
+ gMC->Gsatt("PBTI","seen",1);
+ gMC->Gsatt("PBTO","seen",1);
+ gMC->Gsatt("PBBI","seen",1);
+ gMC->Gsatt("PBBO","seen",1);
}
#-*- Mode: Makefile -*-
+#
# $Id$
-SRCS= AliFMDdigit.cxx
-
-
-HDRS= $(SRCS:.cxx=.h)
-
-DHDR:=FMDbaseLinkDef.h
+SRCS = AliFMDDigit.cxx
+HDRS = $(SRCS:.cxx=.h)
+DHDR := FMDbaseLinkDef.h
+#
+# EOF
+#
\ No newline at end of file
#-*- Mode: Makefile -*-
+#
# $Id$
-SRCS= AliFMDReconstructor.cxx AliFMDReconstParticles.cxx
-
-
-HDRS= $(SRCS:.cxx=.h)
-
-DHDR:=FMDrecLinkDef.h
+SRCS = AliFMDReconstructor.cxx \
+ AliFMDRawStream.cxx \
+ AliFMDParticles.cxx
+HDRS = $(SRCS:.cxx=.h)
+DHDR := FMDrecLinkDef.h
+EINCLUDE := $(ALICE)/RAW
+#
+# EOF
+#
#-*- Mode: Makefile -*-
+#
# $Id$
-SRCS= AliFMD.cxx AliFMDv0.cxx AliFMDv1.cxx AliFMDhit.cxx AliFMDDigitizer.cxx
-
-
-HDRS= $(SRCS:.cxx=.h)
-
-DHDR:=FMDsimLinkDef.h
+SRCS = AliFMD.cxx \
+ AliFMDSubDetector.cxx \
+ AliFMD1.cxx \
+ AliFMD2.cxx \
+ AliFMD3.cxx \
+ AliFMDRing.cxx \
+ AliFMDPolygon.cxx \
+ AliFMDHit.cxx \
+ AliFMDDigitizer.cxx
+HDRS = $(SRCS:.cxx=.h) AliFMDMap.h
+DHDR := FMDsimLinkDef.h
+EINCLUDE := $(ALICE)/RAW
+#
+# EOF
+#
\ No newline at end of file