AliGeometry) and support classes AliFMDRing, AliFMDDetector.
The geometry classes holds parameters only, and does some calculations
based on these.
Simulation code is moved into a seperate abstract class AliFMDSimulator
with 2 concrete implementations. AliFMDGeoSimulator and AliFMDg3Simulator.
The AliFMDSimulator classes sets up the geometry and handles hits in the
detector elements. AliFMD simply forwards calls to the AliFMDSimulator
object. AliFMDGeoSimulator implements the geometry via the ROOT TGeo
classes. That means that we can implement the shape of the silicon
sensors via a divided TUBS volume put inside a ONLY XTRU volume.
AliFMDG3Simulator implements the geometry via messages to TVirtualMC.
Which concrete AliFMDSimulator is instantized is decided at run-time
by checking TVirtualMC::IsRootGeometrySupported. If it returns true, then
the AliFMDGeoSimulator is used. Otherwise, the AliFMDG3Simulator is used.
The new singleton class AliFMDParameters acts as a simple DB of some
parameters which is shared amoung the various piecies of the code, and
which does not belong to the geometry.
TODO: Implement the AliGeometry member functions Impact and
ToGlobal. The latter is seriously limited by the fact that AliRecoPoint
only has 3 indicies to identify a detector, while the FMD uses 4 (detector,
ring, sector, strip). Implement the DrawDetector member function in
AliFMDSimulator (one way od the other). In AliFMDG3Detector, we should
check if the hit is inside the real shape of the silicon sensor.
Things to consider: TGeoManager says it finds the `illegal' extrussions:
* extrusion ov058/FIMO_x_0: vol=FIMO node=FIAC_0 extr=1.16823
* extrusion ov061/FOMO_x_0: vol=FOMO node=FOAC_0 extr=0.737969
and overlaps
* overlap ov190/FMD3_o_7_8: vol=FMD3 <F3SL_6<->F3SL_7> ovlp=0.148996
* overlap ov191/FMD3_o_5_6: vol=FMD3 <F3SL_4<->F3SL_5> ovlp=0.148996
* overlap ov192/FMD3_o_6_7: vol=FMD3 <F3SL_5<->F3SL_6> ovlp=0.148996
* overlap ov193/FMD3_o_1_2: vol=FMD3 <F3SL_0<->F3SL_1> ovlp=0.148996
* overlap ov194/FMD3_o_1_8: vol=FMD3 <F3SL_0<->F3SL_7> ovlp=0.148996
* overlap ov195/FMD3_o_2_3: vol=FMD3 <F3SL_1<->F3SL_2> ovlp=0.148996
* overlap ov196/FMD3_o_3_4: vol=FMD3 <F3SL_2<->F3SL_3> ovlp=0.148996
* overlap ov197/FMD3_o_4_5: vol=FMD3 <F3SL_3<->F3SL_4> ovlp=0.148996
The first comes from the MANY TUBS volume inside the ONLY XTRU volume,
and that should be OK. The latter comes from the some overlaps between the
8 support beams in the FMD3 cone. I've made these MANY volumes (I think),
but TGeoManager still complains (I don't know why - it shouldn't).
Christian Holm <cholm@nbi.dk>
Thursday, 30th of December, 2004.
//
// 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.
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
//
// This is the base class for all FMD manager classes.
//
// The actual code is done by various separate classes. Below is
// diagram showing the relationship between the various FMD classes
-// that handles the geometry
+// that handles the simulation
//
//
// +----------+ +----------+
-// | AliFMDv1 | | AliFMDv1 |
+// | AliFMDv1 | | AliFMDv0 |
// +----------+ +----------+
-// | |
-// +----+--------------+
-// |
-// | +------------+ 1 +---------------+
-// | +- | AliFMDRing |<>--| AliFMDPolygon |
-// V 2 | +------------+ +---------------+
-// +--------+<>--+ |
-// | AliFMD | ^
-// +--------+<>--+ V 1..2
-// 3 | +-------------------+
-// +-| AliFMDSubDetector |
-// +-------------------+
+// | | +-----------------+
+// +----+--------------+ +--| AliFMDDigitizer |
+// | | +-----------------+
+// | +---------------------+ |
+// | +- | AliFMDBaseDigitizer |<--+
+// V 1 | +---------------------+ |
+// +--------+<>--+ | +------------------+
+// | AliFMD | +--| AliFMDSDigitizer |
+// +--------+<>--+ +------------------+
+// 1 | +-----------------+
+// +-| AliFMDSimulator |
+// +-----------------+
// ^
// |
// +-------------+-------------+
-// | | |
-// +---------+ +---------+ +---------+
-// | AliFMD1 | | AliFMD2 | | AliFMD3 |
-// +---------+ +---------+ +---------+
+// | |
+// +--------------------+ +-------------------+
+// | AliFMDGeoSimulator | | AliFMDG3Simulator |
+// +--------------------+ +---------+---------+
//
//
// * AliFMD
// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDDigitizer, AliFMDReconstructor, and so
-// on.
+// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
+// AliFMDReconstructor, and so on.
+//
+// * AliFMDv0
+// This is a concrete implementation of the AliFMD interface.
+// It is the responsibility of this class to create the FMD
+// geometry.
//
// * AliFMDv1
// This is a concrete implementation of the AliFMD interface.
// 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.
+// * AliFMDSimulator
+// This is the base class for the FMD simulation tasks. The
+// simulator tasks are responsible to implment the geoemtry, and
+// process hits.
//
-// The responsible person for this module is Alla Maevskaia
-// <Alla.Maevskaia@cern.ch>.
+// * AliFMDGeoSimulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TGeo classes directly only.
//
-// Many modifications by Christian Holm Christensen <cholm@nbi.dk>
+// * AliFMDG3Simulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TVirtualMC interface with GEANT 3.21-like messages.
//
// These files are not in the same directory, so there's no reason to
// ask the preprocessor to search in the current directory for these
// files by including them with `#include "..."'
+#include <math.h> // __CMATH__
#include <TClonesArray.h> // ROOT_TClonesArray
#include <TGeometry.h> // ROOT_TGeomtry
#include <TNode.h> // ROOT_TNode
+#include <TXTRU.h> // ROOT_TXTRU
+#include <TRotMatrix.h> // ROOT_TRotMatrix
#include <TTUBE.h> // ROOT_TTUBE
#include <TTree.h> // ROOT_TTree
-#include <TVirtualMC.h> // ROOT_TVirtualMC
#include <TBrowser.h> // ROOT_TBrowser
#include <TMath.h> // ROOT_TMath
+#include <TVirtualMC.h> // ROOT_TVirtualMC
#include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
#include <AliLoader.h> // ALILOADER_H
#include <AliRun.h> // ALIRUN_H
#include <AliMC.h> // ALIMC_H
#include <AliLog.h> // ALILOG_H
-#include <AliMagF.h> // ALIMAGF_H
#include "AliFMD.h" // ALIFMD_H
#include "AliFMDDigit.h" // ALIFMDDIGIG_H
#include "AliFMDHit.h" // ALIFMDHIT_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
+#include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H
+#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
+#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H
#include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H
//____________________________________________________________________
ClassImp(AliFMD)
-
-//____________________________________________________________________
-const Char_t* AliFMD::fgkShortLegName = "FSSL";
-const Char_t* AliFMD::fgkLongLegName = "FSLL";
+#if 0
+ ; // This is to keep Emacs from indenting the next line
+#endif
//____________________________________________________________________
AliFMD::AliFMD()
- : fInner(0),
- fOuter(0),
- fFMD1(0),
- fFMD2(0),
- fFMD3(0),
- fSDigits(0),
+ : fSDigits(0),
fNsdigits(0),
- fPrintboardRotationId(0),
- fIdentityRotationId(0),
- fShortLegId(0),
- fLongLegId(0),
- fLegLength(0),
- fLegRadius(0),
- fModuleSpacing(0),
- fSiDensity(0),
- fSiThickness(0),
- fSiDeDxMip(1.664),
- fVA1MipRange(0),
- fAltroChannelSize(0),
- fSampleRate(0)
+ fDetailed(kTRUE),
+ fSimulator(0)
{
//
// Default constructor for class AliFMD
//
- AliDebug(0, "\tDefault CTOR");
+ AliDebug(10, "\tDefault CTOR");
fHits = 0;
fDigits = 0;
fIshunt = 0;
//____________________________________________________________________
AliFMD::AliFMD(const AliFMD& other)
: AliDetector(other),
- fInner(other.fInner),
- fOuter(other.fOuter),
- fFMD1(other.fFMD1),
- fFMD2(other.fFMD2),
- fFMD3(other.fFMD3),
fSDigits(other.fSDigits),
fNsdigits(other.fNsdigits),
- fPrintboardRotationId(other.fPrintboardRotationId),
- fIdentityRotationId(other.fIdentityRotationId),
- fShortLegId(other.fShortLegId),
- fLongLegId(other.fLongLegId),
- fLegLength(other.fLegLength),
- fLegRadius(other.fLegRadius),
- fModuleSpacing(other.fModuleSpacing),
- fSiDensity(other.fSiDensity),
- fSiThickness(other.fSiThickness),
- fSiDeDxMip(other.fSiDeDxMip),
- fVA1MipRange(other.fVA1MipRange),
- fAltroChannelSize(other.fAltroChannelSize),
- fSampleRate(other.fSampleRate)
+ fDetailed(other.fDetailed),
+ fSimulator(other.fSimulator)
{
// Copy constructor
}
//____________________________________________________________________
-AliFMD::AliFMD(const char *name, const char *title, bool detailed)
+AliFMD::AliFMD(const char *name, const char *title)
: AliDetector (name, title),
- fInner(0),
- fOuter(0),
- fFMD1(0),
- fFMD2(0),
- fFMD3(0),
fSDigits(0),
fNsdigits(0),
- fPrintboardRotationId(0),
- fIdentityRotationId(0),
- fShortLegId(0),
- fLongLegId(0),
- fLegLength(0),
- fLegRadius(0),
- fModuleSpacing(0),
- fSiDensity(0),
- fSiThickness(0),
- fSiDeDxMip(1.664),
- fVA1MipRange(0),
- fAltroChannelSize(0),
- fSampleRate(0)
+ fDetailed(kTRUE),
+ fSimulator(0)
{
//
// Standard constructor for Forward Multiplicity Detector
//
- AliDebug(0, "\tStandard CTOR");
+ AliDebug(10, "\tStandard CTOR");
// Initialise Hit array
HitsArray();
fIshunt = 0;
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();
- SetSiThickness();
- SetSiDensity();
- SetVA1MipRange();
- SetAltroChannelSize();
- SetSampleRate();
-
- fInner->SetLowR(4.3);
- fInner->SetHighR(17.2);
- fInner->SetWaferRadius(13.4/2);
- fInner->SetTheta(36/2);
- fInner->SetNStrips(512);
- fInner->SetSiThickness(fSiThickness);
- 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(fSiThickness);
- 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::operator=(const AliFMD& other)
{
AliDetector::operator=(other);
- fInner = other.fInner;
- fOuter = other.fOuter;
- fFMD1 = other.fFMD1;
- fFMD2 = other.fFMD2;
- fFMD3 = other.fFMD3;
fSDigits = other.fSDigits;
fNsdigits = other.fNsdigits;
- fSiDensity = other.fSiDensity;
- fPrintboardRotationId = other.fPrintboardRotationId;
- fIdentityRotationId = other.fIdentityRotationId;
- fShortLegId = other.fShortLegId;
- fLongLegId = other.fLongLegId;
- fLegLength = other.fLegLength;
- fLegRadius = other.fLegRadius;
- fModuleSpacing = other.fModuleSpacing;
- fSiDensity = other.fSiDensity;
- fSiThickness = other.fSiThickness;
- fVA1MipRange = other.fVA1MipRange;
- fAltroChannelSize = other.fAltroChannelSize;
- fSampleRate = other.fSampleRate;
-
+ fDetailed = other.fDetailed;
+ fSimulator = other.fSimulator;
+
return *this;
}
// FOR subdetectors fFMD1, fFMD2, and fFMD3 DO
// AliFMDSubDetector::Geomtry();
// END FOR
- //
-
- // DebugGuard guard("AliFMD::CreateGeometry");
- AliDebug(10, "\tCreating geometry");
-
- fInner->Init();
- fOuter->Init();
-
- Double_t par[3];
-
- Int_t airId = (*fIdtmed)[kAirId];
- Int_t alId = (*fIdtmed)[kAlId];
- Int_t cId = (*fIdtmed)[kCarbonId];
- Int_t siId = (*fIdtmed)[kSiId];
- Int_t pcbId = (*fIdtmed)[kPcbId];
- Int_t plaId = (*fIdtmed)[kPlasticId];
- Int_t pbId = fPrintboardRotationId;
- Int_t idId = fIdentityRotationId;
-
- par[0] = fLegRadius - .1;
- par[1] = fLegRadius;
- par[2] = fLegLength / 2;
- fShortLegId = gMC->Gsvolu(fgkShortLegName,"TUBE", plaId, par, 3);
-
- par[2] += fModuleSpacing / 2;
- fLongLegId = gMC->Gsvolu(fgkLongLegName,"TUBE", plaId, par, 3);
-
- fInner->SetupGeometry(airId, siId, pcbId, pbId, idId);
- fOuter->SetupGeometry(airId, siId, pcbId, pbId, idId);
-
- fFMD1->SetupGeometry(airId, alId, cId);
- fFMD2->SetupGeometry(airId, alId, cId);
- fFMD3->SetupGeometry(airId, alId, cId);
-
- fFMD1->Geometry("ALIC", pbId, idId);
- fFMD2->Geometry("ALIC", pbId, idId);
- fFMD3->Geometry("ALIC", pbId, idId);
+ //
+ if (!fSimulator) {
+ AliFatal("Simulator object not made yet!");
+ return;
+ }
+ fSimulator->DefineGeometry();
}
//____________________________________________________________________
// 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, "\tCreating 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);
-
- // Aluminum
- a = 26.981539;
- z = 13.;
- density = 2.7;
- radiationLength = 8.9;
- id = kAlId;
- AliMaterial(id, "FMD Aluminum$", a, z, density, radiationLength,
- absorbtionLength);
- AliMedium(kAlId, "FMD Aluminum$", 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);
- }
-
-#if 0
- // 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 = KaptionId;
- AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
- AliMedium(kAlId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
- maxStepSize,maxEnergyLoss,precision,minStepSize);
- }
-#endif
- // 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,0,fieldType,maxField,maxBending,
- maxStepSize,maxEnergyLoss,precision,minStepSize);
+ if (fSimulator) {
+ AliFatal("Simulator object already instantised!");
+ return;
}
+ AliFMDGeometry* geometry = AliFMDGeometry::Instance();
+ geometry->Init();
+ TVirtualMC* mc = TVirtualMC::GetMC();
+ Bool_t geo = mc->IsRootGeometrySupported();
+ if (geo)
+ fSimulator = new AliFMDGeoSimulator(this, fDetailed);
+ else
+ fSimulator = new AliFMDG3Simulator(this, fDetailed);
- // 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);
+ fSimulator->DefineMaterials();
}
//____________________________________________________________________
// AliFMDSubDetector::SimpleGeometry.
AliDebug(10, "\tCreating a simplified geometry");
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+
+ static TXTRU* innerShape = 0;
+ static TXTRU* outerShape = 0;
+ static TObjArray* innerRot = 0;
+ static TObjArray* outerRot = 0;
+
+ if (!innerShape || !outerShape) {
+ // Make the shapes for the modules
+ for (Int_t i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ switch (i) {
+ case 0: r = fmd->GetRing('I'); break;
+ case 1: r = fmd->GetRing('O'); break;
+ }
+ if (!r) {
+ AliError(Form("no ring found for i=%d", i));
+ return;
+ }
+ Double_t siThick = r->GetSiThickness();
+ const Int_t nv = r->GetNVerticies();
+ Double_t theta = r->GetTheta();
+ Int_t nmod = r->GetNModules();
+
+ TXTRU* shape = new TXTRU(r->GetName(), r->GetTitle(), "void", nv, 2);
+ for (Int_t j = 0; j < nv; j++) {
+ TVector2* vv = r->GetVertex(nv - 1 - j);
+ shape->DefineVertex(j, vv->X(), vv->Y());
+ }
+ shape->DefineSection(0, -siThick / 2, 1, 0, 0);
+ shape->DefineSection(1, +siThick / 2, 1, 0, 0);
+ shape->SetLineColor(GetLineColor());
+
+ TObjArray* rots = new TObjArray(nmod);
+ for (Int_t j = 0; j < nmod; j++) {
+ Double_t th = (j + .5) * theta * 2;
+ TString name(Form("FMD_ring_%c_rot_%02d", r->GetId(), j));
+ TString title(Form("FMD Ring %c Rotation # %d", r->GetId(), j));
+ TRotMatrix* rot = new TRotMatrix(name.Data(), title.Data(),
+ 90, th, 90, fmod(90+th,360), 0, 0);
+ rots->AddAt(rot, j);
+ }
+
+ switch (r->GetId()) {
+ case 'i':
+ case 'I': innerShape = shape; innerRot = rots; break;
+ case 'o':
+ case 'O': outerShape = shape; outerRot = rots; break;
+ }
+ }
+ }
+
TNode* top = gAlice->GetGeometry()->GetNode("alice");
- fFMD1->SimpleGeometry(fNodes, top, GetLineColor(), 0);
- fFMD2->SimpleGeometry(fNodes, top, GetLineColor(), 0);
- fFMD3->SimpleGeometry(fNodes, top, GetLineColor(), 0);
+ for (Int_t i = 1; i <= 3; i++) {
+ AliFMDDetector* det = fmd->GetDetector(i);
+ if (!det) {
+ Warning("BuildGeometry", "FMD%d seems to be disabled", i);
+ continue;
+ }
+ Double_t w = 0;
+ Double_t rh = det->GetRing('I')->GetHighR();
+ Char_t id = 'I';
+ if (det->GetRing('O')) {
+ w = TMath::Abs(det->GetRingZ('O') - det->GetRingZ('I'));
+ id = (TMath::Abs(det->GetRingZ('O'))
+ > TMath::Abs(det->GetRingZ('I')) ? 'O' : 'I');
+ rh = det->GetRing('O')->GetHighR();
+ }
+ w += (det->GetRing(id)->GetModuleSpacing() +
+ det->GetRing(id)->GetSiThickness());
+ TShape* shape = new TTUBE(det->GetName(), det->GetTitle(), "void",
+ det->GetRing('I')->GetLowR(), rh, w / 2);
+ Double_t z = (det->GetRingZ('I') - w / 2);
+ if (z > 0) z += det->GetRing(id)->GetModuleSpacing();
+ top->cd();
+ TNode* node = new TNode(det->GetName(), det->GetTitle(), shape,
+ 0, 0, z, 0);
+ fNodes->Add(node);
+
+ for (Int_t j = 0; j < 2; j++) {
+ AliFMDRing* r = 0;
+ TShape* rshape = 0;
+ TObjArray* rots = 0;
+ switch (j) {
+ case 0:
+ r = det->GetRing('I'); rshape = innerShape; rots = innerRot; break;
+ case 1:
+ r = det->GetRing('O'); rshape = outerShape; rots = outerRot; break;
+ }
+ if (!r) continue;
+
+ Double_t siThick = r->GetSiThickness();
+ Int_t nmod = r->GetNModules();
+ Double_t modspace = r->GetModuleSpacing();
+ Double_t rz = - (z - det->GetRingZ(r->GetId()));
+
+ for (Int_t k = 0; k < nmod; k++) {
+ node->cd();
+ Double_t offz = (k % 2 == 1 ? modspace : 0);
+ TRotMatrix* rot = static_cast<TRotMatrix*>(rots->At(k));
+ TString name(Form("%s%c_module_%02d", det->GetName(), r->GetId(),k));
+ TString title(Form("%s%c Module %d", det->GetName(), r->GetId(),k));
+ TNode* mnod = new TNode(name.Data(), title.Data(), rshape,
+ 0, 0, rz - siThick / 2
+ + TMath::Sign(offz,z), rot);
+ mnod->SetLineColor(GetLineColor());
+ fNodes->Add(mnod);
+ } // for (Int_t k = 0 ; ...)
+ } // for (Int_t j = 0 ; ...)
+ } // for (Int_t i = 1 ; ...)
}
//____________________________________________________________________
// DebugGuard guard("AliFMD::DrawDetector");
AliDebug(10, "\tDraw detector");
+#if 0
//Set ALIC mother transparent
gMC->Gsatt("ALIC","SEEN",0);
- gMC->Gsatt(fgkShortLegName,"SEEN",1);
- gMC->Gsatt(fgkLongLegName,"SEEN",1);
-
- //Set volumes visible
- fFMD1->Gsatt();
- fFMD2->Gsatt();
- fFMD3->Gsatt();
- fInner->Gsatt();
- fOuter->Gsatt();
-
//
gMC->Gdopt("hide", "on");
gMC->Gdopt("shad", "on");
gMC->Gdhead(1111, "Forward Multiplicity Detector");
gMC->Gdman(16, 10, "MAN");
gMC->Gdopt("hide", "off");
+#endif
}
//____________________________________________________________________
// an AliFMDSDigitizer object, and executing it.
//
AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root");
- digitizer->SetSampleRate(fSampleRate);
- digitizer->SetVA1MipRange(fVA1MipRange);
- digitizer->SetAltroChannelSize(fAltroChannelSize);
digitizer->Exec("");
}
{
// Create a digitizer object
AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager);
- digitizer->SetSampleRate(fSampleRate);
- digitizer->SetVA1MipRange(fVA1MipRange);
- digitizer->SetAltroChannelSize(fAltroChannelSize);
return digitizer;
}
// This uses the class AliFMDRawWriter to do the job. Please refer
// to that class for more information.
AliFMDRawWriter writer(this);
- writer.SetSampleRate(fSampleRate);
writer.Exec();
}
-//==================================================================
-//
-// 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
- //
- AliDebug(10, Form("\tLeg length set to %lf cm", length));
- 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
- //
- AliDebug(10, Form("\tLeg offset set to %lf cm", offset));
- fInner->SetLegOffset(offset);
- fOuter->SetLegOffset(offset);
-}
-
-//__________________________________________________________________
-void
-AliFMD::SetLegRadius(Double_t radius)
-{
- // Set the diameter of the plastic legs that hold the hybrid (print
- // board and silicon sensor) onto the honeycomp support
- //
- AliDebug(10, Form("\tLeg radius set to %lf cm", radius));
- fLegRadius = radius;
- fInner->SetLegRadius(fLegRadius);
- fOuter->SetLegRadius(fLegRadius);
-}
-
-//__________________________________________________________________
-void
-AliFMD::SetModuleSpacing(Double_t spacing)
-{
- // Set the distance between the front and back sensor modules
- // (module staggering).
- //
- AliDebug(10, Form("\tModule spacing set to %lf cm", spacing));
- fModuleSpacing = spacing;
- fInner->SetModuleSpacing(fModuleSpacing);
- fOuter->SetModuleSpacing(fModuleSpacing);
-}
//====================================================================
//
//
AliDebug(30, "\tBrowsing the FMD");
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");
+ if (fSimulator) b->Add(fSimulator);
+ b->Add(AliFMDGeometry::Instance());
}
-
//___________________________________________________________________
//
// EOF
#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 TBranch;
+class TClonesArray;
+class TBrowser;
+class AliDigitizer;
+class AliFMDSimulator;
//____________________________________________________________________
class AliFMD : public AliDetector
{
public:
AliFMD();
- AliFMD(const char *name, const char *title, bool detailed);
+ AliFMD(const char *name, const char *title);
AliFMD(const AliFMD& other);
virtual ~AliFMD();
AliFMD& operator=(const AliFMD& other);
virtual void CreateMaterials();
virtual void Init();
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();
// 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=2);
- void SetModuleSpacing(Double_t spacing=1);
- void SetSiDensity(Float_t r=2.33) { fSiDensity = r; }
- void SetSiThickness(Float_t r=0.03) { fSiThickness = r; }
- 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);}
-
- // 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 GetAlId() const { return (*fIdtmed)[kAlId]; }
- 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; }
- Float_t GetSiDensity() const { return fSiDensity; }
- Float_t GetSiThickness() const { return fSiThickness; }
- UShort_t GetVA1MipRange() const { return fVA1MipRange; }
- UShort_t GetAltroChannelSize() const { return fAltroChannelSize; }
- UShort_t GetSampleRate() const { return fSampleRate; }
- Float_t GetEdepMip() const {
- return fSiDeDxMip * fSiDensity * fSiThickness;
- }
-
// Utility
void Browse(TBrowser* b);
- enum {
- kBaseDDL = 0x1000 // DDL offset for the FMD
- };
- //
- static const Char_t* fgkShortLegName; // Format for short support legs
- static const Char_t* fgkLongLegName; // Format for long support legs
protected:
TClonesArray* HitsArray();
TClonesArray* DigitsArray();
TClonesArray* SDigitsArray();
- 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
- kAlId, // ID of Al medium
- kCarbonId // ID of Carbon medium
- };
-
- AliFMDRing* fInner; // Inner ring structure
- AliFMDRing* fOuter; // Outer ring structure
- AliFMDSubDetector* fFMD1; // FMD1 structure
- AliFMDSubDetector* fFMD2; // FMD2 structure
- AliFMDSubDetector* fFMD3; // FMD3 structure
TClonesArray* fSDigits; // Summable digits
Int_t fNsdigits; // Number of digits
- 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
- Float_t fSiDensity; // Density of Silicon
- Float_t fSiThickness; // Thickness of silicon wafers
- const Float_t fSiDeDxMip; // MIP dE/dx in Silicon
- UShort_t fVA1MipRange; // # MIPs the pre-amp can do
- UShort_t fAltroChannelSize; // Largest # to store in 1 ADC ch.
- UShort_t fSampleRate; // Times the ALTRO samples pre-amp.
-
- ClassDef(AliFMD,9) // Base class FMD entry point
+ Bool_t fDetailed; // Use detailed geometry
+
+ AliFMDSimulator* fSimulator; // Simulator task
+
+ ClassDef(AliFMD,10) // Base class FMD entry point
};
#endif
//____________________________________________________________________
//
-// Concrete implementation of AliFMDSubDetector
+// Concrete implementation of AliFMDDetector
//
// This implements the geometry for FMD1
//
#include "AliFMD1.h" // ALIFMD1_H
#include "AliFMDRing.h" // ALIFMDRING_H
-#include "TVirtualMC.h" // ROOT_TVirtualMC
-#include "AliLog.h" // ALILOG_H
-//____________________________________________________________________
+//====================================================================
ClassImp(AliFMD1)
+#if 0
+ ; // This is to keep Emacs from indenting the next line
+#endif
//____________________________________________________________________
-AliFMD1::AliFMD1()
- : AliFMDSubDetector(1)
-{
- // Default constructor for the FMD1 sub-detector
-}
-
-//____________________________________________________________________
-AliFMD1::~AliFMD1()
-{
- // Destructor - does nothing
-}
-
-//____________________________________________________________________
-void
-AliFMD1::SetupGeometry(Int_t airId, Int_t alId, Int_t /* cId */)
+AliFMD1::AliFMD1(AliFMDRing* inner)
+ : AliFMDDetector(1, inner, 0)
{
- // Setup the FMD1 sub-detector geometry
- //
- // Parameters:
- //
- // airId Id # of the Air medium
- // alId Id # of the Aluminium medium
- //
- AliDebug(10, "\tDefining the geometry for FMD1");
- 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, alId);
-}
-
-//____________________________________________________________________
-void
-AliFMD1::Geometry(const char* mother, Int_t pbRotId,
- Int_t idRotId, Double_t z)
-{
- // Position the FMD1 sub-detector volume
- //
- // Parameters
- //
- // mother name of the mother volume
- // pbRotId Printboard roation matrix ID
- // idRotId Identity rotation matrix ID
- // z Z position (not really used here, but passed down)
- //
- // The Z passed in isn't used.
- z = fInnerZ + fDz;
- AliDebug(10, Form("\tPutting FMD1 in %s at z=%lf cm", mother, z));
- gMC->Gspos("FMD1", 1, mother, 0, 0, z, fRotationId, "ONLY");
-
- AliFMDSubDetector::Geometry("FMD1", pbRotId, idRotId, z);
+ SetInnerZ(340);
}
-
//____________________________________________________________________
//
+#ifndef ALIFMD1_H
+#define ALIFMD1_H
//
// $Id$
//
-#ifndef ALIFMD1_H
-#define ALIFMD1_H
-
-#ifndef ALIFMDSUBDETECTOR_H
-# include "AliFMDSubDetector.h"
+#ifndef ALIFMDDETECTOR_H
+# include "AliFMDDetector.h"
#endif
+class AliFMDRing;
-class AliFMD1 : public AliFMDSubDetector
+//__________________________________________________________________
+/** Geometry description and parameters of the FMD1
+ detector.
+
+ The FMD1 only has one ring.
+*/
+class AliFMD1 : public AliFMDDetector
{
public:
- AliFMD1();
- virtual ~AliFMD1();
- virtual void SetupGeometry(Int_t airId, Int_t alId, Int_t cId=0);
- virtual void Geometry(const char* mother, Int_t pbRotId,
- Int_t idRotId, Double_t z=0);
-protected:
- Int_t fVolumeId; // Volume ID
- Double_t fDz; // Half-length in Z
- ClassDef(AliFMD1,1); // Geometry of FMD1
+ AliFMD1(AliFMDRing* inner);
+ virtual ~AliFMD1() {}
+ virtual void Init() { AliFMDDetector::Init(); }
+ ClassDef(AliFMD1,1)
};
#endif
//____________________________________________________________________
//
-// Concrete implementation of AliFMDSubDetector
+// Concrete implementation of AliFMDDetector
//
// This implements the geometry for FMD2
//
#include "AliFMD2.h" // ALIFMD2_H
#include "AliFMDRing.h" // ALIFMDRING_H
-#include <AliLog.h> // ALILOG_H
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-//____________________________________________________________________
+//====================================================================
ClassImp(AliFMD2)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
-AliFMD2::AliFMD2()
- : AliFMDSubDetector(2)
+AliFMD2::AliFMD2(AliFMDRing* inner, AliFMDRing* outer)
+ : AliFMDDetector(2, inner, outer)
{
- // Default constructor for the FMD2 sub-detector
-}
-
-//____________________________________________________________________
-AliFMD2::~AliFMD2()
-{
- // Destructor - does nothing
+ SetInnerZ(83.4);
+ SetOuterZ(75.2);
}
//____________________________________________________________________
-void
-AliFMD2::SetupGeometry(Int_t airId, Int_t alId, Int_t cId)
+void
+AliFMD2::Init()
{
- // Setup the FMD2 sub-detector geometry
- //
- // Parameters:
- //
- // airId Id # of the Air medium
- // alId Id # of the Aluminium medium
- //
- AliDebug(10, "\tDefining the geometry for FMD1");
- fInnerHoneyLowR = fInner->GetLowR() + 1;
- fInnerHoneyHighR = fOuter->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, alId, cId);
-}
-
-//____________________________________________________________________
-void
-AliFMD2::Geometry(const char* mother, Int_t pbRotId,
- Int_t idRotId, Double_t z)
-{
- // Position the FMD2 sub-detector volume
- //
- // Parameters
- //
- // mother name of the mother volume
- // pbRotId Printboard roation matrix ID
- // idRotId Identity rotation matrix ID
- // z Z position (not really used here, but passed down)
- //
- z = fDz + fOuterZ;
- AliDebug(10, Form("\tPutting FMD2 in %s at z=%lf cm", mother, z));
- AliFMDSubDetector::Geometry("FMD2", pbRotId, idRotId, z);
- gMC->Gspos("FMD2", 1, mother, 0, 0, z, fRotationId);
+ AliFMDDetector::Init();
+ SetInnerHoneyHighR(GetOuterHoneyHighR());
}
-
-
//____________________________________________________________________
//
// EOF
#ifndef ALIFMD2_H
#define ALIFMD2_H
-#ifndef ALIFMDSUBDETECTOR_H
-# include "AliFMDSubDetector.h"
+#ifndef ALIFMDDETECTOR_H
+# include "AliFMDDetector.h"
#endif
-class AliFMD2 : public AliFMDSubDetector
+/** Geometry description and parameters of the FMD2
+ detector.
+*/
+class AliFMD2 : public AliFMDDetector
{
-public:
- AliFMD2();
- virtual ~AliFMD2();
- virtual void SetupGeometry(Int_t airId, Int_t alId, Int_t cId=0);
- virtual void Geometry(const char* mother, Int_t pbRotId,
- Int_t idRotId, Double_t z=0);
-protected:
- Int_t fVolumeId; // Volume ID
- Double_t fDz; // Half-length in Z
- ClassDef(AliFMD2,1); // Geometry of FMD2
+protected:
+public:
+ AliFMD2(AliFMDRing* inner, AliFMDRing* outer);
+ /** Initialize the geometry */
+ virtual void Init();
+ ClassDef(AliFMD2, 1);
};
#endif
//____________________________________________________________________
//
-// Concrete implementation of AliFMDSubDetector
+// Concrete implementation of AliFMDDetector
//
// This implements the geometry for FMD3
//
-#include "TVirtualMC.h" // ROOT_TVirtualMC
-#include "TCONS.h" // ROOT_TCONS
-#include "TNode.h" // ROOT_TNode
-#include "TList.h" // ROOT_TList
#include "AliFMD3.h" // ALIFMD3_H
#include "AliLog.h" // ALILOG_H
#include "AliFMDRing.h" // ALIFMDRING_H
-#include <Riostream.h> // ROOT_Riostream
+#include <TMath.h> // ROOT_TMath
-//____________________________________________________________________
+//====================================================================
ClassImp(AliFMD3)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
-AliFMD3::AliFMD3()
- : AliFMDSubDetector(3),
- fVolumeId(0)
-{
- // Default constructor for the FMD3 sub-detector
- AliDebug(10, "\t\tDefault CTOR");
-}
-
-
-//____________________________________________________________________
-AliFMD3::~AliFMD3()
-{
- // Destructor - does nothing
- AliDebug(10, "\t\tDTOR");
-}
-
-
-//____________________________________________________________________
-void
-AliFMD3::SetupGeometry(Int_t airId, Int_t alId, Int_t carbonId)
+AliFMD3::AliFMD3(AliFMDRing* inner, AliFMDRing* outer)
+ : AliFMDDetector(3, inner, outer)
{
- // Setup the FMD3 sub-detector geometry
- //
- // Parameters:
- //
- // airId Id # of the Air medium
- // kaptionId Id # of the Aluminium medium
- //
- AliDebug(10, "\tSetting up the geometry for FMD3");
- Double_t innerZl = fInnerZ;
- Double_t innerZh = (fInnerZ
- - fInner->GetModuleSpacing()
- - fInner->GetLegLength()
- - fInner->GetSiThickness()
- - fInner->GetPrintboardThickness()
- - fHoneycombThickness);
- Double_t innerRl = fInner->GetLowR();
- Double_t outerZl = fOuterZ;
- Double_t outerZh = (fOuterZ
- - fOuter->GetModuleSpacing()
- - fOuter->GetLegLength()
- - fOuter->GetSiThickness()
- - fOuter->GetPrintboardThickness()
- - fHoneycombThickness);
- Double_t outerRl = fOuter->GetLowR();
-
- fSupport.SetupGeometry(airId, carbonId,
- innerZl, innerZh, innerRl,
- outerZl, outerZh, outerRl);
-
- fInnerHoneyLowR = fInner->GetLowR() + 1;
- fInnerHoneyHighR = fSupport.ConeR(innerZh + fHoneycombThickness, "I");
- fOuterHoneyLowR = fOuter->GetLowR() + 1;
- fOuterHoneyHighR = fSupport.GetBackLowR();
-
- // Identity matrix
- gMC->Matrix(fRotationId, 90, 0, 90, 90, 0, 0);
- //0, 180, 90, 90, 180, 0);
-
-
- AliFMDSubDetector::SetupGeometry(airId, alId, carbonId);
+ SetInnerZ(-62.8);
+ SetOuterZ(-75.2);
+ SetNoseZ();
+ SetNoseLowR();
+ SetNoseHighR();
+ SetNoseLength();
+ SetBackLowR();
+ SetBackHighR();
+ SetBackLength();
+ SetBeamThickness();
+ SetBeamWidth();
+ SetConeLength();
+ SetFlangeR();
+ SetNBeam();
+ SetNFlange();
}
//____________________________________________________________________
-void
-AliFMD3::Geometry(const char* mother, Int_t pbRotId,
- Int_t idRotId, Double_t z)
+void
+AliFMD3::Init()
{
- // Position the FMD3 sub-detector volume
- //
- // Parameters
- //
- // mother name of the mother volume
- // pbRotId Printboard roation matrix ID
- // idRotId Identity rotation matrix ID
- // z Z position (not really used here, but passed down)
- //
- z = fSupport.GetZ();
- fSupport.Geometry(mother, fRotationId, z);
- AliDebug(10, Form("\t\tPassing z=%lf to ring volumes", z));
- AliFMDSubDetector::Geometry("FMD3", pbRotId, idRotId, z);
+ AliFMDDetector::Init();
+ SetInnerHoneyHighR(GetOuterHoneyHighR());
+ Double_t zdist = fConeLength - fBackLength - fNoseLength;
+ Double_t tdist = fBackHighR - fNoseHighR;
+ Double_t innerZh = fInnerZ - fInner->GetRingDepth() - fHoneycombThickness;
+ Double_t outerZh = fOuterZ - fOuter->GetRingDepth() - fHoneycombThickness;
+ Double_t minZ = TMath::Min(fNoseZ - fConeLength, outerZh);
+ fAlpha = tdist / zdist;
+ fZ = fNoseZ + (minZ - fNoseZ) / 2;
+ fInnerHoneyHighR = ConeR(innerZh + fHoneycombThickness,"O") - 1;
+ fOuterHoneyHighR = GetBackLowR();
}
-
//____________________________________________________________________
-void
-AliFMD3::SimpleGeometry(TList* nodes,
- TNode* mother,
- Int_t colour,
- Double_t zMother)
+Double_t
+AliFMD3::ConeR(Double_t z, Option_t* opt) const
{
- // We need to get the equation for the line that connects the
- // outer circumfrences of the two rings, as well as for the line
- // that connects the inner curcumfrences, so that we can project to
- // where the honey-comb actually ends.
- //
- // we have
- //
- // y = a * x + b
- // b = y - a * x;
- //
- // For the outer line, we have the two equations
- //
- // fOuterHoneyHighR = a * x1 + b;
- // fInnerHoneyHighR = a * x2 + b;
- //
- // where
- //
- // x1 = (fOuterZ + fOuter->fSiThickness + fOuter->fPrintboardThickness
- // + fOuter->fLegLength + fModuleSpacing)
- // = fInner - fDz + fHoneycombThickness
- // x2 = (fInnerZ + fInner->fSiThickness + fInner->fPrintboardThickness
- // + fInner->fLegLength + fModuleSpacing)
- //
- // and
- //
- // a = (fOuterHoneyHighR - fInnerHoneyHighR) / (x1 - x2)
- //
- //
- AliDebug(10, "\tCreating simplified geometry for FMD3");
- Double_t dz = (TMath::Abs(fInnerZ - fOuterZ)
- + fOuter->GetSiThickness()
- + fOuter->GetPrintboardThickness()
- + fOuter->GetLegLength()
- + fOuter->GetModuleSpacing()
- + fHoneycombThickness) / 2;
-#if 1
- Double_t x1 = (fOuterZ - (fOuter->GetSiThickness()
- + fOuter->GetPrintboardThickness()
- + fOuter->GetLegLength()
- + fOuter->GetModuleSpacing()));
- Double_t x2 = (fInnerZ - (fInner->GetSiThickness()
- + fInner->GetPrintboardThickness()
- + fInner->GetLegLength()
- + fInner->GetModuleSpacing()));
- Double_t ao = 0;
- Double_t ao1 = (fOuterHoneyHighR - fInnerHoneyHighR) / (x1 - x2);
- Double_t ao2 = ((fOuter->GetHighR() - fInner->GetHighR())
- / (fOuterZ - fInnerZ));
- Double_t bo = 0;
- if (ao2 > ao1) {
- // std::cout << "Wafer determinds the size" << std::endl;
- ao = ao2;
- bo = fInner->GetHighR() - ao * fInnerZ;
+ // Calculate the cone radius at Z
+ if (fAlpha < 0) {
+ Warning("ConeR", "alpha not set: %lf", fAlpha);
+ return -1;
}
- else {
- ao = ao1;
- bo = fOuterHoneyHighR - ao * x1;
+ if (z > fNoseZ) {
+ Warning("ConeR", "z=%lf is before start of cone %lf", z, fNoseZ);
+ return -1;
}
-
- Double_t y1o = ao * (fInnerZ - 2 * dz) + bo;
- Double_t y2o = ao * fInnerZ + bo;
-#endif
- // We probably need to make a PCON here.
- TShape* shape = new TCONS("FMD3", "FMD3", "", dz,
- fOuter->GetLowR(), y1o, /* fOuterHoneyHighR, */
- fInner->GetLowR(), y2o, /* fInnerHoneyHighR, */
- 0, 360);
- mother->cd();
- zMother = fInnerZ - dz;
- TNode* node = new TNode("FMD3", "FMD3", shape, 0, 0, zMother, 0);
- node->SetVisibility(0);
- nodes->Add(node);
- AliFMDSubDetector::SimpleGeometry(nodes, node, colour, zMother);
+ if (z < fOuterZ - fOuter->GetRingDepth() - fHoneycombThickness) {
+ Warning("ConeR", "z=%lf is after end of cone %lf", z,
+ fOuterZ - fOuter->GetRingDepth() - fHoneycombThickness);
+ return -1;
+ }
+ Double_t e = fBeamThickness / TMath::Cos(TMath::ATan(fAlpha));
+ if (opt[0] == 'I' || opt[1] == 'i') e *= -1;
+ if (z > fNoseZ - fNoseLength) return fNoseHighR + e;
+ if (z < fNoseZ - fConeLength + fBackLength) return fBackHighR + e;
+ Double_t r = fNoseHighR + fAlpha * TMath::Abs(z - fNoseZ + fNoseLength) + e;
+ return r;
}
-//____________________________________________________________________
-void
-AliFMD3::Gsatt() const
-{
- // Set draw attributes for the FMD3
- AliDebug(10, "Setting drawing attributes for FMD3");
- AliFMDSubDetector::Gsatt();
- fSupport.Gsatt();
-}
//____________________________________________________________________
//
#ifndef ALIFMD3_H
#define ALIFMD3_H
-#ifndef ALIFMDSUBDETECTOR_H
-# include "AliFMDSubDetector.h"
-#endif
-#ifndef ALIFMD3SUPPORT_H
-# include "AliFMD3Support.h"
+#ifndef ALIFMDDETECTOR_H
+# include "AliFMDDetector.h"
#endif
-class AliFMD3 : public AliFMDSubDetector
+/** Geometry description and parameters of the FMD3 detector.
+
+ FMD3 has a fairly complicated support structure
+*/
+class AliFMD3 : public AliFMDDetector
{
-public:
- AliFMD3();
- virtual ~AliFMD3();
- virtual void SetupGeometry(Int_t airId, Int_t alId, Int_t cId=0);
- 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() const;
-protected:
- Int_t fVolumeId; // Volume ID
- AliFMD3Support fSupport; // Support for FMD3
- ClassDef(AliFMD3,2); // Geometry of FMD3
+public:
+ AliFMD3(AliFMDRing* inner, AliFMDRing* outer);
+ virtual ~AliFMD3(){}
+
+ /** Initialize the geometry */
+ virtual void Init();
+
+ /** @param z Z position of front of nose */
+ void SetNoseZ(Double_t z=-46) { fNoseZ = z; }
+ /** @param r Nose inner radius */
+ void SetNoseLowR(Double_t r=5.5) { fNoseLowR = r; }
+ /** @param r Nose outer radius */
+ void SetNoseHighR(Double_t r=6.7) { fNoseHighR = r; }
+ /** @param l Length of nose in Z */
+ void SetNoseLength(Double_t l=2.8) { fNoseLength = l; }
+ /** @param r Inner radius of base of cone */
+ void SetBackLowR(Double_t r=61./2) { fBackLowR = r; }
+ /** @param r Outer radius of base of cone */
+ void SetBackHighR(Double_t r=66.8/2) { fBackHighR = r; }
+ /** @param l Length of base of cone in Z */
+ void SetBackLength(Double_t l=1.4) { fBackLength = l; }
+ /** @param t Thickness of support beams */
+ void SetBeamThickness(Double_t t=.5) { fBeamThickness = t; }
+ /** @param w Width of support beams */
+ void SetBeamWidth(Double_t w=6) { fBeamWidth = w; }
+ /** @param l Length of the cone in Z */
+ void SetConeLength(Double_t l=30.9) { fConeLength = l; }
+ /** @param r Outer radius of flanges */
+ void SetFlangeR(Double_t r=49.25) { fFlangeR = r; }
+ /** @param n Number of support beams */
+ void SetNBeam(Int_t n=8) { fNBeam = n; }
+ /** @param n Number of support flanges */
+ void SetNFlange(Int_t n=4) { fNFlange = n; }
+
+ /** @return Z position of front of nose */
+ Double_t GetNoseZ() const { return fNoseZ; }
+ /** @return Nose inner radius */
+ Double_t GetNoseLowR() const { return fNoseLowR; }
+ /** @return Nose outer radius */
+ Double_t GetNoseHighR() const { return fNoseHighR; }
+ /** @return Length of nose in Z */
+ Double_t GetNoseLength() const { return fNoseLength; }
+ /** @return Inner radius of base of cone */
+ Double_t GetBackLowR() const { return fBackLowR; }
+ /** @return Outer radius of base of cone */
+ Double_t GetBackHighR() const { return fBackHighR; }
+ /** @return Length of base of cone in Z */
+ Double_t GetBackLength() const { return fBackLength; }
+ /** @return Thickness of support beams */
+ Double_t GetBeamThickness() const { return fBeamThickness; }
+ /** @return Width of support beams */
+ Double_t GetBeamWidth() const { return fBeamWidth; }
+ /** @return Length of the cone in Z */
+ Double_t GetConeLength() const { return fConeLength; }
+ /** @return Outer radius of flanges */
+ Double_t GetFlangeR() const { return fFlangeR; }
+ /** @return Midpoint of mother volume */
+ Double_t GetZ() const { return fZ; }
+ /** @return Slope of cone */
+ Double_t GetAlpha() const { return fAlpha; }
+ /** @return Number of support beams */
+ Int_t GetNBeam() const { return fNBeam; }
+ /** @return Number of support flanges */
+ Int_t GetNFlange() const { return fNFlange; }
+
+ /** Get the cone radii at @a z.
+ @param z Point to evaulate at
+ @param opt If @c "O" get the outer radii, if @c "I" get the
+ inner radii.
+ @return the radius of the cone */
+ Double_t ConeR(Double_t z, Option_t* opt="O") const;
+
+protected:
+ Double_t fNoseZ; // Z position of front of nose
+ Double_t fNoseLowR; // Nose inner radius
+ Double_t fNoseHighR; // Nose outer radius
+ Double_t fNoseLength; // Length of nose in Z
+ Double_t fBackLowR; // Inner radius of base of cone
+ Double_t fBackHighR; // Outer radius of base of cone
+ Double_t fBackLength; // Length of base of cone in Z
+ Double_t fBeamThickness; // Thickness of support beams
+ Double_t fBeamWidth; // Width of support beams
+ Double_t fConeLength; // Length of the cone in Z
+ Double_t fFlangeR; // Outer radius of flanges
+ Double_t fZ; // Midpoint of mother volume
+ Double_t fAlpha; // Slope of cone
+ Int_t fNBeam; // Number of support beams
+ Int_t fNFlange; // Number of support flangesy
+ ClassDef(AliFMD3, 1);
};
#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$ */
-
-//____________________________________________________________________
-//
-// Concrete implementation of AliFMDSubDetector
-//
-// This implements the geometry for FMD3
-//
-#include "TVirtualMC.h" // ROOT_TVirtualMC
-#include "AliFMD3Support.h" // ALIFMD3SUPPORT_H
-#include "AliLog.h" // ALILOG_H
-#include <Riostream.h> // ROOT_Riostream
-
-//____________________________________________________________________
-ClassImp(AliFMD3Support)
-
-//____________________________________________________________________
-const Char_t* AliFMD3Support::fgkNoseName = "F3SN";
-const Char_t* AliFMD3Support::fgkBackName = "F3SB";
-const Char_t* AliFMD3Support::fgkBeamName = "F3SL";
-const Char_t* AliFMD3Support::fgkFlangeName = "F3SF";
-
-//____________________________________________________________________
-AliFMD3Support::AliFMD3Support()
- : fZ(0),
- fAlpha(-1),
- fNoseId(-1),
- fBeamId(-1),
- fBackId(-1),
- fFlangeId(-1)
-{
- // Default constructor for the support of FMD3 sub-detector
- SetNoseZ();
- SetNoseLowR();
- SetNoseHighR();
- SetNoseLength();
- SetBackLowR();
- SetBackHighR();
- SetBackLength();
- SetBeamThickness();
- SetBeamWidth();
- SetConeLength();
- SetFlangeR();
- SetNBeam();
- SetNFlange();
-}
-
-
-//____________________________________________________________________
-AliFMD3Support::~AliFMD3Support()
-{
- // Destructor - does nothing
-}
-
-
-//____________________________________________________________________
-void
-AliFMD3Support::SetupGeometry(Int_t airId,
- Int_t cId,
- Double_t innerZl,
- Double_t innerZh,
- Double_t innerRl,
- Double_t /* outerZl */,
- Double_t outerZh,
- Double_t outerRl)
-{
- // Setup the FMD3 sub-detector geometry
- //
- // Parameters:
- //
- // airId Id # of the Air medium
- // cId Id # of the Carbon fibre medium
- //
-
- // Global stuff we need
- Double_t zdist = fConeLength - fBackLength - fNoseLength;
- Double_t tdist = fBackHighR - fNoseHighR;
- Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
- Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
- Double_t minZ = TMath::Min(fNoseZ - fConeLength, outerZh);
- fAlpha = tdist / zdist;
- fZ = fNoseZ + (minZ - fNoseZ) / 2;
- AliDebug(30, Form("\tTheta = %lf", theta));
-
- const Char_t* mother = "FMD3";
- Double_t p[3 + 9 * 3];
- Double_t eps = 0;
- // ------------- Mother volume -------------------------------------
- // The planes should be defined with increasing Z, as it will become
- // invalid if not
- // Global parameters
- p[0] = 0;
- p[1] = 360;
- p[2] = 8;
- // First plane (at back of back or outer ring)
- p[3] = minZ - fZ - eps;
- p[4] = outerRl - eps;
- p[5] = fFlangeR + eps;
- // Second plane (at front of back, at end of flanges)
- p[6] = fNoseZ - zdist - fNoseLength - fZ + eps;
- p[7] = p[4];
- p[8] = p[5];
- // Third plane (at front of back)
- p[9] = p[6] - eps/2;
- p[10] = p[7];
- p[11] = ConeR(p[9] + fZ) + eps;
- // Fourth plane (at back of inner ring)
- p[12] = innerZh - fZ - eps;
- p[13] = outerRl - eps;
- p[14] = ConeR(p[12] + fZ) + eps;
- // Fifth plane (at back of inner ring)
- p[15] = p[12] - eps/2;
- p[16] = innerRl - eps;
- p[17] = ConeR(p[15] + fZ) + eps;
- // Sixth plane (at front of inner ring)
- p[18] = innerZl - fZ + eps;
- p[19] = p[16];
- p[20] = ConeR(p[18] + fZ) + eps;
- // Seventh plane (at end of nose)
- p[21] = fNoseZ - fNoseLength - fZ - eps;
- p[22] = fNoseLowR - eps;
- p[23] = ConeR(p[21] + fZ) + eps; // fNoseHighR;
- // Eight (and final) plane (at start of nose)
- p[24] = fNoseZ - fZ + eps;
- p[25] = p[22];
- p[26] = fNoseHighR + eps;
-
- // The volume
- gMC->Gsvolu(mother, "PCON", airId, p, 27);
-
- // ------------- Support Structures --------------------------------
- fRotations.Set(fNBeam + fNFlange);
- Double_t par[3];
-
- // The nose
- par[0] = fNoseLowR;
- par[1] = fNoseHighR;
- par[2] = fNoseLength / 2;
- fNoseId = gMC->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
-
- // The Back
- par[0] = fBackLowR;
- par[1] = fBackHighR;
- par[2] = fBackLength / 2;
- fBackId = gMC->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
-
- // The Beams
- par[0] = fBeamThickness / 2;
- par[1] = fBeamWidth / 2;
- par[2] = beaml / 2;
- fBeamId = gMC->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
- for (Int_t i = 0; i < fNBeam; i++) {
- // cout << "Making beam # " << i << endl;
- Double_t phi = 360. / fNBeam * i;
- Int_t id;
- gMC->Matrix(id, 180 - theta, phi, 90, 90 + phi, theta, phi);
- fRotations[i] = id;
- }
-
- // The Flanges
- par[0] = (fFlangeR - fBackHighR) / 2;
- par[1] = fBeamWidth / 2;
- par[2] = fBackLength / 2;
- fFlangeId = gMC->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
- for (Int_t i = 0; i < fNFlange; i++) {
- Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
- Int_t id;
- gMC->Matrix(id, 90, phi, 90, 90+phi, 0, 0);
- fRotations[fNBeam + i] = id;
- }
-}
-
-//____________________________________________________________________
-void
-AliFMD3Support::Geometry(const char* mother, Int_t idRotId, Double_t zTop)
-{
- // Position the FMD3 sub-detector volume
- //
- // Parameters
- //
- // mother name of the mother volume
- // idRotId Identity rotation matrix ID
- // z Z position
- //
-
- // Common parameters
- Double_t zdist = fConeLength - fBackLength - fNoseLength;
- Double_t tdist = fBackHighR - fNoseHighR;
- const Char_t* name = "FMD3";
- Double_t z = zTop;
-
- // Placing mother volume
- AliDebug(10, Form("\tPutting %s in %s at z=%lf", name, mother, zTop));
- gMC->Gspos(name, 1, mother, 0, 0, zTop, idRotId, "ONLY");
-
- // Placing the nose
- z = fNoseZ - fNoseLength / 2 - fZ;
- AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf/2-%lf=%lf",
- fgkNoseName, name, fNoseZ, fNoseLength, fZ, z));
- gMC->Gspos(fgkNoseName, 1, name, 0., 0., z, idRotId, "");
-
- // Placing the back
- z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
- AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
- fgkBackName, name, fNoseZ, fNoseLength, zdist,
- fBackLength, fZ, z));
- gMC->Gspos(fgkBackName, 1, name, 0., 0., z, idRotId, "");
-
- // Placing the beams
- z = fNoseZ - fNoseLength - zdist / 2 - fZ;
- Double_t r = fNoseHighR + tdist / 2;
- AliDebug(10, Form("\tPutting %s's in %s at z=%lf-%lf-%lf/2-%lf=%lf",
- fgkBeamName, name, fNoseZ, fNoseLength, zdist, fZ, z));
- for (Int_t i = 0; i < fNBeam; i++) {
- // cout << "Making beam # " << i << endl;
- Double_t phi = 360. / fNBeam * i;
- gMC->Gspos(fgkBeamName, i, name,
- r * TMath::Cos(TMath::Pi() / 180 * phi),
- r * TMath::Sin(TMath::Pi() / 180 * phi),
- z, fRotations[i], "");
- }
-
- // Placing the flanges
- r = fBackHighR + (fFlangeR - fBackHighR) / 2;
- z = fNoseZ - fNoseLength - zdist - fBackLength / 2 - fZ;
- AliDebug(10, Form("\tPutting %s in %s at z=%lf-%lf-%lf-%lf/2-%lf=%lf",
- fgkFlangeName, name, fNoseZ, fNoseLength, zdist,
- fBackLength, fZ, z));
- for (Int_t i = 0; i < fNFlange; i++) {
- Double_t phi = 360. / fNFlange * i + 180. / fNFlange;
- gMC->Gspos(fgkFlangeName, i, name,
- r * TMath::Cos(TMath::Pi() / 180 * phi),
- r * TMath::Sin(TMath::Pi() / 180 * phi),
- z, fRotations[fNBeam + i], "");
- }
-
-}
-
-//____________________________________________________________________
-Double_t
-AliFMD3Support::ConeR(Double_t z, Option_t* opt) const
-{
- // Calculate the cone radius at Z
- if (fAlpha < 0) {
- Warning("ConeR", "alpha not set: %lf", fAlpha);
- return -1;
- }
- if (z > fNoseZ) {
- Warning("ConeR", "z=%lf is before start of cone %lf", z, fNoseZ);
- return -1;
- }
- Double_t e = fBeamThickness / TMath::Cos(TMath::ATan(fAlpha));
- if (opt[0] == 'I' || opt[1] == 'i') e *= -1;
- if (z > fNoseZ - fNoseLength) return fNoseHighR + e;
- if (z < fNoseZ - fConeLength + fBackLength) return fBackHighR + e;
- Double_t r = fNoseHighR + fAlpha * TMath::Abs(z - fNoseZ + fNoseLength) + e;
- return r;
-}
-
-//____________________________________________________________________
-void
-AliFMD3Support::Gsatt() const
-{
- // Set drawing attributes for the FMD3 Support
- gMC->Gsatt(fgkNoseName, "SEEN", 1);
- gMC->Gsatt(fgkBeamName, "SEEN", 1);
- gMC->Gsatt(fgkBackName, "SEEN", 1);
- gMC->Gsatt(fgkFlangeName, "SEEN", 1);
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-//
-// $Id$
-//
-#ifndef ALIFMD3SUPPORT_H
-#define ALIFMD3SUPPORT_H
-
-#ifndef ROOT_TObject
-# include <TObject.h>
-#endif
-#ifndef ROOT_TArrayI
-# include <TArrayI.h>
-#endif
-
-class AliFMD3Support : public TObject
-{
-public:
- AliFMD3Support();
- virtual ~AliFMD3Support();
- virtual void SetupGeometry(Int_t airId, Int_t cId,
- Double_t innerZl, Double_t innerZh,
- Double_t innerRl, Double_t outerZl,
- Double_t outerZh, Double_t outerRl);
- virtual void Geometry(const char* mother, Int_t idRotId, Double_t z=0);
- virtual void Gsatt() const;
-
- void SetNoseZ(Double_t x=-46) { fNoseZ = x; }
- void SetNoseLowR(Double_t x=5.5) { fNoseLowR = x; }
- void SetNoseHighR(Double_t x=6.7) { fNoseHighR = x; }
- void SetNoseLength(Double_t x=2.8) { fNoseLength = x; }
- void SetBackLowR(Double_t x=61./2) { fBackLowR = x; }
- void SetBackHighR(Double_t x=66.8/2) { fBackHighR = x; }
- void SetBackLength(Double_t x=1.4) { fBackLength = x; }
- void SetBeamThickness(Double_t x=.5) { fBeamThickness = x; }
- void SetBeamWidth(Double_t x=6) { fBeamWidth = x; }
- void SetConeLength(Double_t x=30.9) { fConeLength = x; }
- void SetFlangeR(Double_t x=49.25) { fFlangeR = x; }
- void SetNBeam(Int_t n=8) { fNBeam = n; }
- void SetNFlange(Int_t n=4) { fNFlange = n; }
-
- Double_t GetNoseZ() const { return fNoseZ; }
- Double_t GetNoseLowR() const { return fNoseLowR; }
- Double_t GetNoseHighR() const { return fNoseHighR; }
- Double_t GetNoseLength() const { return fNoseLength; }
- Double_t GetBackLowR() const { return fBackLowR; }
- Double_t GetBackHighR() const { return fBackHighR; }
- Double_t GetBackLength() const { return fBackLength; }
- Double_t GetBeamThickness() const { return fBeamThickness; }
- Double_t GetBeamWidth() const { return fBeamWidth; }
- Double_t GetConeLength() const { return fConeLength; }
- Double_t GetFlangeR() const { return fFlangeR; }
- Int_t GetNBeam() const { return fNBeam; }
- Int_t GetNFlange() const { return fNFlange; }
- Double_t GetZ() const { return fZ; }
- Double_t ConeR(Double_t z, Option_t* opt="O") const;
-protected:
- Double_t fNoseZ; // Z position of front of nose
- Double_t fNoseLowR; // Nose inner radius
- Double_t fNoseHighR; // Nose outer radius
- Double_t fNoseLength; // Length of nose in Z
- Double_t fBackLowR; // Inner radius of base of cone
- Double_t fBackHighR; // Outer radius of base of cone
- Double_t fBackLength; // Length of base of cone in Z
- Double_t fBeamThickness; // Thickness of support beams
- Double_t fBeamWidth; // Width of support beams
- Double_t fConeLength; // Length of the cone in Z
- Double_t fFlangeR; // Outer radius of flanges
- Double_t fZ; // Midpoint of mother volume
- Double_t fAlpha; // Slope of cone
-
- Int_t fNBeam; // Number of support beams
- Int_t fNFlange; // Number of support flanges
- Int_t fNoseId; // Id of nose volume
- Int_t fBeamId; // Id of beam volumes
- Int_t fBackId; // Id of base volume
- Int_t fFlangeId; // Id of flange volume
- TArrayI fRotations;
-
- static const Char_t* fgkNoseName; // Name of nose volume
- static const Char_t* fgkBeamName; // Name of beam volumes
- static const Char_t* fgkBackName; // Name of base volume
- static const Char_t* fgkFlangeName; // Name of flange volume
-
- ClassDef(AliFMD3Support,1); // Geometry of Support for the FMD3
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-//
-// EOF
-//
#include "AliFMDBoolMap.h" //ALIFMDBOOLMAP_H
//__________________________________________________________
ClassImp(AliFMDBoolMap)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//__________________________________________________________
AliFMDBoolMap::AliFMDBoolMap(const AliFMDBoolMap& other)
: AliFMDMap(other.fMaxDetectors,
--- /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 AliFMDGeometry object owns the AliFMDDetector objects
+//
+// Latest changes by Christian Holm Christensen
+//
+#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include <AliLog.h> // ALILOG_H
+
+//====================================================================
+ClassImp(AliFMDDetector)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
+ : TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
+ fId(id),
+ fInner(inner),
+ fOuter(outer)
+{
+ SetHoneycombThickness();
+ SetAlThickness();
+ SetInnerHoneyLowR(0);
+ SetInnerHoneyHighR(0);
+ SetInnerZ(0);
+ SetOuterZ(0);
+ SetOuterHoneyLowR(0);
+ SetOuterHoneyHighR(0);
+}
+
+//____________________________________________________________________
+void
+AliFMDDetector::Init()
+{
+ if (fInner) {
+ SetInnerHoneyLowR(fInner->GetLowR() + 1.);
+ SetInnerHoneyHighR(fInner->GetHighR() + 1.);
+ }
+ if (fOuter) {
+ SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
+ SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
+ }
+
+}
+
+//____________________________________________________________________
+AliFMDRing*
+AliFMDDetector::GetRing(Char_t id) const
+{
+ switch (id) {
+ case 'i':
+ case 'I': return GetInner();
+ case 'o':
+ case 'O': return GetOuter();
+ }
+ return 0;
+}
+
+//____________________________________________________________________
+Double_t
+AliFMDDetector::GetRingZ(Char_t id) const
+{
+ switch (id) {
+ case 'i':
+ case 'I': return GetInnerZ();
+ case 'o':
+ case 'O': return GetOuterZ();
+ }
+ return 0;
+}
+//____________________________________________________________________
+void
+AliFMDDetector::Detector2XYZ(Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Double_t& x,
+ Double_t& y,
+ Double_t& z) const
+{
+ AliFMDRing* r = GetRing(ring);
+ if (!r) return;
+ z = GetRingZ(ring);
+ r->Detector2XYZ(sector, strip, x, y, z);
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDDETECTOR_H
+#define ALIFMDDETECTOR_H
+/* 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 ROOT_TNamed
+# include <TNamed.h>
+#endif
+class AliFMDRing;
+
+
+//__________________________________________________________________
+/** Base class for the geometry description and parameters of the FMD
+ sub detectors FMD1, FMD2, and FMD3.
+
+ This class hold common parameters of the specific FMD detectors.
+*/
+class AliFMDDetector : public TNamed
+{
+public:
+ AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer);
+ virtual ~AliFMDDetector() {}
+ /** Initialize the geometry */
+ virtual void Init();
+
+ /** @param x Detector number */
+ void SetId(Int_t x) { fId = x; }
+ /** @param x Position of outer ring along z */
+ void SetInnerZ(Double_t x) { fInnerZ = x; }
+ /** @param x Position of outer ring along z */
+ void SetOuterZ(Double_t x) { fOuterZ = x; }
+ /** @param x Thickness of honeycomb plate */
+ void SetHoneycombThickness(Double_t x=1) { fHoneycombThickness = x; }
+ /** @param x Thickness of aluminium of honeycomb */
+ void SetAlThickness(Double_t x=.1) { fAlThickness = x; }
+ /** @param x Inner radius of inner honeycomb */
+ void SetInnerHoneyLowR(Double_t x) { fInnerHoneyLowR = x; }
+ /** @param x Outer radius of inner honeycomb */
+ void SetInnerHoneyHighR(Double_t x) { fInnerHoneyHighR = x; }
+ /** @param x Inner radius of outer honeycomb */
+ void SetOuterHoneyLowR(Double_t x) { fOuterHoneyLowR = x; }
+ /** @param x Outer radius of outer honeycomb */
+ void SetOuterHoneyHighR(Double_t x) { fOuterHoneyHighR = x; }
+
+ /** @return Detector number */
+ Int_t GetId() const { return fId; }
+ /** @return Position of outer ring along z */
+ Double_t GetInnerZ() const { return fInnerZ; }
+ /** @return Position of outer ring along z */
+ Double_t GetOuterZ() const { return fOuterZ; }
+ /** @return Thickness of honeycomb plate */
+ Double_t GetHoneycombThickness() const { return fHoneycombThickness; }
+ /** @return Thickness of aluminium of honeycomb */
+ Double_t GetAlThickness() const { return fAlThickness; }
+ /** @return Inner radius of inner honeycomb */
+ Double_t GetInnerHoneyLowR() const { return fInnerHoneyLowR; }
+ /** @return Outer radius of inner honeycomb */
+ Double_t GetInnerHoneyHighR() const { return fInnerHoneyHighR; }
+ /** @return Inner radius of outer honeycomb */
+ Double_t GetOuterHoneyLowR() const { return fOuterHoneyLowR; }
+ /** @return Outer radius of outer honeycomb */
+ Double_t GetOuterHoneyHighR() const { return fOuterHoneyHighR; }
+
+ /** @return Inner ring information */
+ AliFMDRing* GetInner() const { return fInner; }
+ /** @return Outer ring information */
+ AliFMDRing* GetOuter() const { return fOuter; }
+ /** @param id Id of ring to get
+ @return Pointer to ring, 0 on failure */
+ AliFMDRing* GetRing(Char_t id) const;
+ /** @param id Id of ring to get
+ @return Z position of ring or 0 on failure */
+ Double_t GetRingZ(Char_t id) const;
+
+ void Detector2XYZ(Char_t ring, UShort_t sector, UShort_t strip,
+ Double_t& x, Double_t& y, Double_t& z) const;
+
+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 fAlThickness; // Thickness of aluminium of honeycomb
+ Double_t fInnerHoneyLowR; // Inner radius of inner honeycomb
+ Double_t fInnerHoneyHighR; // Outer radius of inner honeycomb
+ Double_t fOuterHoneyLowR; // Inner radius of outer honeycomb
+ Double_t fOuterHoneyHighR; // Outer radius of outer honeycomb
+ AliFMDRing* fInner; // Pointer to inner ring information
+ AliFMDRing* fOuter; // Pointer to outer ring information
+
+ ClassDef(AliFMDDetector, 1); //
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// EOF
+//
//====================================================================
ClassImp(AliFMDBaseDigit)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDBaseDigit::AliFMDBaseDigit()
#include <AliLog.h> // ALILOG_H
#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
#include "AliFMDHit.h" // ALIFMDHIT_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
#include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
#include <AliLoader.h> // ALILOADER_H
#include <AliRunLoader.h> // ALIRUNLOADER_H
-//____________________________________________________________________
-ClassImp(AliFMDEdepMap)
-
//====================================================================
ClassImp(AliFMDBaseDigitizer)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDBaseDigitizer::AliFMDBaseDigitizer()
// the energy signal to ADC counts, and store the created digit in
// the digits array (AliFMD::fDigits)
//
+ AliFMDGeometry* geometry = AliFMDGeometry::Instance();
+
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;
- }
+ AliFMDDetector* det = geometry->GetDetector(detector);
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;
- }
+ AliFMDRing* r = det->GetRing((ringi == 0 ? 'I' : 'O'));
if (!r) continue;
// Get number of sectors
Float_t edep = fEdep(detector, r->GetId(), sector, strip).fEdep;
ConvertToCount(edep, last, r->GetSiThickness(),
- fmd->GetSiDensity(), counts);
+ geometry->GetSiDensity(), counts);
last = edep;
AddDigit(fmd, detector, r->GetId(), sector, strip,
edep, UShort_t(counts[0]),
//____________________________________________________________________
ClassImp(AliFMDEdepMap)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDEdepMap::AliFMDEdepMap(const AliFMDEdepMap& other)
--- /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 wafers. This class
+// contains the base procedures for the Forward Multiplicity detector
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
+//
+// This is the base class for all FMD manager classes.
+//
+// The actual code is done by various separate classes. Below is
+// diagram showing the relationship between the various FMD classes
+// that handles the simulation
+//
+// +--------+ 1 +-----------------+
+// | AliFMD |<>-----| AliFMDSimulator |
+// +--------+ +-----------------+
+// ^
+// |
+// +-------------+-------------+
+// | |
+// +--------------------+ +-------------------+
+// | AliFMDGeoSimulator | | AliFMDG3Simulator |
+// +--------------------+ +---------+---------+
+//
+//
+// * AliFMD
+// This defines the interface for the various parts of AliROOT that
+// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
+// AliFMDReconstructor, and so on.
+//
+// * AliFMDSimulator
+// This is the base class for the FMD simulation tasks. The
+// simulator tasks are responsible to implment the geoemtry, and
+// process hits.
+//
+// * AliFMDGeoSimulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TGeo classes directly only. This defines the active
+// volume as an ONLY XTRU shape with a divided MANY TUBS shape
+// inside to implement the particular shape of the silicon
+// sensors.
+//
+// * AliFMDG3Simulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TVirtualMC interface with GEANT 3.21-like messages.
+// This implements the active volume as a divided TUBS shape. Hits
+// in the corners should be cut away at run time (but currently
+// isn't).
+//
+#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliFMD1.h" // ALIFMD1_H
+#include "AliFMD2.h" // ALIFMD2_H
+#include "AliFMD3.h" // ALIFMD3_H
+#include "AliFMD.h" // ALIFMD_H
+#include <AliLog.h> // ALILOG_H
+#include <TVector2.h> // ROOT_TVector2
+#include <TVirtualMC.h> // ROOT_TVirtualMC
+#include <TArrayI.h> // ROOT_TArrayI
+
+//====================================================================
+ClassImp(AliFMDG3Simulator)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDG3Simulator::AliFMDG3Simulator()
+{
+ // Default constructor
+ fSectorOff = 1;
+ fModuleOff = 3;
+ fRingOff = 4;
+ fDetectorOff = 5;
+}
+
+//____________________________________________________________________
+AliFMDG3Simulator::AliFMDG3Simulator(AliFMD* fmd, Bool_t detailed)
+ : AliFMDSimulator(fmd, detailed)
+{
+ // Normal constructor
+ //
+ // Parameters:
+ //
+ // fmd Pointer to AliFMD object
+ // detailed Whether to make a detailed simulation or not
+ //
+ fSectorOff = 1;
+ fModuleOff = 3;
+ fRingOff = 4;
+ fDetectorOff = 5;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDG3Simulator::RingGeometry(AliFMDRing* r)
+{
+ // Setup the geometry of a ring. The defined TGeoVolume is
+ // returned, and should be used when setting up the rest of the
+ // volumes.
+ //
+ // Parameters:
+ //
+ // r Pointer to ring geometry object
+ //
+ // Returns:
+ // true on success
+ //
+ if (!r) {
+ AliError("Didn't get a ring object");
+ return kFALSE;
+ }
+ Char_t id = r->GetId();
+ Double_t siThick = r->GetSiThickness();
+ // const Int_t nv = r->GetNVerticies();
+ TVector2* a = r->GetVertex(5);
+ TVector2* b = r->GetVertex(3);
+ TVector2* c = r->GetVertex(4);
+ Double_t theta = r->GetTheta();
+ Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
+ * r->GetBondingWidth());
+ Double_t rmax = b->Mod();
+ Double_t rmin = r->GetLowR();
+ Double_t pcbThick = r->GetPrintboardThickness();
+ Double_t modSpace = r->GetModuleSpacing();
+ Double_t legr = r->GetLegRadius();
+ Double_t legl = r->GetLegLength();
+ Double_t legoff = r->GetLegOffset();
+ Int_t ns = r->GetNStrips();
+ Double_t stripoff = a->Mod();
+ Double_t dstrip = (rmax - stripoff) / ns;
+ Double_t par[10];
+ TString name;
+ TString name2;
+ TVirtualMC* mc = TVirtualMC::GetMC();
+
+ Int_t siId = fFMD->GetIdtmed()->At(kSiId);
+ Int_t airId = fFMD->GetIdtmed()->At(kAirId);
+ Int_t pcbId = fFMD->GetIdtmed()->At(kPcbId);
+ Int_t plaId = fFMD->GetIdtmed()->At(kPlasticId);
+
+ // Virtual volume shape to divide - This volume is only defined if
+ // the geometry is set to be detailed.
+ // Ring mother volume
+ par[0] = rmin;
+ par[1] = rmax;
+ par[2] = (siThick + pcbThick + legl + modSpace) / 2;
+ name = Form(fgkRingName, id);
+ mc->Gsvolu(name.Data(), "TUBE", airId, par, 3);
+
+ par[0] = rmin;
+ par[1] = rmax;
+ par[2] = siThick / 2;
+ par[3] = -theta;
+ par[4] = theta;
+ name = Form(fgkActiveName, id);
+ mc->Gsvolu(name.Data(), "TUBS", (fDetailed ? airId : siId), par, 5);
+
+ Int_t sid = -1;
+ if (fDetailed) {
+ name2 = name;
+ name = Form(fgkSectorName, id);
+ mc->Gsdvn2(name.Data(), name2.Data(), 2, 2, -theta, airId);
+
+ name2 = name;
+ name = Form(fgkStripName, id);
+ mc->Gsdvt2(name.Data(), name2.Data(), dstrip, 1, stripoff, siId, ns);
+ sid = mc->VolId(name.Data());
+ AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
+ }
+
+ switch (id) {
+ case 'i':
+ case 'I':
+ fInnerId = sid;
+ // fInnerV = moduleVolume->GetNumber();
+ break;
+ case 'o':
+ case 'O':
+ fOuterId = sid;
+ // fOuterV = moduleVolume->GetNumber();
+ break;
+ }
+
+ // Shape of Printed circuit Board
+ // Top
+ par[0] = c->Y() - off;
+ par[1] = b->Y() - off;
+ par[2] = pcbThick / 2;
+ par[3] = (b->X() - c->X()) / 2;
+ par[4] = off;
+ name = Form(fgkPCBName, id, 'T');
+ mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
+ // Bottom
+ par[0] = a->Y() - off;
+ par[1] = c->Y() - off;
+ par[3] = (c->X() - a->X()) / 2;
+ name = Form(fgkPCBName, id, 'B');
+ mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
+
+ // Short leg volume
+ par[0] = legr - .1;
+ par[1] = legr;
+ par[2] = legl / 2;
+ name = Form(fgkShortLegName, id);
+ mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
+
+ // Long leg volume
+ par[2] += modSpace / 2;
+ name = Form(fgkLongLegName, id);
+ mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
+
+ // Back container volume
+ par[0] = rmin;
+ par[1] = rmax;
+ par[2] = (siThick + pcbThick + legl) / 2;
+ par[3] = -theta;
+ par[4] = +theta;
+ name = Form(fgkBackVName, id);
+ mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+
+ Double_t x = 0;
+ Double_t y = 0;
+ Double_t z = - par[2] + siThick / 2;
+ name2 = name;
+ name = Form(fgkActiveName, id);
+ mc->Gspos(name.Data(), 0, name2.Data(), x, y, z, 0, "ONLY");
+
+ Double_t pbTopL = (b->X() - c->X());
+ Double_t pbBotL = (c->X() - a->X());
+ Int_t pbRot;
+ mc->Matrix(pbRot, 90, 90, 0, 90, 90, 0);
+
+ x = rmin + pbBotL + pbTopL / 2;
+ z += siThick / 2 + pcbThick / 2;
+ name = Form(fgkPCBName, id, 'T');
+ mc->Gspos(name.Data(), 0, name2.Data(), x, y, z, pbRot, "ONLY");
+
+ x = rmin + pbBotL / 2;
+ name = Form(fgkPCBName, id, 'B');
+ mc->Gspos(name.Data(), 0, name2.Data(), x, y, z, pbRot, "ONLY");
+
+ x = a->X() + legoff + legr;
+ y = 0;
+ z += pcbThick / 2 + legl / 2;
+ name = Form(fgkShortLegName, id);
+ mc->Gspos(name.Data(), 0, name2.Data(), x, y, z, 0, "ONLY");
+
+ x = c->X();
+ y = c->Y() - legoff - legr - off;
+ mc->Gspos(name.Data(), 1, name2.Data(), x, y, z, 0, "ONLY");
+
+ y = -y;
+ mc->Gspos(name.Data(), 2, name2.Data(), x, y, z, 0, "ONLY");
+
+
+ // Front container volume
+ par[2] += modSpace / 2;
+ name = Form(fgkFrontVName, id);
+ mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+
+ x = 0;
+ y = 0;
+ z = - par[2] + siThick / 2;
+ name2 = name;
+ name = Form(fgkActiveName, id);
+ mc->Gspos(name.Data(), 1, name2.Data(), x, y, z, 0, "ONLY");
+
+ pbTopL = (b->X() - c->X());
+ pbBotL = (c->X() - a->X());
+ x = rmin + pbBotL + pbTopL / 2;
+ z += siThick / 2 + pcbThick / 2;
+ name = Form(fgkPCBName, id, 'T');
+ mc->Gspos(name.Data(), 1, name2.Data(), x, y, z, pbRot, "ONLY");
+
+ x = rmin + pbBotL / 2;
+ name = Form(fgkPCBName, id, 'B');
+ mc->Gspos(name.Data(), 1, name2.Data(), x, y, z, pbRot, "ONLY");
+
+ x = a->X() + legoff + legr;
+ y = 0;
+ z += pcbThick / 2 + legl / 2 + modSpace / 2;
+ name = Form(fgkLongLegName, id);
+ mc->Gspos(name.Data(), 0, name2.Data(), x, y, z, 0, "ONLY");
+
+ x = c->X();
+ y = c->Y() - legoff - legr - off;
+ mc->Gspos(name.Data(), 1, name2.Data(), x, y, z, 0, "ONLY");
+
+ y = -y;
+ mc->Gspos(name.Data(), 2, name2.Data(), x, y, z, 0, "ONLY");
+
+
+
+ Int_t nmod = r->GetNModules();
+ name2 = Form(fgkRingName, id);
+ AliDebug(10, Form("making %d modules in ring %c", nmod, id));
+ for (Int_t i = 0; i < nmod; i++) {
+ Double_t th = (i + .5) * 2 * theta;
+ Bool_t isFront = (i % 2 == 0);
+ name = (isFront ? Form(fgkFrontVName,id) :
+ Form(fgkBackVName,id));
+ Double_t z = (isFront ? 0 : modSpace) / 2;
+ Int_t rot;
+ mc->Matrix(rot, 90, th, 90, fmod(90 + th, 360), 0, 0);
+ mc->Gspos(name.Data(), i, name2.Data(), 0, 0, z, rot, "ONLY");
+ }
+
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDG3Simulator::DetectorGeometry(AliFMDDetector* d, Double_t zmother)
+{
+ // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
+ // This includes putting the Honeycomb support plates and the rings
+ // into the mother volumes.
+ //
+ // Parameeters:
+ // d The detector geometry to use
+ // zmother The midpoint in global coordinates of detector vol.
+ //
+ // Returns:
+ // true on success
+ //
+ if (!d) return kFALSE;
+
+ TString name;
+ TString name2;
+ TVirtualMC* mc = TVirtualMC::GetMC();
+
+ // Loop over the defined rings
+ for (int i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ Double_t lowr = 0;
+ Double_t highr = 0;
+ Double_t rz = 0;
+ switch (i) {
+ case 0:
+ r = d->GetInner();
+ lowr = d->GetInnerHoneyLowR();
+ highr = d->GetInnerHoneyHighR();
+ rz = d->GetInnerZ();
+ break;
+ case 1:
+ r = d->GetOuter();
+ lowr = d->GetOuterHoneyLowR();
+ highr = d->GetOuterHoneyHighR();
+ rz = d->GetOuterZ();
+ break;
+ }
+ if (!r) continue;
+ Char_t c = r->GetId();
+ Int_t id = d->GetId();
+ Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
+ Int_t alId = (fFMD->GetIdtmed()->At(kAlId));
+ Double_t hcThick = d->GetHoneycombThickness();
+ Double_t alThick = d->GetAlThickness();
+ Double_t par[10];
+ Double_t z;
+ // Place ring in mother volume
+ if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
+ else z = zmother - rz + r->GetRingDepth() / 2;
+ name = Form(fgkRingName, c);
+ name2 = d->GetName();
+ mc->Gspos(name.Data(), Int_t(c), name2.Data(), 0, 0, z, 0, "ONLY");
+
+ // Place Top Honeycomb in mother volume
+ z += + r->GetRingDepth() / 2 + hcThick / 2;
+ // Top of Honeycomb
+ par[0] = lowr;
+ par[1] = highr;
+ par[2] = hcThick / 2;
+ par[3] = 0;
+ par[4] = 180;
+ name = Form(fgkTopHCName, id, c);
+ mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
+ mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
+
+ par[0] += alThick;
+ par[1] -= alThick;
+ par[2] -= alThick / 2;
+ name2 = name;
+ name = Form(fgkTopIHCName, id, c);
+ mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+ mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
+
+ // Bot of Honeycomb
+ par[0] = lowr;
+ par[1] = highr;
+ par[2] = hcThick / 2;
+ par[3] = 180;
+ par[4] = 360;
+ name2 = d->GetName();
+ name = Form(fgkBotHCName, id, c);
+ mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
+ mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
+
+ par[0] += alThick;
+ par[1] -= alThick;
+ par[2] -= alThick / 2;
+ name2 = name;
+ name = Form(fgkBotIHCName, id, c);
+ mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
+ mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
+ }
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDG3Simulator::FMD1Geometry(AliFMD1* fmd1)
+{
+ // Setup the FMD1 geometry. The FMD1 only has one ring, and no
+ // special support as it is at the momement.
+ //
+ // See also AliFMDG3Simulator::DetectorGeometry
+ //
+ if (!fmd1) return kFALSE;
+ Double_t rmin = fmd1->GetInner()->GetLowR();
+ Double_t rmax = fmd1->GetInnerHoneyHighR();
+ Double_t hcThick = fmd1->GetHoneycombThickness();
+ Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
+ Double_t z = fmd1->GetInnerZ() + w / 2;
+ TVirtualMC* mc = TVirtualMC::GetMC();
+ Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
+
+ Double_t par[3];
+ par[0] = rmin;
+ par[1] = rmax;
+ par[2] = w / 2;
+ mc->Gsvolu(fmd1->GetName(), "TUBE", airId, par, 3);
+ mc->Gspos(fmd1->GetName(), fmd1->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
+
+ return DetectorGeometry(fmd1, z);
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDG3Simulator::FMD2Geometry(AliFMD2* fmd2)
+{
+ // Setup the FMD2 geometry. The FMD2 has no
+ // special support as it is at the momement.
+ //
+ // See also AliFMDG3Simulator::DetectorGeometry
+ //
+ if (!fmd2) return kFALSE;
+ Double_t rmin = fmd2->GetInner()->GetLowR();
+ Double_t rmax = fmd2->GetOuterHoneyHighR();
+ Double_t hcThick = fmd2->GetHoneycombThickness();
+ Double_t ow = fmd2->GetInner()->GetRingDepth();
+ Double_t iz = fmd2->GetInnerZ();
+ Double_t oz = fmd2->GetOuterZ();
+ Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
+ Double_t z = oz + w / 2;
+
+ TVirtualMC* mc = TVirtualMC::GetMC();
+ Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
+
+ Double_t par[3];
+ par[0] = rmin;
+ par[1] = rmax;
+ par[2] = w / 2;
+ mc->Gsvolu(fmd2->GetName(), "TUBE", airId, par, 3);
+ mc->Gspos(fmd2->GetName(), fmd2->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
+
+ return DetectorGeometry(fmd2, z);
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDG3Simulator::FMD3Geometry(AliFMD3* fmd3)
+{
+ // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
+ // structure, as the support will also support the vacuum
+ // beam-pipe.
+ //
+ // See also AliFMDG3Simulator::DetectorGeometry
+ //
+ if (!fmd3) return kFALSE;
+ Double_t nlen = fmd3->GetNoseLength();
+ Double_t nz = fmd3->GetNoseZ();
+ Double_t noser1 = fmd3->GetNoseLowR();
+ Double_t noser2 = fmd3->GetNoseHighR();
+ Double_t conel = fmd3->GetConeLength();
+ Double_t backl = fmd3->GetBackLength();
+ Double_t backr1 = fmd3->GetBackLowR();
+ Double_t backr2 = fmd3->GetBackHighR();
+ Double_t zdist = conel - backl - nlen;
+ Double_t tdist = backr2 - noser2;
+ Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
+ Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
+ Double_t innerZ = fmd3->GetInnerZ();
+ Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
+ - fmd3->GetHoneycombThickness());
+ Double_t outerZ = fmd3->GetOuterZ();
+ Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
+ - fmd3->GetHoneycombThickness());
+ Double_t innerr1 = fmd3->GetInner()->GetLowR();
+ // Double_t innerr2 = fmd3->GetInner()->GetHighR();
+ Double_t outerr1 = fmd3->GetOuter()->GetLowR();
+ // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
+ Double_t flanger = fmd3->GetFlangeR();
+ Double_t minZ = TMath::Min(nz - conel, outerZh);
+ Double_t z = fmd3->GetZ();
+ Double_t zi;
+ TVirtualMC* mc = TVirtualMC::GetMC();
+ Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
+ Int_t cId = (fFMD->GetIdtmed()->At(kCarbonId));
+ Double_t par[27];
+
+ // FMD3 volume
+ par[0] = 0;
+ par[1] = 360;
+ par[2] = 8;
+ // First
+ par[3] = z - nz;
+ par[4] = noser1;
+ par[5] = noser2;
+ // Second
+ par[6] = z - (nz - nlen);
+ par[7] = noser1;
+ par[8] = fmd3->ConeR(z - par[6])+.15;
+ // Third
+ par[9] = z - innerZ;
+ par[10] = innerr1;
+ par[11] = fmd3->ConeR(z - par[9])+.15;
+ // Fourth
+ par[12] = z - innerZh;
+ par[13] = innerr1;
+ par[14] = fmd3->ConeR(z - par[12])+.15;
+ // Fifth
+ par[15] = par[12];
+ par[16] = outerr1;
+ par[17] = fmd3->ConeR(z - par[15])+.15;
+ // Sixth
+ par[18] = z - nz + zdist + nlen;
+ par[19] = outerr1;
+ par[20] = fmd3->ConeR(z - par[18])+.15;
+ // Seventh
+ par[21] = z - nz + nlen + zdist;
+ par[22] = outerr1;
+ par[23] = flanger+1.5;
+ // Eight
+ par[24] = z - minZ;
+ par[25] = outerr1;
+ par[26] = flanger+1.5;
+ mc->Gsvolu(fmd3->GetName(), "PCON", airId, par, 27);
+
+ Int_t id;
+ mc->Matrix(id, 270, 180, 90, 90, 180, 0);
+ mc->Gspos(fmd3->GetName(), fmd3->GetId(), "ALIC", 0, 0, z, id, "ONLY");
+
+ // Nose volume
+ par[0] = noser1;
+ par[1] = noser2;
+ par[2] = nlen / 2;
+ zi = z - nz + nlen / 2;
+ mc->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
+ mc->Gspos(fgkNoseName, 0, fmd3->GetName(), 0, 0, zi, 0, "MANY");
+
+ // Back
+ par[0] = backr1;
+ par[1] = backr2;
+ par[2] = backl / 2;
+ zi = z - nz + conel - backl / 2;
+ mc->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
+ mc->Gspos(fgkBackName, 0, fmd3->GetName(), 0, 0, zi, 0, "ONLY");
+
+ Int_t n;
+ Double_t r;
+ // The flanges
+ par[0] = (flanger - backr2) / 2;
+ par[1] = fmd3->GetBeamWidth() / 2;
+ par[2] = backl / 2;
+ mc->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
+ n = fmd3->GetNFlange();
+ r = backr2 + (flanger - backr2) / 2;
+ for (Int_t i = 0; i < n; i++) {
+ Double_t phi = 360. / n * i + 180. / n;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ Int_t id;
+ mc->Matrix(id, 90, phi, 90, 90 + phi, 0, 0);
+ mc->Gspos(fgkFlangeName, i, fmd3->GetName(), x, y, zi, id, "ONLY");
+ }
+
+ // The Beams
+ par[0] = fmd3->GetBeamThickness() / 2;
+ par[1] = fmd3->GetBeamWidth() / 2;
+ par[2] = beaml / 2;
+ mc->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
+ n = fmd3->GetNBeam();
+ r = noser2 + tdist / 2;
+ zi = z - nz + nlen + zdist / 2;
+ for (Int_t i = 0; i < n; i++) {
+ Double_t phi = 360. / n * i;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ Int_t id;
+ (void)theta;
+ mc->Matrix(id, 90-theta, phi, 90, 90 + phi, 360 - theta, phi);
+ mc->Gspos(fgkBeamName, i, fmd3->GetName(), x, y, zi, id, "MANY");
+ }
+
+ return DetectorGeometry(fmd3, z);
+}
+
+//____________________________________________________________________
+void
+AliFMDG3Simulator::DefineGeometry()
+{
+ // Setup up the FMD geometry.
+ AliDebug(10, "Setting up volume");
+
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ if (!RingGeometry(fmd->GetInner())) {
+ AliError("Failed to create inner ring volume");
+ return;
+ }
+ if (!RingGeometry(fmd->GetOuter())) {
+ AliError("Failed to create outer ring volume");
+ return;
+ }
+ FMD1Geometry(fmd->GetFMD1());
+ FMD2Geometry(fmd->GetFMD2());
+ FMD3Geometry(fmd->GetFMD3());
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDG3SIMULATOR_H
+#define ALIFMDG3SIMULATOR_H
+/* 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 ALIFMDSIMULATOR
+# include <AliFMDSimulator.h>
+#endif
+class AliFMD;
+class AliFMDRing;
+class AliFMDDetector;
+class AliFMD1;
+class AliFMD2;
+class AliFMD3;
+
+//____________________________________________________________________
+class AliFMDG3Simulator : public AliFMDSimulator
+{
+public:
+ AliFMDG3Simulator();
+ /** CTOR */
+ AliFMDG3Simulator(AliFMD* fmd, Bool_t detailed=kTRUE);
+ virtual ~AliFMDG3Simulator() {}
+ /** Register */
+ virtual void DefineGeometry();
+protected:
+ /** Make a ring volume
+ @param r Ring geometry
+ @return Ring volume */
+ Bool_t RingGeometry(AliFMDRing* r);
+ /** Make a detector volume
+ @param d Detector geometry
+ @param mother Mother volume (detector volume)
+ @param zmother Z position of mother
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return Detector volume */
+ Bool_t DetectorGeometry(AliFMDDetector* d, Double_t zmother);
+ /** Make FMD1 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @return FMD1 volume */
+ Bool_t FMD1Geometry(AliFMD1* d);
+ /** Make FMD2 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return FMD2 volume */
+ Bool_t FMD2Geometry(AliFMD2* d);
+ /** Make FMD3 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return FMD3 volume */
+ Bool_t FMD3Geometry(AliFMD3* d);
+
+ ClassDef(AliFMDG3Simulator,1);
+};
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// 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$ */
+
+//____________________________________________________________________
+//
+// Forward Multiplicity Detector based on Silicon wafers. This class
+// contains the base procedures for the Forward Multiplicity detector
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
+//
+// This is the base class for all FMD manager classes.
+//
+// The actual code is done by various separate classes. Below is
+// diagram showing the relationship between the various FMD classes
+// that handles the simulation
+//
+// +--------+ 1 +-----------------+
+// | AliFMD |<>-----| AliFMDSimulator |
+// +--------+ +-----------------+
+// ^
+// |
+// +-------------+-------------+
+// | |
+// +--------------------+ +-------------------+
+// | AliFMDGeoSimulator | | AliFMDG3Simulator |
+// +--------------------+ +---------+---------+
+//
+//
+// * AliFMD
+// This defines the interface for the various parts of AliROOT that
+// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
+// AliFMDReconstructor, and so on.
+//
+// * AliFMDSimulator
+// This is the base class for the FMD simulation tasks. The
+// simulator tasks are responsible to implment the geoemtry, and
+// process hits.
+//
+// * AliFMDGeoSimulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TGeo classes directly only. This defines the active
+// volume as an ONLY XTRU shape with a divided MANY TUBS shape
+// inside to implement the particular shape of the silicon
+// sensors.
+//
+// * AliFMDG3Simulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TVirtualMC interface with GEANT 3.21-like messages.
+// This implements the active volume as a divided TUBS shape. Hits
+// in the corners should be cut away at run time (but currently
+// isn't).
+//
+#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliFMD1.h" // ALIFMD1_H
+#include "AliFMD2.h" // ALIFMD2_H
+#include "AliFMD3.h" // ALIFMD3_H
+#include "AliFMD.h" // ALIFMD_H
+#include "AliLog.h" // ALILOG_H
+#include <TGeoVolume.h> // ROOT_TGeoVolume
+#include <TGeoTube.h> // ROOT_TGeoTube
+#include <TGeoPcon.h> // ROOT_TGeoPcon
+#include <TGeoMaterial.h> // ROOT_TGeoMaterial
+#include <TGeoMedium.h> // ROOT_TGeoMedium
+#include <TGeoXtru.h> // ROOT_TGeoXtru
+#include <TGeoPolygon.h> // ROOT_TGeoPolygon
+#include <TGeoTube.h> // ROOT_TGeoTube
+#include <TGeoManager.h> // ROOT_TGeoManager
+#include <TVector2.h> // ROOT_TVector2
+#include <TArrayD.h> // ROOT_TArrayD
+
+//====================================================================
+ClassImp(AliFMDGeoSimulator)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDGeoSimulator::AliFMDGeoSimulator()
+ : fSi(0),
+ fC(0),
+ fAl(0),
+ fPCB(0),
+ fChip(0),
+ fPlastic(0)
+{
+ // Default constructor
+ fSectorOff = 1;
+ fModuleOff = 4;
+ fRingOff = 5;
+ fDetectorOff = 6;
+}
+
+//____________________________________________________________________
+AliFMDGeoSimulator::AliFMDGeoSimulator(AliFMD* fmd, Bool_t detailed)
+ : AliFMDSimulator(fmd, detailed),
+ fSi(0),
+ fC(0),
+ fAl(0),
+ fPCB(0),
+ fChip(0),
+ fPlastic(0)
+{
+ // Normal constructor
+ //
+ // Parameters:
+ //
+ // fmd Pointer to AliFMD object
+ // detailed Whether to make a detailed simulation or not
+ //
+ fSectorOff = 1;
+ fModuleOff = 4;
+ fRingOff = 5;
+ fDetectorOff = 6;
+}
+
+//____________________________________________________________________
+void
+AliFMDGeoSimulator::DefineMaterials()
+{
+ // Define the materials and tracking mediums needed by the FMD
+ // simulation. These mediums are made by sending the messages
+ // AliMaterial, AliMixture, and AliMedium to the passed AliModule
+ // object module. The defined mediums are
+ //
+ // FMD Si$ Silicon (active medium in sensors)
+ // FMD C$ Carbon fibre (support cone for FMD3 and vacuum pipe)
+ // FMD Al$ Aluminium (honeycomb support plates)
+ // FMD PCB$ Printed Circuit Board (FEE board with VA1_ALICE)
+ // FMD Chip$ Electronics chips (currently not used)
+ // FMD Air$ Air (Air in the FMD)
+ // FMD Plastic$ Plastic (Support legs for the hybrid cards)
+ //
+ // Pointers to TGeoMedium objects are retrived from the TGeoManager
+ // singleton. These pointers are later used when setting up the
+ // geometry
+ AliDebug(10, "\tCreating materials");
+
+ if (!gGeoManager) {
+ AliFatal("No TGeoManager defined");
+ return;
+ }
+ AliFMDSimulator::DefineMaterials();
+ fSi = gGeoManager->GetMedium("FMD Si$");
+ fC = gGeoManager->GetMedium("FMD Carbon$");
+ fAl = gGeoManager->GetMedium("FMD Aluminum$");
+ fChip = gGeoManager->GetMedium("FMD Chip$");
+ fAir = gGeoManager->GetMedium("FMD Air$");
+ fPCB = gGeoManager->GetMedium("FMD PCB$");
+ fPlastic = gGeoManager->GetMedium("FMD Plastic$");
+}
+
+//____________________________________________________________________
+TGeoVolume*
+AliFMDGeoSimulator::RingGeometry(AliFMDRing* r)
+{
+ // Setup the geometry of a ring. The defined TGeoVolume is
+ // returned, and should be used when setting up the rest of the
+ // volumes.
+ //
+ //
+ // Parameters:
+ //
+ // r Pointer to ring geometry object
+ //
+ // Returns:
+ // pointer to ring volume
+ //
+ if (!r) {
+ AliError("Didn't get a ring object");
+ return 0;
+ }
+ Char_t id = r->GetId();
+ Double_t siThick = r->GetSiThickness();
+ const Int_t nv = r->GetNVerticies();
+ TVector2* a = r->GetVertex(5);
+ TVector2* b = r->GetVertex(3);
+ TVector2* c = r->GetVertex(4);
+ Double_t theta = r->GetTheta();
+ Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
+ * r->GetBondingWidth());
+ Double_t rmax = b->Mod();
+ Double_t rmin = r->GetLowR();
+ Double_t pcbThick = r->GetPrintboardThickness();
+ Double_t modSpace = r->GetModuleSpacing();
+ Double_t legr = r->GetLegRadius();
+ Double_t legl = r->GetLegLength();
+ Double_t legoff = r->GetLegOffset();
+ Int_t ns = r->GetNStrips();
+ Double_t stripoff = a->Mod();
+ Double_t dstrip = (rmax - stripoff) / ns;
+ TArrayD xs(nv);
+ TArrayD ys(nv);
+ for (Int_t i = 0; i < nv; i++) {
+ // Reverse the order
+ TVector2* vv = r->GetVertex(nv - 1 - i);
+ if (!vv) {
+ AliError(Form("Failed to get vertex # %d", nv - 1 - i));
+ continue;
+ }
+ xs[i] = vv->X();
+ ys[i] = vv->Y();
+ }
+
+ // Virtual volume shape to divide - This volume is only defined if
+ // the geometry is set to be detailed.
+ Int_t sid = -1;
+ TGeoVolume* activeVolume = 0;
+ if (fDetailed) {
+ TGeoTubeSeg* activeShape =
+ new TGeoTubeSeg(rmin, rmax, siThick/2, - theta, theta);
+ activeVolume = new TGeoVolume(Form(fgkActiveName, id), activeShape, fSi);
+ TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName, id),
+ 2, 2, -theta, 0, 0, "N");
+ TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id), 1,
+ ns, stripoff, dstrip,
+ 0, "SX");
+ sid = stripVolume->GetNumber();
+ }
+
+ // Shape of actual sensor
+ TGeoXtru* moduleShape = new TGeoXtru(2);
+ moduleShape->DefinePolygon(nv, xs.fArray, ys.fArray);
+ moduleShape->DefineSection(0, - siThick/2);
+ moduleShape->DefineSection(1, siThick/2);
+ TGeoVolume* moduleVolume = new TGeoVolume(Form(fgkModuleName, id),
+ moduleShape, fSi);
+ // Add divived MANY volume to the true shape of the module, but only
+ // if a detailed simulation is reguested.
+ if (activeVolume) moduleVolume->AddNodeOverlap(activeVolume, 0);
+
+ switch (id) {
+ case 'i':
+ case 'I':
+ fInnerId = sid;
+ // fInnerV = moduleVolume->GetNumber();
+ break;
+ case 'o':
+ case 'O':
+ fOuterId = sid;
+ // fOuterV = moduleVolume->GetNumber();
+ break;
+ }
+
+ // Shape of Printed circuit Board
+ TGeoXtru* pcbShape = new TGeoXtru(2);
+ for (Int_t i = 0; i < nv / 2; i++) ys[i] -= off;
+ for (Int_t i = nv / 2; i < nv; i++) ys[i] += off;
+ pcbShape->DefinePolygon(nv, xs.fArray, ys.fArray);
+ pcbShape->DefineSection(0, - pcbThick/2);
+ pcbShape->DefineSection(1, pcbThick/2);
+ TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id, 'B'),
+ pcbShape, fPCB);
+
+ // Short leg shape
+ TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
+ TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
+ shortLegShape, fPlastic);
+
+ // Long leg shape
+ TGeoTube* longLegShape = new TGeoTube(0, legr, (legl + modSpace) / 2);
+ TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
+ longLegShape, fPlastic);
+
+ TGeoMatrix* matrix = 0;
+ // Back container volume
+ Double_t contThick = siThick + pcbThick + legl;
+ TGeoTubeSeg* backShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
+ - theta, theta);
+ TGeoVolume* backVolume = new TGeoVolume(Form(fgkBackVName, id),
+ backShape, fAir);
+ Double_t x = 0;
+ Double_t y = 0;
+ Double_t z = -contThick / 2 + siThick / 2;
+ matrix = new TGeoTranslation(Form("FMD Ring %c mod 1 transform", id),
+ x, y, z);
+ backVolume->AddNode(moduleVolume, 0, matrix);
+ z += siThick / 2 + pcbThick / 2;
+ matrix = new TGeoTranslation(Form("FMD Ring %c pcb 1 transfrom", id),
+ x, y, z);
+ backVolume->AddNode(pcbVolume, 0, matrix);
+ x = a->X() + legoff + legr;
+ y = 0;
+ z += pcbThick / 2 + legl / 2;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 1 transfrom", id),
+ x, y, z);
+ backVolume->AddNode(shortLegVolume, 0, matrix);
+ x = c->X();
+ y = c->Y() - legoff - legr - off;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 2 transfrom", id),
+ x, y, z);
+ backVolume->AddNode(shortLegVolume, 1, matrix);
+ y = -y;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 3 transfrom", id),
+ x, y, z);
+ backVolume->AddNode(shortLegVolume, 2, matrix);
+ // backVolume->SetVisibility(kFALSE);
+ // backVolume->VisibleDaughters(kTRUE);
+
+ // Front container volume
+ contThick += modSpace;
+ TGeoTubeSeg* frontShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
+ -theta, theta);
+ TGeoVolume* frontVolume = new TGeoVolume(Form(fgkFrontVName, id),
+ frontShape, fAir);
+ x = 0;
+ y = 0;
+ z = -contThick / 2 + siThick / 2 ;
+ matrix = new TGeoTranslation(Form("FMD Ring %c mod 2 transfrom", id),
+ 0, 0, z);
+ frontVolume->AddNode(moduleVolume, 1, matrix);
+ z += siThick / 2 + pcbThick / 2;
+ matrix = new TGeoTranslation(Form("FMD Ring %c pcb 2 transfrom", id),
+ x, y, z);
+ frontVolume->AddNode(pcbVolume, 1, matrix);
+ x = a->X() + legoff + legr;
+ y = 0;
+ z += pcbThick / 2 + (legl + modSpace)/ 2;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
+ x, y, z);
+ frontVolume->AddNode(longLegVolume, 0, matrix);
+ x = c->X();
+ y = c->Y() - legoff - legr - off;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
+ x, y, z);
+ frontVolume->AddNode(longLegVolume, 1, matrix);
+ y = -y;
+ matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
+ x, y, z);
+ frontVolume->AddNode(longLegVolume, 2, matrix);
+ // frontVolume->SetVisibility(kFALSE);
+ // frontVolume->VisibleDaughters(kTRUE);
+
+ // Ring mother volume
+ TGeoTube* ringShape = new TGeoTube(rmin, rmax, contThick / 2);
+ TGeoVolume* ringVolume = new TGeoVolume(Form(fgkRingName, id), ringShape,
+ fAir);
+
+ Int_t nmod = r->GetNModules();
+ AliDebug(10, Form("making %d modules in ring %c", nmod, id));
+ for (Int_t i = 0; i < nmod; i++) {
+ Bool_t isFront = (i % 2 == 0);
+ TGeoVolume* vol = (isFront ? frontVolume : backVolume);
+ TGeoRotation* rot = new TGeoRotation(Form("FMD Ring %c rotation %d",id,i));
+ rot->RotateZ((i + .5) * 2 * theta);
+ Double_t z = (isFront ? 0 : modSpace) / 2;
+ matrix = new TGeoCombiTrans(Form("FMD Ring %c transform %d", id, i),
+ 0, 0, z, rot);
+ ringVolume->AddNode(vol, i, matrix);
+ }
+
+ ringVolume->SetVisibility(kFALSE);
+ ringVolume->VisibleDaughters(kTRUE);
+ return ringVolume;
+}
+
+//____________________________________________________________________
+TGeoVolume*
+AliFMDGeoSimulator::DetectorGeometry(AliFMDDetector* d,
+ TGeoVolume* mother,
+ Double_t zmother,
+ TGeoVolume* inner,
+ TGeoVolume* outer)
+{
+ // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
+ // This includes putting the Honeycomb support plates and the rings
+ // into the mother volumes.
+ //
+ // Parameeters:
+ // d The detector geometry to use
+ // mother The mother volume of the detector
+ // zmother The midpoint in global coordinates of detector vol.
+ // inner Pointer to inner ring volume
+ // outer Pointer to outer ring volume
+ //
+ // Returns:
+ // Pointer to mother (detector volume)
+ //
+ if (!d) return 0;
+ // Loop over the defined rings
+ for (int i = 0; i < 2; i++) {
+ AliFMDRing* r = 0;
+ Double_t lowr = 0;
+ Double_t highr = 0;
+ Double_t rz = 0;
+ TGeoVolume* rvol = 0;
+ switch (i) {
+ case 0:
+ r = d->GetInner();
+ lowr = d->GetInnerHoneyLowR();
+ highr = d->GetInnerHoneyHighR();
+ rz = d->GetInnerZ();
+ rvol = inner;
+ break;
+ case 1:
+ r = d->GetOuter();
+ lowr = d->GetOuterHoneyLowR();
+ highr = d->GetOuterHoneyHighR();
+ rz = d->GetOuterZ();
+ rvol = outer;
+ break;
+ }
+ if (!r) continue;
+ Char_t c = r->GetId();
+ Int_t id = d->GetId();
+ Double_t hcThick = d->GetHoneycombThickness();
+ Double_t alThick = d->GetAlThickness();
+ Double_t z;
+ if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
+ else z = zmother - rz + r->GetRingDepth() / 2;
+ // Place ring in mother volume
+ mother->AddNode(rvol, Int_t(c),
+ new TGeoTranslation(Form("FMD%d%c transform", id, c),
+ 0, 0, z));
+
+ z += r->GetRingDepth() / 2 + hcThick / 2;
+ // Top of Honeycomb
+ TGeoTubeSeg* topHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
+ TGeoVolume* topHCVolume = new TGeoVolume(Form(fgkTopHCName, id, c),
+ topHCShape, fAl);
+ TGeoMatrix* topHCMatrix =
+ new TGeoTranslation(Form("FMD%d%c top HC transform", id, c), 0, 0, z);
+ mother->AddNode(topHCVolume, 0, topHCMatrix);
+
+ // Air in top of honeycomb
+ TGeoTubeSeg* topIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
+ (hcThick-alThick)/2, 0, 180);
+ TGeoVolume* topIHCVolume = new TGeoVolume(Form(fgkTopIHCName, id, c),
+ topIHCShape, fAir);
+ topHCVolume->AddNode(topIHCVolume, 0);
+ topHCVolume->VisibleDaughters(kFALSE);
+ topHCVolume->SetVisibility(kTRUE);
+
+
+ // Bottom of Honeycomb
+ TGeoTubeSeg* botHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2,
+ 180, 360);
+ TGeoVolume* botHCVolume = new TGeoVolume(Form(fgkBotHCName, id, c),
+ botHCShape, fAl);
+ TGeoMatrix* botHCMatrix =
+ new TGeoTranslation(Form("FMD%d%c bottom HC transform", id, c), 0, 0, z);
+ mother->AddNode(botHCVolume, 0, botHCMatrix);
+
+ // Air in bot of honeycomb
+ TGeoTubeSeg* botIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
+ (hcThick-alThick)/2, 180, 360);
+ TGeoVolume* botIHCVolume = new TGeoVolume(Form(fgkBotIHCName, id, c),
+ botIHCShape, fAir);
+ botHCVolume->AddNode(botIHCVolume, 0);
+ botHCVolume->VisibleDaughters(kFALSE);
+ botHCVolume->SetVisibility(kTRUE);
+ }
+ mother->SetVisibility(kFALSE);
+ mother->VisibleDaughters(kTRUE);
+ return mother;
+}
+
+//____________________________________________________________________
+TGeoVolume*
+AliFMDGeoSimulator::FMD1Geometry(AliFMD1* fmd1, TGeoVolume* inner)
+{
+ // Setup the FMD1 geometry. The FMD1 only has one ring, and no
+ // special support as it is at the momement.
+ //
+ // See also AliFMDGeoSimulator::DetectorGeometry
+ //
+ if (!fmd1 || !inner) return 0;
+ Double_t rmin = fmd1->GetInner()->GetLowR();
+ Double_t rmax = fmd1->GetInnerHoneyHighR();
+ Double_t hcThick = fmd1->GetHoneycombThickness();
+ Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
+ Double_t z = fmd1->GetInnerZ() + w / 2;
+
+ TGeoTube* fmd1Shape = new TGeoTube(rmin, rmax, w / 2);
+ TGeoVolume* fmd1Volume = new TGeoVolume(fmd1->GetName(), fmd1Shape, fAir);
+
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ TGeoMatrix* matrix = new TGeoTranslation("FMD1 transform", 0, 0, z);
+ top->AddNode(fmd1Volume, fmd1->GetId(), matrix);
+
+ return DetectorGeometry(fmd1, fmd1Volume, z, inner, 0);
+}
+
+//____________________________________________________________________
+TGeoVolume*
+AliFMDGeoSimulator::FMD2Geometry(AliFMD2* fmd2,
+ TGeoVolume* inner,
+ TGeoVolume* outer)
+{
+ // Setup the FMD2 geometry. The FMD2 has no
+ // special support as it is at the momement.
+ //
+ // See also AliFMDGeoSimulator::DetectorGeometry
+ //
+ if (!fmd2 || !inner || !outer) return 0;
+ Double_t rmin = fmd2->GetInner()->GetLowR();
+ Double_t rmax = fmd2->GetOuterHoneyHighR();
+ Double_t hcThick = fmd2->GetHoneycombThickness();
+ Double_t ow = fmd2->GetInner()->GetRingDepth();
+ Double_t iz = fmd2->GetInnerZ();
+ Double_t oz = fmd2->GetOuterZ();
+ Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
+ Double_t z = oz + w / 2;
+
+ TGeoTube* fmd2Shape = new TGeoTube(rmin, rmax, w / 2);
+ TGeoVolume* fmd2Volume = new TGeoVolume(fmd2->GetName(), fmd2Shape, fAir);
+
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ TGeoMatrix* matrix = new TGeoTranslation("FMD2 transform", 0, 0, z);
+ top->AddNode(fmd2Volume, fmd2->GetId(), matrix);
+
+ return DetectorGeometry(fmd2, fmd2Volume, z, inner, outer);
+}
+
+//____________________________________________________________________
+TGeoVolume*
+AliFMDGeoSimulator::FMD3Geometry(AliFMD3* fmd3,
+ TGeoVolume* inner,
+ TGeoVolume* outer)
+{
+ // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
+ // structure, as the support will also support the vacuum
+ // beam-pipe.
+ //
+ // See also AliFMDGeoSimulator::DetectorGeometry
+ //
+ if (!fmd3 || !inner || !outer) return 0;
+ Double_t nlen = fmd3->GetNoseLength();
+ Double_t nz = fmd3->GetNoseZ();
+ Double_t noser1 = fmd3->GetNoseLowR();
+ Double_t noser2 = fmd3->GetNoseHighR();
+ Double_t conel = fmd3->GetConeLength();
+ Double_t backl = fmd3->GetBackLength();
+ Double_t backr1 = fmd3->GetBackLowR();
+ Double_t backr2 = fmd3->GetBackHighR();
+ Double_t zdist = conel - backl - nlen;
+ Double_t tdist = backr2 - noser2;
+ Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
+ Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
+ Double_t innerZ = fmd3->GetInnerZ();
+ Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
+ - fmd3->GetHoneycombThickness());
+ Double_t outerZ = fmd3->GetOuterZ();
+ Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
+ - fmd3->GetHoneycombThickness());
+ Double_t innerr1 = fmd3->GetInner()->GetLowR();
+ // Double_t innerr2 = fmd3->GetInner()->GetHighR();
+ Double_t outerr1 = fmd3->GetOuter()->GetLowR();
+ // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
+ Double_t flanger = fmd3->GetFlangeR();
+ Double_t minZ = TMath::Min(nz - conel, outerZh);
+ Double_t z = fmd3->GetZ();
+ Double_t zi;
+
+ // FMD3 volume
+ TGeoPcon* fmd3Shape = new TGeoPcon(0, 360, 8);
+ zi = z - nz;
+ fmd3Shape->DefineSection(0, zi, noser1, noser2);
+ zi = z - (nz - nlen);
+ fmd3Shape->DefineSection(1, zi, noser1, fmd3->ConeR(z - zi)+.15);
+ zi = z - innerZ;
+ fmd3Shape->DefineSection(2, zi, innerr1, fmd3->ConeR(z - zi)+.15);
+ zi = z - innerZh;
+ fmd3Shape->DefineSection(3, zi, innerr1, fmd3->ConeR(z - zi)+.15);
+ fmd3Shape->DefineSection(4, zi, outerr1, fmd3->ConeR(z - zi)+.15);
+ zi = z - nz + zdist + nlen;
+ fmd3Shape->DefineSection(5, zi, outerr1, fmd3->ConeR(z - zi)+.15);
+ zi = z - nz + nlen + zdist;
+ fmd3Shape->DefineSection(6, zi, outerr1, flanger+1.5);
+ zi = z - minZ;
+ fmd3Shape->DefineSection(7, zi, outerr1, flanger+1.5);
+ TGeoVolume* fmd3Volume = new TGeoVolume(fmd3->GetName(), fmd3Shape, fAir);
+
+ TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
+ rot->RotateY(180);
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 transform", 0, 0, z, rot);
+ top->AddNode(fmd3Volume, fmd3->GetId(), mmatrix);
+
+ // Nose volume
+ TGeoTube* noseShape = new TGeoTube(noser1, noser2, nlen / 2);
+ TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
+ zi = z - nz + nlen / 2;
+ TGeoMatrix* nmatrix = new TGeoTranslation("FMD3 Nose translation", 0, 0, zi);
+ fmd3Volume->AddNodeOverlap(noseVolume, 0, nmatrix);
+
+ // Back
+ TGeoTube* backShape = new TGeoTube(backr1, backr2, backl / 2);
+ TGeoVolume* backVolume = new TGeoVolume(fgkBackName, backShape, fC);
+ zi = z - nz + conel - backl / 2;
+ TGeoMatrix* bmatrix = new TGeoTranslation("FMD3 Back translation", 0, 0, zi);
+ fmd3Volume->AddNode(backVolume, 0, bmatrix);
+
+ Int_t n;
+ Double_t r;
+ // The flanges
+ TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
+ fmd3->GetBeamWidth() / 2,
+ backl / 2);
+ TGeoVolume* flangeVolume = new TGeoVolume(fgkFlangeName, flangeShape, fC);
+ n = fmd3->GetNFlange();
+ r = backr2 + (flanger - backr2) / 2;
+ for (Int_t i = 0; i < n; i++) {
+ Double_t phi = 360. / n * i + 180. / n;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ TGeoRotation* rot = new TGeoRotation(Form("FMD3 Flange rotation %d", i));
+ rot->RotateZ(phi);
+ TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 flange transform %d",
+ i), x, y, zi, rot);
+ fmd3Volume->AddNodeOverlap(flangeVolume, i, matrix);
+
+ }
+
+ // The Beams
+ TGeoBBox* beamShape = new TGeoBBox(fmd3->GetBeamThickness() / 2,
+ fmd3->GetBeamWidth() / 2,
+ beaml / 2);
+ TGeoVolume* beamVolume = new TGeoVolume(fgkBeamName, beamShape, fC);
+ n = fmd3->GetNBeam();
+ r = noser2 + tdist / 2;
+ zi = z - nz + nlen + zdist / 2;
+ for (Int_t i = 0; i < n; i++) {
+ Double_t phi = 360. / n * i;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ TGeoRotation* rot = new TGeoRotation(Form("FMD3 beam rotation %d", i));
+ rot->RotateZ(phi);
+ rot->RotateY(-theta);
+ TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam transform %d", i),
+ x, y, zi, rot);
+ fmd3Volume->AddNode(beamVolume, i, matrix);
+ }
+
+
+ return DetectorGeometry(fmd3, fmd3Volume, z, inner, outer);
+}
+
+//____________________________________________________________________
+void
+AliFMDGeoSimulator::DefineGeometry()
+{
+ // Setup up the FMD geometry.
+ AliDebug(10, "Setting up volume");
+
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ TGeoVolume* inner = RingGeometry(fmd->GetInner());
+ TGeoVolume* outer = RingGeometry(fmd->GetOuter());
+
+ if (!inner || !outer) {
+ AliError("Failed to create one of the ring volumes");
+ return;
+ }
+ FMD1Geometry(fmd->GetFMD1(), inner);
+ FMD2Geometry(fmd->GetFMD2(), inner, outer);
+ FMD3Geometry(fmd->GetFMD3(), inner, outer);
+}
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDGEOSIMULATOR_H
+#define ALIFMDGEOSIMULATOR_H
+/* 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 ALIFMDSIMULATOR
+# include <AliFMDSimulator.h>
+#endif
+class TGeoVolume;
+class TGeoMedium;
+class AliFMD;
+class AliFMDRing;
+class AliFMDDetector;
+class AliFMD1;
+class AliFMD2;
+class AliFMD3;
+
+//____________________________________________________________________
+class AliFMDGeoSimulator : public AliFMDSimulator
+{
+public:
+ AliFMDGeoSimulator();
+ /** CTOR */
+ AliFMDGeoSimulator(AliFMD* fmd, Bool_t detailed=kTRUE);
+ virtual ~AliFMDGeoSimulator() {}
+ /** Initialize */
+ virtual void DefineMaterials();
+ /** Register */
+ virtual void DefineGeometry();
+protected:
+ /** Make a ring volume
+ @param r Ring geometry
+ @return Ring volume */
+ TGeoVolume* RingGeometry(AliFMDRing* r);
+ /** Make a detector volume
+ @param d Detector geometry
+ @param mother Mother volume (detector volume)
+ @param zmother Z position of mother
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return Detector volume */
+ TGeoVolume* DetectorGeometry(AliFMDDetector* d,
+ TGeoVolume* mother,
+ Double_t zmother,
+ TGeoVolume* inner,
+ TGeoVolume* outer=0);
+ /** Make FMD1 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @return FMD1 volume */
+ TGeoVolume* FMD1Geometry(AliFMD1* d, TGeoVolume* inner);
+ /** Make FMD2 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return FMD2 volume */
+ TGeoVolume* FMD2Geometry(AliFMD2* d, TGeoVolume* inner,
+ TGeoVolume* outer);
+ /** Make FMD3 volume
+ @param d Detector geometry
+ @param inner Inner ring volume
+ @param outer Outer ring volume
+ @return FMD3 volume */
+ TGeoVolume* FMD3Geometry(AliFMD3* d, TGeoVolume* inner,
+ TGeoVolume* outer);
+ TGeoMedium* fSi; //! Si Medium
+ TGeoMedium* fC; //! C Medium
+ TGeoMedium* fAl; //! Al Medium
+ TGeoMedium* fPCB; //! PCB Medium
+ TGeoMedium* fChip; //! Chip Medium
+ TGeoMedium* fAir; //! Air Medium
+ TGeoMedium* fPlastic; //! Plastic Medium
+
+ ClassDef(AliFMDGeoSimulator,1)
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// 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$ */
+
+//____________________________________________________________________
+//
+// Forward Multiplicity Detector based on Silicon wafers.
+//
+// This class is a singleton that handles the geometry parameters of
+// the FMD detectors.
+//
+// The actual code is done by various separate classes. Below is
+// diagram showing the relationship between the various FMD classes
+// that handles the geometry
+//
+// +------------+
+// +- | AliFMDRing |
+// 2 | +------------+
+// +----------------+<>--+ |
+// | AliFMDGeometry | ^
+// +----------------+<>--+ V 1..2
+// 3 | +----------------+
+// +-| AliFMDDetector |
+// +----------------+
+// ^
+// |
+// +-------------+-------------+
+// | | |
+// +---------+ +---------+ +---------+
+// | AliFMD1 | | AliFMD2 | | AliFMD3 |
+// +---------+ +---------+ +---------+
+//
+//
+// * AliFMDRing
+// This class contains all stuff needed to do with a ring. It's
+// used by the AliFMDDetector objects to instantise inner and
+// outer rings. The AliFMDRing objects are shared by the
+// AliFMDDetector objects, and owned by the AliFMDv1 object.
+//
+// * AliFMD1, AliFMD2, and AliFMD3
+// These are specialisation of AliFMDDetector, 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.
+//
+//
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliFMD1.h" // ALIFMD1_H
+#include "AliFMD2.h" // ALIFMD2_H
+#include "AliFMD3.h" // ALIFMD2_H
+#include "AliRecPoint.h" // ALIRECPOINT_H
+#include "AliLog.h" // ALIRECPOINT_H
+#include <TVector3.h> // ROOT_TVector3
+#include <TMatrix.h> // ROOT_TMatrix
+#include <TParticle.h> // ROOT_TParticle
+#include <Riostream.h>
+
+//====================================================================
+ClassImp(AliFMDGeometry)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDGeometry* AliFMDGeometry::fgInstance = 0;
+
+//____________________________________________________________________
+AliFMDGeometry*
+AliFMDGeometry::Instance()
+{
+ if (!fgInstance) fgInstance = new AliFMDGeometry;
+ return fgInstance;
+}
+
+//____________________________________________________________________
+AliFMDGeometry::AliFMDGeometry()
+ : AliGeometry("FMD", "Forward multiplicity")
+{
+ fUseFMD1 = kTRUE;
+ fUseFMD2 = kTRUE;
+ fUseFMD3 = kTRUE;
+ fInner = new AliFMDRing('I');
+ fOuter = new AliFMDRing('O');
+ fFMD1 = new AliFMD1(fInner);
+ fFMD2 = new AliFMD2(fInner, fOuter);
+ fFMD3 = new AliFMD3(fInner, fOuter);
+ fIsInitialized = kFALSE;
+}
+
+//____________________________________________________________________
+void
+AliFMDGeometry::Init()
+{
+ if (fIsInitialized) return;
+ fInner->Init();
+ fOuter->Init();
+ fFMD1->Init();
+ fFMD2->Init();
+ fFMD3->Init();
+}
+
+//____________________________________________________________________
+AliFMDDetector*
+AliFMDGeometry::GetDetector(Int_t i) const
+{
+ switch (i) {
+ case 1: return fUseFMD1 ? static_cast<AliFMDDetector*>(fFMD1) : 0;
+ case 2: return fUseFMD2 ? static_cast<AliFMDDetector*>(fFMD2) : 0;
+ case 3: return fUseFMD3 ? static_cast<AliFMDDetector*>(fFMD3) : 0;
+ }
+ return 0;
+}
+
+//____________________________________________________________________
+AliFMDRing*
+AliFMDGeometry::GetRing(Char_t i) const
+{
+ switch (i) {
+ case 'I':
+ case 'i': return fInner;
+ case 'O':
+ case 'o': return fOuter;
+ }
+ return 0;
+}
+
+//____________________________________________________________________
+void
+AliFMDGeometry::Enable(Int_t i)
+{
+ switch (i) {
+ case 1: fUseFMD1 = kTRUE; break;
+ case 2: fUseFMD2 = kTRUE; break;
+ case 3: fUseFMD3 = kTRUE; break;
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDGeometry::Disable(Int_t i)
+{
+ switch (i) {
+ case 1: fUseFMD1 = kFALSE; break;
+ case 2: fUseFMD2 = kFALSE; break;
+ case 3: fUseFMD3 = kFALSE; break;
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDGeometry::Detector2XYZ(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Double_t& x,
+ Double_t& y,
+ Double_t& z) const
+{
+ AliFMDDetector* det = GetDetector(detector);
+ if (!det) return;
+ det->Detector2XYZ(ring, sector, strip, x, y, z);
+}
+
+
+//____________________________________________________________________
+void
+AliFMDGeometry::GetGlobal(const AliRecPoint* p,
+ TVector3& pos,
+ TMatrix& /* mat */) const
+{
+ GetGlobal(p, pos);
+}
+
+//____________________________________________________________________
+void
+AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const
+{
+ Double_t x, y, z;
+ TVector3 local;
+ p->GetLocalPosition(local);
+ UShort_t detector = UShort_t(local.X());
+ UShort_t sector = UShort_t(local.Y());
+ UShort_t strip = UShort_t(local.Z());
+ Detector2XYZ(detector, 'I', sector, strip, x, y, z);
+ pos.SetXYZ(x, y, z);
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDGeometry::Impact(const TParticle* /* particle */) const
+{
+ return kFALSE;
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDGEOMETRY_H
+#define ALIFMDGEOMETRY_H
+//____________________________________________________________________
+//
+// $Id$
+//
+#ifndef ALIGEOMETRY_H
+# include <AliGeometry.h>
+#endif
+#ifndef ROOT_TObjArray
+# include <TObjArray.h>
+#endif
+class TVector3;
+class TMatrix;
+class TParticle;
+class AliRecPoint;
+class AliFMDRing;
+class AliFMDDetector;
+class AliFMD1;
+class AliFMD2;
+class AliFMD3;
+
+
+//__________________________________________________________________
+/** Singleton object of FMD geometry descriptions and parameters.
+ */
+class AliFMDGeometry : public AliGeometry
+{
+public:
+ static AliFMDGeometry* Instance();
+ virtual void Init();
+ AliFMDRing* GetInner() const { return fInner; }
+ AliFMDRing* GetOuter() const { return fOuter; }
+ AliFMD1* GetFMD1() const { return (fUseFMD1 ? fFMD1 : 0); }
+ AliFMD2* GetFMD2() const { return (fUseFMD2 ? fFMD2 : 0); }
+ AliFMD3* GetFMD3() const { return (fUseFMD3 ? fFMD3 : 0); }
+ AliFMDDetector* GetDetector(Int_t i) const;
+ AliFMDRing* GetRing(Char_t i) const;
+ void Disable(Int_t i);
+ void Enable(Int_t i);
+ Double_t GetSiDensity() const { return 2.33; }
+ void Detector2XYZ(UShort_t detector,
+ Char_t ring, UShort_t sector, UShort_t strip,
+ Double_t& x, Double_t& y, Double_t& z) const;
+
+ // AliGeometry member functions
+ virtual void GetGlobal(const AliRecPoint* p, TVector3& pos,
+ TMatrix& mat) const;
+ virtual void GetGlobal(const AliRecPoint* p, TVector3& pos) const;
+ virtual Bool_t Impact(const TParticle* particle) const;
+protected:
+ Bool_t fIsInitialized;
+ AliFMDRing* fInner; // Inner ring geometry information
+ AliFMDRing* fOuter; // Outer ring geometry information
+ AliFMD1* fFMD1; // FMD1 geometry information
+ AliFMD2* fFMD2; // FMD2 geometry information
+ AliFMD3* fFMD3; // FMD3 geometry information
+ Bool_t fUseFMD1; // Wheter to Use FMD1 or not
+ Bool_t fUseFMD2; // Wheter to Use FMD2 or not
+ Bool_t fUseFMD3; // Wheter to Use FMD3 or not
+ static AliFMDGeometry* fgInstance;
+ AliFMDGeometry();
+ virtual ~AliFMDGeometry() {}
+
+ ClassDef(AliFMDGeometry,1); //
+};
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// EOF
+//
//____________________________________________________________________
ClassImp(AliFMDHit)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
//____________________________________________________________________
ClassImp(AliFMDMap)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDMap::AliFMDMap(size_t maxDet,
//____________________________________________________________________
ClassImp(AliFMDMult)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDMult::AliFMDMult(Float_t particles, UShort_t method)
//____________________________________________________________________
ClassImp(AliFMDMultAlgorithm)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDMultAlgorithm::AliFMDMultAlgorithm(const char* name, const char* title)
//
#include "AliFMD.h" // ALIFMD_H
#include "AliFMDMultNaiive.h" // ALIFMDMULTNAIIVE_H
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
#include "AliFMDMultStrip.h" // ALIFMDMULTNAIIVE_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
#include <TClonesArray.h> // ROOT_TClonesArray
//____________________________________________________________________
ClassImp(AliFMDMultNaiive)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDMultNaiive::AliFMDMultNaiive()
{
// Initialise before a run
AliFMDMultAlgorithm::PreRun(fmd);
- fEdepMip = fmd->GetEdepMip();
- fGain = (Float_t(fmd->GetVA1MipRange()) / fmd->GetAltroChannelSize()
+ AliFMDParameters* pars = AliFMDParameters::Instance();
+ fEdepMip = pars->GetEdepMip();
+ fGain = (Float_t(pars->GetVA1MipRange()) / pars->GetAltroChannelSize()
* fEdepMip);
}
// ratio of empty to full strips.
//
#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
#include "AliFMDMultPoisson.h" // ALIFMDMULTPOISSON_H
#include "AliFMDMultRegion.h" // ALIFMDMULTREGION_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
//____________________________________________________________________
ClassImp(AliFMDMultPoisson)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDMultPoisson::AliFMDMultPoisson()
// 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;
- }
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ AliFMDDetector* sub = fmd->GetDetector(i);
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;
- }
+ AliFMDRing* r = sub->GetRing((j == 0 ? 'I' : 'O'));
+ Float_t rZ = sub->GetRingZ((j == 0 ? 'I' : 'O'));
if (!r) continue;
// Calculate low/high theta and eta
//____________________________________________________________________
ClassImp(AliFMDMultRegion)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
//____________________________________________________________________
ClassImp(AliFMDMultStrip)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#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 wafers.
+//
+// This class is a singleton that handles various parameters of
+// the FMD detectors.
+//
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliLog.h" // ALILOG_H
+#include <Riostream.h>
+
+//====================================================================
+ClassImp(AliFMDParameters)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDParameters* AliFMDParameters::fgInstance = 0;
+
+//____________________________________________________________________
+AliFMDParameters*
+AliFMDParameters::Instance()
+{
+ // Get static instance
+ if (!fgInstance) fgInstance = new AliFMDParameters;
+ return fgInstance;
+}
+
+//____________________________________________________________________
+AliFMDParameters::AliFMDParameters()
+ : fSiDeDxMip(1.664)
+{
+ // Default constructor
+ SetVA1MipRange();
+ SetAltroChannelSize();
+ SetChannelsPerAltro();
+ SetZeroSuppression();
+ SetSampleRate();
+ SetPedestal();
+ SetPedestalWidth();
+ SetPedestalFactor();
+}
+
+
+
+//__________________________________________________________________
+Float_t
+AliFMDParameters::GetEdepMip() const
+{
+ // Get energy deposited by a MIP in the silicon sensors
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ return (fSiDeDxMip
+ * fmd->GetRing('I')->GetSiThickness()
+ * fmd->GetSiDensity());
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDPARAMETERS_H
+#define ALIFMDPARAMETERS_H
+/* 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
+ */
+
+//____________________________________________________________________
+//
+// Singleton class to handle various parameters (not geometry) of the
+// FMD
+//
+#ifndef ROOT_TNamed
+# include <TNamed.h>
+#endif
+
+class AliFMDParameters : public TNamed
+{
+public:
+ static AliFMDParameters* Instance();
+
+ // Set various parameters
+ void SetVA1MipRange(UShort_t r=20) { fVA1MipRange = r; }
+ void SetAltroChannelSize(UShort_t s=1024) { fAltroChannelSize = s;}
+ void SetChannelsPerAltro(UShort_t size=128) { fChannelsPerAltro = size; }
+ void SetZeroSuppression(UShort_t s=0) { fZeroSuppression = s; }
+ void SetSampleRate(UShort_t r=1) { fSampleRate = (r>2?2:r);}
+ void SetPedestal(Float_t p=10) { fPedestal = p; }
+ void SetPedestalWidth(Float_t w=1) { fPedestalWidth = w; }
+ void SetPedestalFactor(Float_t f=3) { fPedestalFactor = f; }
+
+ // Get various parameters
+ UShort_t GetVA1MipRange() const { return fVA1MipRange; }
+ UShort_t GetAltroChannelSize() const { return fAltroChannelSize; }
+ UShort_t GetChannelsPerAltro() const { return fChannelsPerAltro; }
+ UShort_t GetZeroSuppression() const { return fZeroSuppression; }
+ UShort_t GetSampleRate() const { return fSampleRate; }
+ Float_t GetEdepMip() const;
+ Float_t GetPedestal() const { return fPedestal; }
+ Float_t GetPedestalWidth() const { return fPedestalWidth; }
+ Float_t GetPedestalFactor() const { return fPedestalFactor; }
+
+ enum {
+ kBaseDDL = 0x1000 // DDL offset for the FMD
+ };
+protected:
+ AliFMDParameters();
+ virtual ~AliFMDParameters() {}
+ static AliFMDParameters* fgInstance;
+
+ const Float_t fSiDeDxMip; // MIP dE/dx in Silicon
+ UShort_t fVA1MipRange; // # MIPs the pre-amp can do
+ UShort_t fAltroChannelSize; // Largest # to store in 1 ADC ch.
+ UShort_t fChannelsPerAltro; // Number of pre-amp. channels/adc chan.
+ UShort_t fZeroSuppression; // Threshold for zero-suppression
+ UShort_t fSampleRate; // Times the ALTRO samples pre-amp.
+ Float_t fPedestal; // Pedestal to subtract
+ Float_t fPedestalWidth; // Width of pedestal
+ Float_t fPedestalFactor; // Number of pedestal widths
+
+
+ ClassDef(AliFMDParameters,1)
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// 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 shape of the FMD modules
-//
-// Latest changes by Christian Holm Christensen
-//
-//////////////////////////////////////////////////////////////////////////////
-#include "AliFMDPolygon.h" // ALIFMDPOLYGON_H
-#include "AliLog.h" // ALILOG_H
-#include "TString.h" // ROOT_TString
-#include "TVector2.h" // ROOT_TVector2
-#include "TCanvas.h" // ROOT_TCanvas
-#include "TText.h" // ROOT_TText
-#include "TGraph.h" // ROOT_TGraph
-#include "TError.h" // ROOT_TError
-
-//____________________________________________________________________
-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
-#ifndef ALIFMDPOLYGON_H
-#define ALIFMDPOLYGON_H
-/* 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 ROOT_TVector2
-# include <TVector2.h>
-#endif
-#ifndef ROOT_TObjArray
-# include <TObjArray.h>
-#endif
-
-class AliFMDPolygon : public TObject
-{
-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;
-
-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;
-
- ClassDef(AliFMDPolygon,1) // Polygon parameters
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
-
-
// +----------------+
//
#include <AliLog.h> // ALILOG_H
-#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
#include "AliRawReader.h" // ALIRAWREADER_H
#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
#include <TArrayI.h> // ROOT_TArrayI
-// #include <TClonesArray.h> // ROOT_TClonesArray
+#include <TTree.h> // ROOT_TTree
+#include <TClonesArray.h> // ROOT_TClonesArray
//____________________________________________________________________
ClassImp(AliFMDRawReader)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
-AliFMDRawReader::AliFMDRawReader(AliFMD* fmd, AliRawReader* reader)
+AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree)
: TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
- fFMD(fmd),
- fReader(reader)
+ fTree(tree),
+ fReader(reader),
+ fSampleRate(1)
{
// Default CTOR
- SetSampleRate(fmd->GetSampleRate());
+ AliFMDParameters* pars = AliFMDParameters::Instance();
+ fSampleRate = pars->GetSampleRate();
}
return;
}
+ Int_t n = 0;
+ TClonesArray* array = new TClonesArray("AliFMDDigit");
+ fTree->Branch("FMD", &array);
+
// Use AliAltroRawStream to read the ALTRO format. No need to
// reinvent the wheel :-)
AliFMDRawStream input(fReader, fSampleRate);
// Select FMD DDL's
- fReader->Select(AliFMD::kBaseDDL >> 8);
+ fReader->Select(AliFMDParameters::kBaseDDL >> 8);
Int_t oldDDL = -1;
Int_t count = 0;
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]);
+ new ((*array)[n]) AliFMDDigit(oldDetector,
+ input.PrevRing(),
+ input.PrevSector(),
+ input.PrevStrip(),
+ counts[0], counts[1], counts[2]);
+ n++;
#if 0
AliFMDDigit* digit =
static_cast<AliFMDDigit*>(fFMD->Digits()->
oldDDL = ddl;
// Check that we're processing a FMD detector
Int_t detId = fReader->GetDetectorID();
- if (detId != (AliFMD::kBaseDDL >> 8)) {
+ if (detId != (AliFMDParameters::kBaseDDL >> 8)) {
Error("ReadAdcs", "Detector ID %d != %d",
- detId, (AliFMD::kBaseDDL >> 8));
+ detId, (AliFMDParameters::kBaseDDL >> 8));
break;
}
// Figure out what detector we're deling with
input.Strip(), input.Count()));
oldDetector = detector;
}
+ fTree->Fill();
return;
}
//____________________________________________________________________
class AliRawReader;
-class AliFMD;
+class TTree;
//____________________________________________________________________
class AliFMDRawReader : public TTask
{
public:
- AliFMDRawReader(AliFMD* fmd, AliRawReader* reader);
+ AliFMDRawReader(AliRawReader* reader, TTree* array);
virtual void Exec(Option_t* option="");
- void SetSampleRate(UShort_t sampleRate=1) { fSampleRate = sampleRate; }
protected:
- AliFMD* fFMD; //! Pointer to detector description
+ TTree* fTree; //! Pointer to tree to read into
AliRawReader* fReader; //! Pointer to raw reader
UShort_t fSampleRate; // The sample rate (if 0, inferred from data)
ClassDef(AliFMDRawReader, 0) // Read FMD raw data into a cache
//____________________________________________________________________
ClassImp(AliFMDRawStream)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate)
#include <AliLoader.h> // ALILOADER_H
#include <AliAltroBuffer.h> // ALIALTROBUFFER_H
#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
#include "AliFMDRawWriter.h" // ALIFMDRAWREADER_H
#include <TArrayI.h> // ROOT_TArrayI
//____________________________________________________________________
ClassImp(AliFMDRawWriter)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDRawWriter::AliFMDRawWriter(AliFMD* fmd)
: TTask("FMDRawWriter", "Writer of Raw ADC values from the FMD"),
fFMD(fmd)
{
- SetSampleRate();
- SetThreshold();
- SetChannelsPerAltro();
+ AliFMDParameters* pars = AliFMDParameters::Instance();
+ fSampleRate = pars->GetSampleRate();
+ fThreshold = pars->GetZeroSuppression();
+ fChannelsPerAltro = pars->GetChannelsPerAltro();
}
UShort_t sector = digit->Sector();
UShort_t strip = digit->Strip();
if (det != prevDetector) {
- AliDebug(10, Form("FMD: New DDL, was %d, now %d",
- AliFMD::kBaseDDL + prevDetector - 1,
- AliFMD::kBaseDDL + det - 1));
+ AliDebug(15, Form("FMD: New DDL, was %d, now %d",
+ AliFMDParameters::kBaseDDL + prevDetector - 1,
+ AliFMDParameters::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 "
+ AliDebug(15, Form("New altro: Write channel at %d Strip: %d "
"Sector: %d Ring: %d",
i, startStrip, prevSector, prevRing));
// TPC to FMD translations
prevDetector = det;
// Need to open a new DDL!
- Int_t ddlId = AliFMD::kBaseDDL + det - 1;
+ Int_t ddlId = AliFMDParameters::kBaseDDL + det - 1;
TString filename(Form("%s_%d.ddl", fFMD->GetName(), ddlId));
- AliDebug(10, Form("New altro buffer with DDL file %s",
+ AliDebug(15, Form("New altro buffer with DDL file %s",
filename.Data()));
- AliDebug(10, Form("New altro at %d", i));
+ AliDebug(15, 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);
|| digit->Ring() != prevRing
|| digit->Sector() != prevSector) {
// Force a new Altro channel
- AliDebug(10, Form("Flushing channel to disk because %s",
+ AliDebug(15, Form("Flushing channel to disk because %s",
(offset == fChannelsPerAltro ? "channel is full" :
(ring != prevRing ? "new ring up" :
"new sector up"))));
- AliDebug(10, Form("New Channel: Write channel at %d Strip: %d "
+ AliDebug(15, Form("New Channel: Write channel at %d Strip: %d "
"Sector: %d Ring: %d",
i, startStrip, prevSector, prevRing));
WriteChannel(altro, startStrip, prevSector, prevRing, channel);
AliFMDRawWriter(AliFMD* fmd);
virtual void Exec(Option_t* option="");
- void SetSampleRate(UShort_t sampleRate=1) { fSampleRate = sampleRate; }
- void SetChannelsPerAltro(UShort_t size=128) { fChannelsPerAltro = size; }
- void SetThreshold(UShort_t t=0) { fThreshold = t; }
protected:
virtual void WriteChannel(AliAltroBuffer* altro,
UShort_t strip, UShort_t sector, Char_t ring,
#include <AliHeader.h> // ALIHEADER_H
#include <AliRawReader.h> // ALIRAWREADER_H
#include <AliGenEventHeader.h> // ALIGENEVENTHEADER_H
-#include "AliFMD.h" // ALIFMD_H
+#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
#include "AliFMDReconstructor.h" // ALIFMDRECONSTRUCTOR_H
#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
//____________________________________________________________________
ClassImp(AliFMDReconstructor)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDReconstructor::AliFMDReconstructor()
fPedestalFactor(0)
{
// Make a new FMD reconstructor object - default CTOR.
- SetPedestal();
-
- fFMDLoader = 0;
- fRunLoader = 0;
- fFMD = 0;
+ AliFMDParameters* pars = AliFMDParameters::Instance();
+ fPedestal = pars->GetPedestal();
+ fPedestalWidth = pars->GetPedestalWidth();
+ fPedestalFactor = pars->GetPedestalFactor();
+
fAlgorithms.Add(new AliFMDMultNaiive);
fAlgorithms.Add(new AliFMDMultPoisson);
}
fPedestalFactor(0)
{
// Copy constructor
- SetPedestal(other.fPedestal, other.fPedestalWidth, other.fPedestalFactor);
+ fPedestal = other.fPedestal;
+ fPedestalWidth = other.fPedestalWidth;
+ fPedestalFactor = other.fPedestalFactor;
- fFMDLoader = other.fFMDLoader;
- fRunLoader = other.fRunLoader;
- fFMD = other.fFMD;
fAlgorithms.Delete();
TIter next(&(other.fAlgorithms));
AliFMDReconstructor::operator=(const AliFMDReconstructor& other)
{
// Assignment operator
- SetPedestal(other.fPedestal, other.fPedestalWidth, other.fPedestalFactor);
-
- fFMDLoader = other.fFMDLoader;
- fRunLoader = other.fRunLoader;
- fFMD = other.fFMD;
+ fPedestal = other.fPedestal;
+ fPedestalWidth = other.fPedestalWidth;
+ fPedestalFactor = other.fPedestalFactor;
fAlgorithms.Delete();
TIter next(&(other.fAlgorithms));
// Destructor
fAlgorithms.Delete();
}
-
-//____________________________________________________________________
-void
-AliFMDReconstructor::SetPedestal(Float_t mean, Float_t width, Float_t factor)
-{
- // Set the pedestal, and pedestal width
- fPedestal = mean;
- fPedestalWidth = width;
- fPedestalFactor = factor;
-}
//____________________________________________________________________
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.
- if (!runLoader) {
- Error("Exec","Run Loader loader is NULL - Session not opened");
+AliFMDReconstructor::Init(AliRunLoader* runLoader)
+{
+ // Initialize the reconstructor
+ AliDebug(1, Form("Init called with runloader 0x%x", runLoader));
+ fCurrentVertex = 0;
+ if (!runLoader) {
+ Warning("Init", "No run loader");
return;
}
- fRunLoader = runLoader;
- fFMDLoader = runLoader->GetLoader("FMDLoader");
- if (!fFMDLoader)
- Fatal("AliFMDReconstructor","Can not find FMD (loader) "
- "in specified event");
-
- // 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");
+ AliHeader* header = runLoader->GetHeader();
+ if (!header) {
+ Warning("Init", "No header");
return;
}
- fFMDLoader->LoadRecPoints("RECREATE");
-
- if (!fRunLoader->TreeE()) fRunLoader->LoadHeader();
-
- TIter next(&fAlgorithms);
- AliFMDMultAlgorithm* algorithm = 0;
- while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
- algorithm->PreRun(fFMD);
-
- if (rawReader) {
- Int_t event = 0;
- while (rawReader->NextEvent()) {
- ProcessEvent(event, rawReader);
- event++;
- }
- }
- else {
- Int_t nEvents= Int_t(fRunLoader->TreeE()->GetEntries());
- for(Int_t event = 0; event < nEvents; event++)
- ProcessEvent(event, 0);
+ AliGenEventHeader* eventHeader = header->GenEventHeader();
+ if (!eventHeader) {
+ Warning("Init", "no event header");
+ return;
}
-
- next.Reset();
- algorithm = 0;
- while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
- algorithm->PostRun();
-
- fFMDLoader->UnloadRecPoints();
- fFMDLoader = 0;
- fRunLoader = 0;
- fFMD = 0;
+ TArrayF vtx;
+ eventHeader->PrimaryVertex(vtx);
+ fCurrentVertex = vtx[2];
+ AliDebug(1, Form("Primary vertex Z coordinate for event # %d/%d is %f",
+ header->GetRun(), header->GetEvent(), fCurrentVertex));
}
//____________________________________________________________________
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 determined by numberOfVolume,
- // numberOfMinSector, numberOfMaxSector, numberOfMinRing,
- // numberOgMaxRing
- //
- // The reconstruction method is choosen based on the number of empty
- // strips.
- Reconstruct(runLoader, 0);
+AliFMDReconstructor::ConvertDigits(AliRawReader* reader,
+ TTree* digitsTree) const
+{
+ // Convert Raw digits to AliFMDDigit's in a tree
+ AliFMDRawReader rawRead(reader, digitsTree);
+ // rawRead.SetSampleRate(fFMD->GetSampleRate());
+ rawRead.Exec();
}
-
//____________________________________________________________________
void
-AliFMDReconstructor::ProcessEvent(Int_t event,
- AliRawReader* reader) const
+AliFMDReconstructor::Reconstruct(TTree* digitsTree,
+ TTree* clusterTree) const
{
- // Process one event read from either a clones array or from a a raw
- // data reader.
- 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);
-
- // Get the Z--coordinate from the event header
- TArrayF o(3);
- if (genHeader) genHeader->PrimaryVertex(o);
- else Warning("ProcessEvent", "No GenEventHeader Found");
- fCurrentVertex = o.At(2);
-
- // If the recontruction tree isn't loaded, load it
- if(fFMDLoader->TreeR()==0) fFMDLoader->MakeTree("R");
-
- // Load or recreate the digits
- if (fFMDLoader->LoadDigits((reader ? "UPDATE" : "READ"))) {
- if (!reader) {
- 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();
-
- }
+ // Reconstruct event from digits in tree
// Get the FMD branch holding the digits.
- TBranch *digitBranch = digitTree->GetBranch("FMD");
- TClonesArray* digits = fFMD->Digits();
+ AliDebug(1, "Reconstructing from digits in a tree");
+
+ TBranch *digitBranch = digitsTree->GetBranch("FMD");
+ TClonesArray* digits = new TClonesArray("AliFMDDigit");
if (!digitBranch) {
- if (!reader) {
- Error("Exec", "No digit branch for the FMD found");
- return;
- }
- fFMD->MakeBranchInTree(digitTree, fFMD->GetName(), &(digits), 4000, 0);
+ Error("Exec", "No digit branch for the FMD found");
+ return;
}
- if (!reader) digitBranch->SetAddress(&digits);
+ digitBranch->SetAddress(&digits);
- if (reader) {
- AliFMDRawReader rawRead(fFMD, reader);
- AliDebug(10, Form("Making raw reader with sample rate: %d",
- fFMD->GetSampleRate()));
- rawRead.SetSampleRate(fFMD->GetSampleRate());
- rawRead.Exec();
- }
- else {
- // Read the ADC values from a clones array.
- AliDebug(10, "Reading ADCs from Digits array");
- // read Digits, and reconstruct the particles
- if (!fFMDLoader->TreeD()->GetEvent(0)) return;
- }
-
TIter next(&fAlgorithms);
AliFMDMultAlgorithm* algorithm = 0;
while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
- algorithm->PreEvent(fFMDLoader->TreeR(), fCurrentVertex);
-
+ algorithm->PreEvent(clusterTree, fCurrentVertex);
+ digitBranch->GetEntry(0);
+
ProcessDigits(digits);
next.Reset();
algorithm = 0;
while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next())))
algorithm->PostEvent();
-
- if (reader) {
- digitTree->Fill();
- fFMDLoader->WriteDigits("OVERWRITE");
- }
- fFMDLoader->UnloadDigits();
- fFMDLoader->TreeR()->Reset();
- fFMDLoader->TreeR()->Fill();
- fFMDLoader->WriteRecPoints("OVERWRITE");
-}
-
-//____________________________________________________________________
-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 = 0;
- Float_t ped = fPedestal + fPedestalFactor * fPedestalWidth;
- if (digit->Count3() > 0) counts = digit->Count3();
- else if (digit->Count2() > 0) counts = digit->Count2();
- else counts = digit->Count1();
- counts = TMath::Max(Int_t(counts - ped), 0);
- return UShort_t(counts);
+ clusterTree->Fill();
}
-
+
//____________________________________________________________________
void
AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
{
Int_t nDigits = digits->GetEntries();
+ AliDebug(1, Form("Got %d digits", nDigits));
for (Int_t i = 0; i < nDigits; i++) {
AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
- AliFMDSubDetector* subDetector = 0;
- switch (digit->Detector()) {
- case 1: subDetector = fFMD->GetFMD1(); break;
- case 2: subDetector = fFMD->GetFMD2(); break;
- case 3: subDetector = fFMD->GetFMD3(); break;
- }
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ AliFMDDetector* subDetector = fmd->GetDetector(digit->Detector());
if (!subDetector) {
Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
continue;
}
- AliFMDRing* ring = 0;
- Float_t ringZ = 0;
- switch(digit->Ring()) {
- case 'i':
- case 'I':
- ring = subDetector->GetInner();
- ringZ = subDetector->GetInnerZ();
- break;
- case 'o':
- case 'O':
- ring = subDetector->GetOuter();
- ringZ = subDetector->GetOuterZ();
- break;
- }
+ AliFMDRing* ring = subDetector->GetRing(digit->Ring());
+ Float_t ringZ = subDetector->GetRingZ(digit->Ring());
if (!ring) {
Warning("ProcessDigits", "Unknown ring: FMD%d%c", digit->Detector(),
digit->Ring());
}
}
-
+//____________________________________________________________________
+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 = 0;
+ Float_t ped = fPedestal + fPedestalFactor * fPedestalWidth;
+ if (digit->Count3() > 0) counts = digit->Count3();
+ else if (digit->Count2() > 0) counts = digit->Count2();
+ else counts = digit->Count1();
+ counts = TMath::Max(Int_t(counts - ped), 0);
+ return UShort_t(counts);
+}
+
//____________________________________________________________________
void
-AliFMDReconstructor::FillESD(AliRunLoader* /*fRunLoader*/,
- AliESD* /*esd*/) const
+AliFMDReconstructor::FillESD(TTree* /* digitsTree */,
+ TTree* /* clusterTree */,
+ AliESD* /* esd*/) const
{
// nothing to be done
#endif
//____________________________________________________________________
+class TTree;
class TClonesArray;
-class AliFMD;
-class AliLoader;
-class AliRunLoader;
class AliFMDDigit;
class AliRawReader;
+class AliRunLoader;
//____________________________________________________________________
class AliFMDReconstructor: public AliReconstructor
virtual ~AliFMDReconstructor();
AliFMDReconstructor& operator=(const AliFMDReconstructor& other);
- void SetPedestal(Float_t mean=10, Float_t width=1, Float_t f=3);
+ virtual void Init(AliRunLoader* runLoader);
+ virtual Bool_t HasDigitConversion() const { return kTRUE; }
+ virtual void ConvertDigits(AliRawReader* reader, TTree* digitsTree) const;
+ virtual Bool_t HasLocalReconstruction() const { return kTRUE; }
+ virtual void Reconstruct(TTree* digitsTree, TTree* clusterTree) const;
+ virtual void FillESD(TTree* digitsTree, TTree* clusterTree,
+ AliESD* esd) const;
- 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) const;
virtual void ProcessDigits(TClonesArray* digits) const;
virtual UShort_t SubtractPedestal(AliFMDDigit* digit) const;
-
- mutable AliRunLoader* fRunLoader; //! Run loader
- mutable AliLoader* fFMDLoader; //! FMD specific loader
- mutable AliFMD* fFMD; //! Pointer to FMD manager
TObjArray fAlgorithms; // Array of algorithms
Float_t fPedestal; // Pedestal to subtract
//__________________________________________________________________
//
// Utility class to help implement collection of FMD modules into
-// rings. This is used by AliFMDSubDetector and AliFMD.
+// rings. This is used by AliFMDDetector and AliFMDGeometry.
//
-// The AliFMD object owns the AliFMDRing objects, and the
-// AliFMDSubDetector objects reference these. That is, the AliFMDRing
-// objects are share amoung the AliFMDSubDetector objects.
+// The AliFMDGeometry object owns the AliFMDRing objects, and the
+// AliFMDDetector objects reference these. That is, the AliFMDRing
+// objects are share amoung the AliFMDDetector objects.
//
// Latest changes by Christian Holm Christensen
//
-#include <math.h> // fmod
#include <AliLog.h> // ALILOG_H
#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD.h" // ALIFMD_H
#include <TMath.h> // ROOT_TMath
-#include <TH2.h> // ROOT_TH2
-#include <TVirtualMC.h> // ROOT_TVirtualMC
#include <TVector2.h> // ROOT_TVector2
-#include <TBrowser.h> // ROOT_TBrowser
-#include <TString.h> // ROOT_TString
-#include <TArc.h> // ROOT_TArc
-#include <TObjArray.h> // ROOT_TObjArray
-#include <TXTRU.h> // ROOT_TXTRU
-#include <TNode.h> // ROOT_TNode
-#include <TRotMatrix.h> // ROOT_TRotMatrix
-#include <TList.h> // ROOT_TList
-const Char_t* AliFMDRing::fgkRingFormat = "F%cRG";
-const Char_t* AliFMDRing::fgkVirtualFormat = "F%cV%c";
-const Char_t* AliFMDRing::fgkActiveFormat = "F%cAC";
-const Char_t* AliFMDRing::fgkSectorFormat = "F%cAP";
-const Char_t* AliFMDRing::fgkStripFormat = "F%cAR";
-const Char_t* AliFMDRing::fgkPrintboardFormat = "F%cP%c";
-
-
-//____________________________________________________________________
-ClassImp(AliFMDRing)
-
-//____________________________________________________________________
-AliFMDRing::AliFMDRing(Char_t id, Bool_t detailed)
- : fId(id),
- fDetailed(detailed),
- fActiveId(0),
- fPrintboardBottomId(0),
- fPrintboardTopId(0),
- fRingId(0),
- fSectionId(0),
- fStripId(0),
- fVirtualBackId(0),
- fVirtualFrontId(0),
- fBondingWidth(0),
- fWaferRadius(0),
- fSiThickness(0),
- fLowR(0),
- fHighR(0),
- fTheta(0),
- fNStrips(0),
- fRingDepth(0),
- fLegRadius(0),
- fLegLength(0),
- fLegOffset(0),
- fModuleSpacing(0),
- fPrintboardThickness(0),
- fShape(0),
- fRotMatricies(0)
-{
- // Construct a alifmdring.
- //
- // id Id of the ring (either 'i' or 'o').
- // detailed Whether the strips are made or not.
- //
-}
-
-//____________________________________________________________________
-AliFMDRing::AliFMDRing(const AliFMDRing& other)
- : TObject(other),
- fId(other.fId),
- fDetailed(other.fDetailed),
- fActiveId(other.fActiveId),
- fPrintboardBottomId(other.fPrintboardBottomId),
- fPrintboardTopId(other.fPrintboardTopId),
- fRingId(other.fRingId),
- fSectionId(other.fSectionId),
- fStripId(other.fStripId),
- fVirtualBackId(other.fVirtualBackId),
- fVirtualFrontId(other.fVirtualFrontId),
- fBondingWidth(other.fBondingWidth),
- fWaferRadius(other.fWaferRadius),
- fSiThickness(other.fSiThickness),
- fLowR(other.fLowR),
- fHighR(other.fHighR),
- fTheta(other.fTheta),
- fNStrips(other.fNStrips),
- fRingDepth(other.fRingDepth),
- fLegRadius(other.fLegRadius),
- fLegLength(other.fLegLength),
- fLegOffset(other.fLegOffset),
- fModuleSpacing(other.fModuleSpacing),
- fPrintboardThickness(other.fPrintboardThickness),
- fRotations(other.fRotations),
- fShape(other.fShape),
- fRotMatricies(other.fRotMatricies)
-{
- // Copy constructor of a AliFMDRing.
-}
-
-//____________________________________________________________________
-AliFMDRing&
-AliFMDRing::operator=(const AliFMDRing& other)
-{
- // Assignment operator
- //
- fId = other.fId;
- fDetailed = other.fDetailed;
- fActiveId = other.fActiveId;
- fPrintboardBottomId = other.fPrintboardBottomId;
- fPrintboardTopId = other.fPrintboardTopId;
- fRingId = other.fRingId;
- fSectionId = other.fSectionId;
- fStripId = other.fStripId;
- fVirtualBackId = other.fVirtualBackId;
- fVirtualFrontId = other.fVirtualFrontId;
- fBondingWidth = other.fBondingWidth;
- fWaferRadius = other.fWaferRadius;
- fSiThickness = other.fSiThickness;
- fLowR = other.fLowR;
- fHighR = other.fHighR;
- fTheta = other.fTheta;
- fNStrips = other.fNStrips;
- fRingDepth = other.fRingDepth;
- fLegRadius = other.fLegRadius;
- fLegLength = other.fLegLength;
- fLegOffset = other.fLegOffset;
- fModuleSpacing = other.fModuleSpacing;
- fPrintboardThickness = other.fPrintboardThickness;
- fRotations = other.fRotations;
- if (other.fShape) {
- if (other.fShape->IsA() == TXTRU::Class())
- ((TXTRU*)other.fShape)->Copy(*fShape);
- else
- fShape = 0;
- }
- if (other.fRotMatricies) {
- Int_t n = other.fRotMatricies->GetEntries();
- if (!fRotMatricies) fRotMatricies = new TObjArray(n);
- else fRotMatricies->Expand(n);
- TIter next(other.fRotMatricies);
- TObject* o = 0;
- while ((o = next())) fRotMatricies->Add(o);
- }
- return *this;
-}
-
-
-
-//____________________________________________________________________
-void
-AliFMDRing::Init()
-{
- // Initialize the ring object.
- // DebugGuard guard("AliFMDRing::Init");
- AliDebug(30, Form("\tInitializing ring %c", fId));
- fPolygon.Clear();
- SetupCoordinates();
-}
-
-//____________________________________________________________________
-AliFMDRing::~AliFMDRing()
-{
- // Destructor - deletes shape and rotation matricies
- AliDebug(30, Form("\tDestructing ring %c", fId));
- if (fShape) delete fShape;
- if (fRotMatricies) delete fRotMatricies;
-}
-
-
-//____________________________________________________________________
-void
-AliFMDRing::Browse(TBrowser* /* b */)
-{
- // DebugGuard guard("AliFMDRing::Browse");
- AliDebug(30, Form("\tBrowsing ring %c", fId));
-}
-
-
-//____________________________________________________________________
-void
-AliFMDRing::SetupCoordinates()
-{
- // Calculates the parameters of the polygon shape.
- //
- //
-
- // Get out immediately if we have already done all this
- if (fPolygon.GetNVerticies() > 1) return;
- AliDebug(10, Form("\tSetting up the coordinates for ring %c", fId));
-
- double tanTheta = TMath::Tan(fTheta * TMath::Pi() / 180.);
- double tanTheta2 = TMath::Power(tanTheta,2);
- double r2 = TMath::Power(fWaferRadius,2);
- double yA = tanTheta * fLowR;
- double lr2 = TMath::Power(fLowR, 2);
- double hr2 = TMath::Power(fHighR,2);
- double xD = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
- double xD2 = TMath::Power(xD,2);
- //double xD_2 = fLowR - TMath::Sqrt(r2 - tanTheta2 * lr2);
- double yB = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
- double xC = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
- + r2 * tanTheta2))
- / (1 + tanTheta2));
- double yC = tanTheta * xC;
-
- fPolygon.AddVertex(fLowR, -yA);
- fPolygon.AddVertex(xC, -yC);
- fPolygon.AddVertex(fHighR, -yB);
- fPolygon.AddVertex(fHighR, yB);
- fPolygon.AddVertex(xC, yC);
- fPolygon.AddVertex(fLowR, yA);
-}
+//====================================================================
+ClassImp(AliFMDRing);
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
-bool
-AliFMDRing::IsWithin(size_t moduleNo, double x, double y) const
+AliFMDRing::AliFMDRing(Char_t id)
+ : TNamed(Form("FMD%c", id), "Forward multiplicity ring"),
+ fId(id),
+ fVerticies(0)
{
- // Checks if a point (x,y) is inside the module with number moduleNo
- //
- // DebugGuard guard("AliFMDRing::IsWithin");
- AliDebug(20, Form("\tChecking wether the hit at (%lf,%lf) in module %d "
- "is within this ring (%c)", x, y, moduleNo, fId));
- 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);
+ SetBondingWidth();
+ SetWaferRadius();
+ SetSiThickness();
+ SetLegRadius();
+ SetLegLength();
+ SetLegOffset();
+ SetModuleSpacing();
+ SetPrintboardThickness();
- ret = fPolygon.Contains(xr,yr);
+ if (fId == 'I' || fId == 'i') {
+ SetLowR(4.3);
+ SetHighR(17.2);
+ SetTheta(36/2);
+ SetNStrips(512);
+ }
+ else if (fId == 'O' || fId == 'o') {
+ SetLowR(15.6);
+ SetHighR(28.0);
+ SetTheta(18/2);
+ SetNStrips(256);
}
- return ret;
}
-
-
-
//____________________________________________________________________
void
-AliFMDRing::Draw(Option_t* option) const
+AliFMDRing::Init()
{
- // 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(20, Form("\tDrawing ring %c", fId));
- // 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);
+ Double_t tanTheta = TMath::Tan(fTheta * TMath::Pi() / 180.);
+ Double_t tanTheta2 = TMath::Power(tanTheta,2);
+ Double_t r2 = TMath::Power(fWaferRadius,2);
+ Double_t yA = tanTheta * fLowR;
+ Double_t lr2 = TMath::Power(fLowR, 2);
+ Double_t hr2 = TMath::Power(fHighR,2);
+ Double_t xD = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
+ Double_t xD2 = TMath::Power(xD,2);
+ Double_t yB = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
+ Double_t xC = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
+ + r2 * tanTheta2))
+ / (1 + tanTheta2));
+ Double_t yC = tanTheta * xC;
- 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();
- }
+ fVerticies.Expand(6);
+ fVerticies.AddAt(new TVector2(fLowR, -yA), 0);
+ fVerticies.AddAt(new TVector2(xC, -yC), 1);
+ fVerticies.AddAt(new TVector2(fHighR, -yB), 2);
+ fVerticies.AddAt(new TVector2(fHighR, yB), 3);
+ fVerticies.AddAt(new TVector2(xC, yC), 4);
+ fVerticies.AddAt(new TVector2(fLowR, yA), 5);
+
+ fRingDepth = (fSiThickness + fPrintboardThickness
+ + fLegLength + fModuleSpacing);
}
//____________________________________________________________________
-void
-AliFMDRing::SetupGeometry(Int_t vacuumId, Int_t siId, Int_t pcbId,
- Int_t pbRotId, Int_t idRotId)
+TVector2*
+AliFMDRing::GetVertex(Int_t i) const
{
- // 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
- //
- // FRGx // Ring volume
- // FVFx // Container of hybrid + legs
- // FACx // Active volume (si sensor approx)
- // FSEx // Section division
- // FSTx // Strip division
- // FPTx // Print board (bottom)
- // FPBx // Print board (top)
- // FLL // Support leg (long version)
- // FVBx // Container of hybrid + legs
- // FACx // Active volume (si sensor approx)
- // FSEx // Section division
- // FSTx // Strip division
- // FPTx // Print board (bottom)
- // FPBx // Print board (top)
- // FSL // 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, Form("\tSetting up the geometry for ring %c", fId));
-
- 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] = rmax;
- pars[2] = fRingDepth / 2;
- name = Form(fgkRingFormat, 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(fgkVirtualFormat, fId, 'F');
- fVirtualFrontId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5);
-
- // Virtual volume for modules with long legs
- pars[2] = (fRingDepth - fModuleSpacing) / 2;
- name = Form(fgkVirtualFormat, fId, 'B');
- fVirtualBackId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5);
-
- // Virtual mother volume for silicon
- pars[2] = fSiThickness/2;
- name2 = name;
- name = Form(fgkActiveFormat, fId);
- fActiveId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId , pars, 5);
-
- if (fDetailed) {
- // Virtual sector volumes
- name2 = name;
- name = Form(fgkSectorFormat, fId);
- gMC->Gsdvn2(name.Data(), name2.Data(), 2, 2, -fTheta, vacuumId);
- fSectionId = gMC->VolId(name.Data());
-
- // Active strip volumes
- name2 = name;
- name = Form(fgkStripFormat, 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(fgkPrintboardFormat, fId, 'T');
- 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(fgkPrintboardFormat, fId, 'B');
- 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(fgkRingFormat, 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(fgkVirtualFormat, fId, (isFront ? 'F' : 'B'));
- dz = (w - fRingDepth) / 2;
- gMC->Gspos(name.Data(), id, name2.Data(), 0., 0., dz,fRotations[i],
- "ONLY");
-
- // 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(fgkActiveFormat, fId);
- dz = (w - fSiThickness) / 2;
- gMC->Gspos(name.Data(), id, name2.Data(),0.,0.,dz,idRotId, "ONLY");
-
- // Place print board. This is put immediately behind the silicon
- name = Form(fgkPrintboardFormat, fId, 'T');
- dz = w / 2 - fSiThickness - fPrintboardThickness / 2;
- gMC->Gspos(name.Data(), id, name2.Data(),
- fLowR + pbBotL + pbTopL / 2, 0, dz, pbRotId, "ONLY");
- name = Form(fgkPrintboardFormat, fId, 'B');
- 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 ? AliFMD::fgkLongLegName : AliFMD::fgkShortLegName);
- gMC->Gspos(name.Data(), id*10 + 1, name2.Data(),
- aCorner.X() + fLegOffset + fLegRadius, 0., dz, idRotId, "ONLY");
- Double_t y = cCorner.Y() - yoffset - fLegOffset - fLegRadius;
- gMC->Gspos(name.Data(),id*10+2,name2.Data(),cCorner.X(),y,dz,
- idRotId,"ONLY");
- gMC->Gspos(name.Data(),id*10+3,name2.Data(),cCorner.X(),-y,dz,
- idRotId,"ONLY");
- }
-}
-//____________________________________________________________________
-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");
- TString name;
- Double_t offsetZ = (fSiThickness
- + fPrintboardThickness
- + fLegLength + fModuleSpacing) / 2;
- name = Form(fgkRingFormat, fId);
- AliDebug(10, Form("\tPlacing ring %s in %s at z=%lf-%lf=%lf (base ID: %d)",
- name.Data(), mother, z, offsetZ, z-offsetZ, baseId));
- gMC->Gspos(name.Data(), baseId, mother, 0., 0., z - offsetZ, idRotId,
- "ONLY");
+ return static_cast<TVector2*>(fVerticies.At(i));
}
//____________________________________________________________________
-void
-AliFMDRing::SimpleGeometry(TList* nodes,
- TNode* mother,
- Int_t colour,
- Double_t z,
- Int_t n)
+void
+AliFMDRing::Detector2XYZ(UShort_t sector,
+ UShort_t strip,
+ Double_t& x,
+ Double_t& y,
+ Double_t& z) const
{
- // 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");
- SetupCoordinates();
-
- AliDebug(10, Form("\tCreating simple geometry for "
- "ring %c at z=%lf cm in %s",
- fId, z, mother->GetName()));
- // If the shape hasn't been defined yet, we define it here.
- if (!fShape) {
-
- TString name(Form(fgkActiveFormat, 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);
- }
+ if (sector >= GetNSectors()) {
+ Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c",
+ sector, GetNSectors(), fId);
+ return;
}
-
- 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("FAC%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);
+ if (strip >= GetNStrips()) {
+ Error("Detector2XYZ", "Invalid strip number %d (>=%d)",
+ strip, GetNStrips(), fId);
+ return;
}
-}
-
-
-
-//____________________________________________________________________
-void
-AliFMDRing::Gsatt()
-{
- // Set drawing attributes for the RING
- //
- // DebugGuard guard("AliFMDRing::Gsatt");
- AliDebug(10, Form("\tSetting drawing attributes for Ring %c", fId));
- TString name;
- name = Form(fgkRingFormat,fId);
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkVirtualFormat, fId, 'F');
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkVirtualFormat, fId, 'B');
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkActiveFormat,fId);
- gMC->Gsatt(name.Data(), "SEEN", 1);
-
- name = Form(fgkSectorFormat,fId);
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkStripFormat,fId);
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkPrintboardFormat, fId, 'T');
- gMC->Gsatt(name.Data(), "SEEN", 1);
-
- name = Form(fgkPrintboardFormat, fId, 'B');
- gMC->Gsatt(name.Data(), "SEEN", 1);
+ Double_t phi = Float_t(sector + .5) / GetNSectors() * 2 * TMath::Pi();
+ Double_t r = Float_t(strip + .5) / GetNStrips() * (fHighR - fLowR) + fLowR;
+ x = r * TMath::Cos(phi);
+ y = r * TMath::Sin(phi);
+ if (((sector / 2) % 2) == 1)
+ z += TMath::Sign(fModuleSpacing, z);
}
//
// This class is responsible to make the (common) rings of the three
// sub-detectors.
//
-#ifndef ALIFMDPOLYGON_H
-# include "AliFMDPolygon.h"
+#ifndef ROOT_TNamed
+# include <TNamed.h>
#endif
-#ifndef ROOT_TArrayI
-# include <TArrayI.h>
+#ifndef ROOT_TObjArray
+# include <TObjArray.h>
#endif
class TBrowser;
-class TNode;
-class TObjArray;
-class TShape;
-class TList;
+class TVector2;
-
-//__________________________________________________________________
-class AliFMDRing : public TObject
+/** Geometry description and parameters of a ring in the FMD
+ detector.
+
+ As there are only 2 kinds of rings @e Inner (@c 'I') and @e
+ Outer (@c 'O') the two objects of this class is owned by the
+ Geometry::FMD singleton object. The 3 Geometry::FMDDetector
+ objects shares these two instances as needed.
+*/
+class AliFMDRing : public TNamed
{
public:
- AliFMDRing(Char_t id='\0', Bool_t detailed=kTRUE);
- AliFMDRing(const AliFMDRing& other);
- AliFMDRing& operator=(const AliFMDRing& other);
- 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; }
+ AliFMDRing(Char_t fId);
+ virtual ~AliFMDRing() {}
+ /** Initialize the ring geometry */
+ virtual void Init();
+
+ /** @param x Value of The Id of this ring type */
+ void SetId(Char_t x) { fId = x; }
+ /** @param x Value of With of bonding pad on sensor */
+ void SetBondingWidth(Double_t x=.5) { fBondingWidth = x; }
+ /** @param x Value of Size of wafer the sensor was made from */
+ void SetWaferRadius(Double_t x=13.4/2) { fWaferRadius = x; }
+ /** @param x Value of Thickness of sensor */
+ void SetSiThickness(Double_t x=.03) { fSiThickness = x; }
+ /** @param x Value of Lower radius of ring */
+ void SetLowR(Double_t x) { fLowR = x; }
+ /** @param x Value of Upper radius of ring */
+ void SetHighR(Double_t x) { fHighR = x; }
+ /** @param x Value of Opening angle of the silicon wafers */
+ void SetTheta(Double_t x) { fTheta = x; }
+ /** @param x Value of Number of strips */
+ void SetNStrips(Int_t x) { fNStrips = x; }
+ /** @param x Value of How far the ring extends beyond the z value given. */
+ void SetRingDepth(Double_t x) { fRingDepth = x; }
+ /** @param x Value of Radius of support legs */
+ void SetLegRadius(Double_t x=.5) { fLegRadius = x; }
+ /** @param x Value of Radius of support legs */
+ void SetLegLength(Double_t x=1) { fLegLength = x; }
+ /** @param x Value of Radius of support legs */
+ void SetLegOffset(Double_t x=2) { fLegOffset = x; }
+ /** @param x Value of Staggering offset */
+ void SetModuleSpacing(Double_t x=1) { fModuleSpacing = x; }
+ /** @param x Value of Thickness of print board */
+ void SetPrintboardThickness(Double_t x=.1) { fPrintboardThickness = x; }
- 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; }
+ /** @return The Id of this ring type */
+ Char_t GetId() const { return fId; }
+ /** @return With of bonding pad on sensor */
+ Double_t GetBondingWidth() const { return fBondingWidth; }
+ /** @return Size of wafer the sensor was made from */
+ Double_t GetWaferRadius() const { return fWaferRadius; }
+ /** @return Thickness of sensor */
+ Double_t GetSiThickness() const { return fSiThickness; }
+ /** @return Lower radius of ring */
+ Double_t GetLowR() const { return fLowR; }
+ /** @return Upper radius of ring */
+ Double_t GetHighR() const { return fHighR; }
+ /** @return Opening angle of the sector (half that of silicon wafers) */
+ Double_t GetTheta() const { return fTheta; }
+ /** @return Number of strips */
+ Int_t GetNStrips() const { return fNStrips; }
+ /** @return Number of sectors */
+ Int_t GetNSectors() const { return Int_t(360. / fTheta); }
+ /** @return Number of modules (2 sectors per module) */
+ Int_t GetNModules() const { return GetNSectors() / 2; }
+ /** @return How far the ring extends beyond the z value given. */
+ Double_t GetRingDepth() const { return fRingDepth; }
+ /** @return Radius of support legs */
+ Double_t GetLegRadius() const { return fLegRadius; }
+ /** @return Radius of support legs */
+ Double_t GetLegLength() const { return fLegLength; }
+ /** @return Radius of support legs */
+ Double_t GetLegOffset() const { return fLegOffset; }
+ /** @return Staggering offset */
+ Double_t GetModuleSpacing() const { return fModuleSpacing; }
+ /** @return Thickness of print board */
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; }
-
-protected:
- Char_t fId; // ID
- Bool_t fDetailed; // True if a detailed geometry is made
- 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
-
- static const Char_t* fgkRingFormat; // Format for Ring names
- static const Char_t* fgkVirtualFormat; // Format for Virtual names
- static const Char_t* fgkActiveFormat; // Format for Active names
- static const Char_t* fgkSectorFormat; // Format for Sector names
- static const Char_t* fgkStripFormat; // Format for Strip names
- static const Char_t* fgkPrintboardFormat; // Format for Printboard names
+ /** @return List of verticies */
+ const TObjArray& GetVerticies() const { return fVerticies; }
+ /** @return Number of verticies */
+ Int_t GetNVerticies() const { return fVerticies.GetEntries(); }
+ /** @param i Vertex number
+ @return the ith vertex */
+ TVector2* GetVertex(Int_t i) const;
+
+ void Detector2XYZ(UShort_t sector, UShort_t strip,
+ Double_t& x, Double_t& y, Double_t& z) const;
+
+private:
+ Char_t fId; // The Id of this ring type
+ Double_t fBondingWidth; // With of bonding pad on sensor
+ Double_t fWaferRadius; // Size of wafer 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 z
+ 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
+ TObjArray fVerticies; // List of verticies
- ClassDef(AliFMDRing, 1) // FMD Ring volume parameters
+ ClassDef(AliFMDRing, 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 wafers. This class
+// contains the base procedures for the Forward Multiplicity detector
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
+//
+// This is the base class for all FMD manager classes.
+//
+// The actual code is done by various separate classes. Below is
+// diagram showing the relationship between the various FMD classes
+// that handles the simulation
+//
+// +--------+ 1 +-----------------+
+// | AliFMD |<>-----| AliFMDSimulator |
+// +--------+ +-----------------+
+// ^
+// |
+// +-------------+-------------+
+// | |
+// +--------------------+ +-------------------+
+// | AliFMDGeoSimulator | | AliFMDG3Simulator |
+// +--------------------+ +---------+---------+
+//
+//
+// * AliFMD
+// This defines the interface for the various parts of AliROOT that
+// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
+// AliFMDReconstructor, and so on.
+//
+// * AliFMDSimulator
+// This is the base class for the FMD simulation tasks. The
+// simulator tasks are responsible to implment the geoemtry, and
+// process hits.
+//
+// * AliFMDGeoSimulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TGeo classes directly only. This defines the active
+// volume as an ONLY XTRU shape with a divided MANY TUBS shape
+// inside to implement the particular shape of the silicon
+// sensors.
+//
+// * AliFMDG3Simulator
+// This is a concrete implementation of the AliFMDSimulator that
+// uses the TVirtualMC interface with GEANT 3.21-like messages.
+// This implements the active volume as a divided TUBS shape. Hits
+// in the corners should be cut away at run time (but currently
+// isn't).
+//
+#include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
+#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliFMD1.h" // ALIFMD1_H
+#include "AliFMD2.h" // ALIFMD2_H
+#include "AliFMD3.h" // ALIFMD3_H
+#include "AliFMD.h" // ALIFMD_H
+#include <AliRun.h> // ALIRUN_H
+#include <AliMC.h> // ALIMC_H
+#include <AliMagF.h> // ALIMAGF_H
+#include <AliLog.h> // ALILOG_H
+#include <TGeoVolume.h> // ROOT_TGeoVolume
+#include <TGeoTube.h> // ROOT_TGeoTube
+#include <TGeoPcon.h> // ROOT_TGeoPcon
+#include <TGeoMaterial.h> // ROOT_TGeoMaterial
+#include <TGeoMedium.h> // ROOT_TGeoMedium
+#include <TGeoXtru.h> // ROOT_TGeoXtru
+#include <TGeoPolygon.h> // ROOT_TGeoPolygon
+#include <TGeoTube.h> // ROOT_TGeoTube
+#include <TGeoManager.h> // ROOT_TGeoManager
+#include <TTree.h> // ROOT_TTree
+#include <TParticle.h> // ROOT_TParticle
+#include <TLorentzVector.h> // ROOT_TLorentzVector
+#include <TVector2.h> // ROOT_TVector2
+#include <TVector3.h> // ROOT_TVector3
+#include <TVirtualMC.h> // ROOT_TVirtualMC
+#include <TArrayD.h> // ROOT_TArrayD
+
+//====================================================================
+ClassImp(AliFMDSimulator)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+const Char_t* AliFMDSimulator::fgkActiveName = "F%cAC";
+const Char_t* AliFMDSimulator::fgkSectorName = "F%cSE";
+const Char_t* AliFMDSimulator::fgkStripName = "F%cST";
+const Char_t* AliFMDSimulator::fgkModuleName = "F%cMO";
+const Char_t* AliFMDSimulator::fgkPCBName = "F%cP%c";
+const Char_t* AliFMDSimulator::fgkLongLegName = "F%cLL";
+const Char_t* AliFMDSimulator::fgkShortLegName = "F%cSL";
+const Char_t* AliFMDSimulator::fgkFrontVName = "F%cFV";
+const Char_t* AliFMDSimulator::fgkBackVName = "F%cBV";
+const Char_t* AliFMDSimulator::fgkRingName = "FMD%c";
+const Char_t* AliFMDSimulator::fgkTopHCName = "F%d%cI";
+const Char_t* AliFMDSimulator::fgkBotHCName = "F%d%cJ";
+const Char_t* AliFMDSimulator::fgkTopIHCName = "F%d%cK";
+const Char_t* AliFMDSimulator::fgkBotIHCName = "F%d%cL";
+const Char_t* AliFMDSimulator::fgkNoseName = "F3SN";
+const Char_t* AliFMDSimulator::fgkBackName = "F3SB";
+const Char_t* AliFMDSimulator::fgkBeamName = "F3SL";
+const Char_t* AliFMDSimulator::fgkFlangeName = "F3SF";
+
+//____________________________________________________________________
+AliFMDSimulator::AliFMDSimulator()
+ : fFMD(0),
+ fDetailed(kFALSE),
+ fInnerId(-1),
+ fOuterId(-1)
+{
+ // Default constructor
+}
+
+//____________________________________________________________________
+AliFMDSimulator::AliFMDSimulator(AliFMD* fmd, Bool_t detailed)
+ : TTask("FMDsimulator", "Forward Multiplicity Detector Simulator"),
+ fFMD(fmd),
+ fDetailed(detailed),
+ fInnerId(-1),
+ fOuterId(-1)
+{
+ // Normal constructor
+ //
+ // Parameters:
+ //
+ // fmd Pointer to AliFMD object
+ // detailed Whether to make a detailed simulation or not
+ //
+}
+
+
+//____________________________________________________________________
+void
+AliFMDSimulator::DefineMaterials()
+{
+ // Define the materials and tracking mediums needed by the FMD
+ // simulation. These mediums are made by sending the messages
+ // AliMaterial, AliMixture, and AliMedium to the passed AliModule
+ // object module. The defined mediums are
+ //
+ // FMD Si$ Silicon (active medium in sensors)
+ // FMD C$ Carbon fibre (support cone for FMD3 and vacuum pipe)
+ // FMD Al$ Aluminium (honeycomb support plates)
+ // FMD PCB$ Printed Circuit Board (FEE board with VA1_ALICE)
+ // FMD Chip$ Electronics chips (currently not used)
+ // FMD Air$ Air (Air in the FMD)
+ // FMD Plastic$ Plastic (Support legs for the hybrid cards)
+ //
+ // Pointers to TGeoMedium objects are retrived from the TGeoManager
+ // singleton. These pointers are later used when setting up the
+ // geometry
+ AliDebug(10, "\tCreating materials");
+ // Get pointer to geometry singleton object.
+ AliFMDGeometry* geometry = AliFMDGeometry::Instance();
+ geometry->Init();
+
+ 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 = geometry->GetSiDensity();
+ radiationLength = 9.36;
+ maxBending = 1;
+ maxStepSize = .001;
+ precision = .001;
+ minStepSize = .001;
+ id = kSiId;
+ fFMD->AliMaterial(id, "FMD Si$",
+ a, z, density, radiationLength, absorbtionLength);
+ fFMD->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;
+ fFMD->AliMaterial(id, "FMD Carbon$",
+ a, z, density, radiationLength, absorbtionLength);
+ fFMD->AliMedium(kCarbonId, "FMD Carbon$",
+ id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+
+ // Aluminum
+ a = 26.981539;
+ z = 13.;
+ density = 2.7;
+ radiationLength = 8.9;
+ id = kAlId;
+ fFMD->AliMaterial(id, "FMD Aluminum$",
+ a, z, density, radiationLength, absorbtionLength);
+ fFMD->AliMedium(kAlId, "FMD Aluminum$",
+ 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;
+ fFMD->AliMixture(id, "FMD Si Chip$", as, zs, density, 6, ws);
+ fFMD->AliMedium(kSiChipId, "FMD Si Chip$",
+ id, 0, fieldType, maxField, maxBending,
+ maxStepSize, maxEnergyLoss, precision, minStepSize);
+ }
+
+#if 0
+ // 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 = KaptionId;
+ fFMD->AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
+ fFMD->AliMedium(kAlId, "FMD Kaption$",
+ id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+#endif
+
+ // 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;
+ fFMD->AliMixture(id, "FMD Air$", as, zs, density, 4, ws);
+ fFMD->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;
+ fFMD->AliMixture(id, "FMD PCB$", as, zs, density, 14, ws);
+ fFMD->AliMedium(kPcbId, "FMD PCB$",
+ id,0,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;
+ fFMD->AliMixture(id, "FMD Plastic$", as, zs, density, -2, ws);
+ fFMD->AliMedium(kPlasticId, "FMD Plastic$",
+ id,0,fieldType,maxField,maxBending,
+ maxStepSize,maxEnergyLoss,precision,minStepSize);
+ }
+}
+
+//____________________________________________________________________
+void
+AliFMDSimulator::Exec(Option_t* /* option */)
+{
+ // Member function that is executed each time a hit is made in the
+ // FMD. None-charged particles are ignored. Dead tracks are
+ // ignored.
+ //
+ // 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
+ //
+ TVirtualMC* mc = TVirtualMC::GetMC();
+
+ if (!mc->IsTrackAlive()) return;
+ if (TMath::Abs(mc->TrackCharge()) <= 0) return;
+
+ Int_t copy;
+ Int_t vol = mc->CurrentVolID(copy);
+ if (vol != fInnerId && vol != fOuterId) {
+ AliDebug(15, Form("Not an FMD volume %d '%s' (%d or %d)",
+ vol, mc->CurrentVolName(), fInnerId, fOuterId));
+ return;
+ }
+
+ // Check that the track is actually within the active area
+ Bool_t entering = mc->IsTrackEntering();
+ Bool_t inside = mc->IsTrackInside();
+ Bool_t out = (mc->IsTrackExiting()|| mc->IsTrackDisappeared()||
+ mc->IsTrackStop());
+
+ // Reset the energy deposition for this track, and update some of
+ // our parameters.
+ if (entering) {
+ AliDebug(15, "Entering active FMD volume");
+ fCurrentDeltaE = 0;
+
+ // Get production vertex and momentum of the track
+ mc->TrackMomentum(fCurrentP);
+ mc->TrackPosition(fCurrentV);
+ fCurrentPdg = mc->IdFromPDG(mc->TrackPid());
+ }
+
+ // If the track is inside, then update the energy deposition
+ if (inside && fCurrentDeltaE >= 0)
+ AliDebug(15, "Inside active FMD volume");
+ fCurrentDeltaE += 1000 * mc->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) {
+ AliDebug(15, Form("Leaving active FMD volume %s", mc->CurrentVolPath()));
+
+ Int_t strip = copy - 1;
+ Int_t sectordiv;
+ mc->CurrentVolOffID(fSectorOff, sectordiv);
+ Int_t module;
+ mc->CurrentVolOffID(fModuleOff, module);
+ Int_t sector = 2 * module + sectordiv;
+ Int_t iring;
+ mc->CurrentVolOffID(fRingOff, iring);
+ Char_t ring = Char_t(iring);
+ Int_t detector;
+ mc->CurrentVolOffID(fDetectorOff, detector);
+
+
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ Double_t rz = fmd->GetDetector(detector)->GetRingZ(ring);
+ Int_t n = fmd->GetDetector(detector)->GetRing(ring)->GetNSectors();
+ if (rz < 0) {
+ Int_t s = ((n - sector + n / 2) % n) + 1;
+ AliDebug(40, Form("Recalculating sector to %d (=%d-%d+%d/2%%%d+1 z=%f)",
+ s, n, sector, n, n, rz));
+ sector = s;
+ }
+ if (sector < 1 || sector > n) {
+ Warning("Step", "sector # %d out of range (0-%d)", sector-1, n-1);
+ return;
+ }
+ sector--;
+ fCurrentDeltaE += 1000 * mc->Edep();
+
+ AliDebug(20, Form("Processing hit in FMD%d%c[%2d,%3d]: %f",
+ detector, ring, sector, strip, fCurrentDeltaE));
+
+ fFMD->AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),
+ UShort_t(detector), ring, UShort_t(sector), UShort_t(strip),
+ fCurrentV.X(), fCurrentV.Y(), fCurrentV.Z(),
+ fCurrentP.X(), fCurrentP.Y(), fCurrentP.Z(),
+ fCurrentDeltaE, fCurrentPdg, fCurrentV.T());
+ fCurrentDeltaE = -1;
+ }
+}
+
+
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDSIMULATOR_H
+#define ALIFMDSIMULATOR_H
+/* 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 TTask
+# include <TTask.h>
+#endif
+#ifndef TLorentzVector
+# include <TLorentzVector.h>
+#endif
+class TVector3;
+class AliFMD;
+class AliFMDRing;
+class AliFMDDetector;
+class AliFMD1;
+class AliFMD2;
+class AliFMD3;
+
+/** Simulation of the FMD.
+ This class builds the geometry, and processes hits in the FMD */
+class AliFMDSimulator : public TTask
+{
+public:
+ AliFMDSimulator();
+ /** CTOR */
+ AliFMDSimulator(AliFMD* fmd, Bool_t detailed=kTRUE);
+ virtual ~AliFMDSimulator() {}
+ /** Initialize */
+ virtual void DefineMaterials();
+ /** Register */
+ virtual void DefineGeometry() = 0;
+ /** Deal with a hit in the FMD */
+ virtual void Exec(Option_t* option="");
+
+protected:
+ AliFMD* fFMD; //! Pointer to module
+ Bool_t fDetailed; // Whether to make a detailed simulation
+ Int_t fInnerId; //! ID of inner ring strips
+ Int_t fOuterId; //! ID of outer ring strips
+ TLorentzVector fCurrentV; //! Current hit postition
+ TLorentzVector fCurrentP; //! Current hit momentum
+ Int_t fCurrentPdg; //! Current hit particle code
+ Double_t fCurrentDeltaE; //! Current hit energy loss
+
+ static const Char_t* fgkActiveName; // Name of Active volumes
+ static const Char_t* fgkSectorName; // Name of Sector volumes
+ static const Char_t* fgkStripName; // Name of Strip volumes
+ static const Char_t* fgkModuleName; // Name of Module volumes
+ static const Char_t* fgkPCBName; // Name of PCB volumes
+ static const Char_t* fgkLongLegName; // Name of LongLeg volumes
+ static const Char_t* fgkShortLegName; // Name of ShortLeg volumes
+ static const Char_t* fgkFrontVName; // Name of Front volumes
+ static const Char_t* fgkBackVName; // Name of Back volumes
+ static const Char_t* fgkRingName; // Name of Ring volumes
+ static const Char_t* fgkTopHCName; // Name of TopHC volumes
+ static const Char_t* fgkBotHCName; // Name of BotHC volumes
+ static const Char_t* fgkTopIHCName; // Name of TopIHC volumes
+ static const Char_t* fgkBotIHCName; // Name of BotIHC volumes
+ static const Char_t* fgkNoseName; // Name of Nose volumes
+ static const Char_t* fgkBackName; // Name of Back volumes
+ static const Char_t* fgkBeamName; // Name of Beam volumes
+ static const Char_t* fgkFlangeName; // Name of Flange volumes
+
+ enum {
+ kSiId, // ID index of Si medium
+ kAirId, // ID index of Air medium
+ kPlasticId, // ID index of Plastic medium
+ kPcbId, // ID index of PCB medium
+ kSiChipId, // ID index of Si Chip medium
+ kAlId, // ID index of Al medium
+ kCarbonId // ID index of Carbon medium
+ };
+
+ Int_t fSectorOff; // Sector offset in volume tree
+ Int_t fModuleOff; // Module offset in volume tree
+ Int_t fRingOff; // Ring offset in the volume tree
+ Int_t fDetectorOff; // Detector offfset in the volume tree
+
+ ClassDef(AliFMDSimulator,0) // Simulation class for the FMD
+};
+
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// 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
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#include "AliFMDSubDetector.h" // ALIFMDSUBDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include <AliLog.h> // ALILOG_H
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TList.h> // ROOT_TList
-#include <TString.h> // ROOT_TString
-
-//____________________________________________________________________
-ClassImp(AliFMDSubDetector)
-
-//____________________________________________________________________
-const Char_t* AliFMDSubDetector::fgkHoneyTopFormat = "F%d%cH";
-const Char_t* AliFMDSubDetector::fgkHoneyBottomFormat = "F%d%cI";
-const Char_t* AliFMDSubDetector::fgkHoneyTopInnerFormat = "F%d%cJ";
-const Char_t* AliFMDSubDetector::fgkHoneyBottomInnerFormat = "F%d%cK";
-
-//____________________________________________________________________
-AliFMDSubDetector::AliFMDSubDetector(Int_t n)
- : fId(n),
- fInnerZ(0),
- fOuterZ(0),
- fInner(0),
- fOuter(0)
-{
- // Normal CTOR
- SetAlThickness();
- SetHoneycombThickness();
-}
-
-
-//____________________________________________________________________
-void
-AliFMDSubDetector::Draw(Option_t* /* opt */) const
-{
- // DebugGuard guard("AliFMDSubDetector::Draw");
- AliDebug(30, Form("\tDrawing FMD%d", fId));
- Gsatt();
- gMC->Gdraw(Form("FMD%d", fId));
-}
-
-//____________________________________________________________________
-void
-AliFMDSubDetector::DrawSpecs() const
-{
- // DebugGuard guard("AliFMDSubDetector::Draw");
- AliDebug(30, Form("\tDrawing specs foro FMD%d", fId));
- gMC->DrawOneSpec(Form("FMD%d", fId));
-}
-
-//____________________________________________________________________
-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.
- AliDebug(30, Form("\tChecking wether the hit at (%lf,%lf) "
- "is in ring %c module %d", x, y, ring, module));
- 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
- //
- AliDebug(20, Form("\tCreating simple geometry for FMD%d", fId));
- 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 alId, Int_t /* cId
- */)
-{
- // 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
- // alId Medium of honeycomb
- //
- // DebugGuard guard("AliFMDSubDetector::SetupGeometry");
- AliDebug(20, Form("\tSetting up the geometry for FMD%d", fId));
- 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;
- par[0] = fInnerHoneyLowR;
- par[1] = fInnerHoneyHighR;
- break;
- case 1:
- r = fOuter;
- par[0] = fOuterHoneyLowR;
- par[1] = fOuterHoneyHighR;
- break;
- }
- if (!r) continue;
- c = r->GetId();
-
- // Top of honeycomb, inner ring
- par[2] = fHoneycombThickness / 2;
- par[3] = 0;
- par[4] = 180;
- name = Form(fgkHoneyTopFormat, fId, c);
- gMC->Gsvolu(name.Data(), "TUBS", alId, par, 5);
-
- // Bottom of honeycomb, inner ring
- par[3] = 180;
- par[4] = 360;
- name = Form(fgkHoneyBottomFormat, fId, c);
- gMC->Gsvolu(name.Data(), "TUBS", alId, par, 5);
-
- // Air in top of honeycomb, inner ring
- par[0] += fAlThickness;
- par[1] -= fAlThickness;
- par[2] -= fAlThickness;
- par[3] = 0;
- par[4] = 180;
- name = Form(fgkHoneyTopInnerFormat, fId, c);
- gMC->Gsvolu(name.Data(), "TUBS", airId, par, 5);
-
- // Air in bottom of honeycomb, inner ring
- par[3] = 180;
- par[4] = 360;
- name = Form(fgkHoneyBottomInnerFormat, fId, c);
- 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(20, Form("\tDefining the rings in %s (z=%lf cm)",
- mother, zMother));
-
- 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;
- z = fInnerZ;
- break;
- case 1:
- r = fOuter;
- z = fOuterZ;
- break;
- }
- if (!r) continue;
- c = r->GetId();
-
- // 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.
- Double_t z2 = z;
- z2 -= zMother;
- if (zMother > 0) z2 *= -1;
- AliDebug(10, Form("\tPutting ring %c in %s at z=%lf-%lf=%lf",
- c, mother, z, zMother, z2));
- r->Geometry(mother, fId, z2, pbRotId, idRotId);
- ringW = r->GetRingDepth();
- z2 -= ringW + fHoneycombThickness / 2;
-
- // Top of honeycomb
- name = Form(fgkHoneyTopFormat, fId, c);
- gMC->Gspos(name.Data(), 1, mother, 0, 0, z2, idRotId, "ONLY");
-
- // Air in top of honeycomb
- name2 = name;
- name = Form(fgkHoneyTopInnerFormat, fId, c);
- gMC->Gspos(name.Data(), 1, name2.Data(),0,fAlThickness,0,idRotId,"ONLY");
-
- // Bottom of honeycomb
- name = Form(fgkHoneyBottomFormat, fId, c);
- gMC->Gspos(name.Data(), 1, mother, 0, 0, z2, idRotId, "ONLY");
-
- // Air in bottom of honeycomb
- name2 = name;
- name = Form(fgkHoneyBottomInnerFormat, fId, c);
- gMC->Gspos(name.Data(),1,name2.Data(),0,-fAlThickness,0,idRotId, "ONLY");
- }
-}
-
-//____________________________________________________________________
-void
-AliFMDSubDetector::Gsatt() const
-{
- // Set drawing attributes for the detector
- //
- // DebugGuard guard("AliFMDSubDetector::Gsatt");
- AliDebug(30, Form("\tSetting draw attributs for FMD%d", fId));
- TString name;
-
- name = Form("FMD%d", fId);
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- for (int i = 0; i < 2; i++) {
- AliFMDRing* r = 0;
- char c = '\0';
- switch (i) {
- case 0: r = fInner; break;
- case 1: r = fOuter; break;
- }
- if (!r) continue;
- c = r->GetId();
-
- name = Form(fgkHoneyTopFormat, fId, c);
- gMC->Gsatt(name.Data(), "SEEN", 1);
-
- name = Form(fgkHoneyBottomFormat, fId, c);
- gMC->Gsatt(name.Data(), "SEEN", 1);
-
- name = Form(fgkHoneyTopInnerFormat, fId, c);
- gMC->Gsatt(name.Data(), "SEEN", 0);
-
- name = Form(fgkHoneyBottomInnerFormat, fId, c);
- gMC->Gsatt(name.Data(), "SEEN", 0);
- }
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDSUBDETECTOR_H
-#define ALIFMDSUBDETECTOR_H
-/* 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
- */
-//____________________________________________________________________
-//
-// Parameters of a sub-detector, and builder of sub detector geometry
-//
-#ifndef ROOT_TObject
-# include <TObject.h>
-#endif
-class TNode;
-class TList;
-class AliFMDRing;
-
-
-//__________________________________________________________________
-class AliFMDSubDetector : public TObject
-{
-public:
- AliFMDSubDetector(Int_t n);
- virtual ~AliFMDSubDetector() {}
- virtual void SetupGeometry(Int_t airId, Int_t alId, Int_t cId=0);
- 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() const;
- virtual void Draw(Option_t* option="BIOL0") const; //*MENU*
- virtual void DrawSpecs() 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 SetAlThickness(Double_t t=.05) { fAlThickness = 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 GetAlThickness() const { return fAlThickness; }
- Int_t GetId() const { return fId; }
- Bool_t IsFolder() const { return kTRUE; }
-
-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 fAlThickness; // Thickness of aluminium 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; // The ID of the sub-detector rotation
-
- AliFMDRing* fInner; // Reference to inner ring description
- AliFMDRing* fOuter; // Reference to outer ring description
-
- static const Char_t* fgkHoneyTopFormat; // Format of honeycomb name
- static const Char_t* fgkHoneyBottomFormat; // Format of honeycomb name
- static const Char_t* fgkHoneyTopInnerFormat; // Format of honeycomb name
- static const Char_t* fgkHoneyBottomInnerFormat; // Format of honeycomb name
-
- ClassDef(AliFMDSubDetector, 1) // FMD Sub detector base class
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
//____________________________________________________________________
ClassImp(AliFMDUShortMap)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
AliFMDUShortMap::AliFMDUShortMap(const AliFMDUShortMap& other)
//____________________________________________________________________
//
-// Forward Multiplicity Detector based on Silicon wafers This class
+// 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.
-//
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
+//
// This contains the coarse version of the FMD - that is, the
// simulation produces no hits in the FMD volumes.
-//
-// 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 |
-// +---------+ +---------+ +---------+
-//
//
// See also the AliFMD class for a more detailed description of the
// various components.
//____________________________________________________________________
ClassImp(AliFMDv0)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//___________________________________________________________________
//
public:
AliFMDv0() {}
AliFMDv0(const char *name, const char *title="Coarse geometry")
- : AliFMD(name, title, false)
+ : AliFMD(name, title)
{}
virtual ~AliFMDv0()
{}
//
// 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.
-//
+// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
+// which has 1 or 2 rings of silicon sensors.
+//
// This class contains the detailed version of the FMD - that is, hits
// are produced during simulation.
//
-// 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 |
-// +---------+ +---------+ +---------+
-//
-//
// See also the class AliFMD for a more detailed explanation of the
// various componets.
+//
#include <TVirtualMC.h> // ROOT_TVirtualMC
#include <AliRun.h> // ALIRUN_H
#include <AliMC.h> // ALIMC_H
#include <AliLog.h> // ALILOG_H
#include "AliFMDv1.h" // ALIFMDV1_H
+#include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H
+#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
+#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H
//____________________________________________________________________
ClassImp(AliFMDv1)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
//____________________________________________________________________
void
AliFMDv1::StepManager()
{
- //
// Called for every step in the Forward Multiplicity Detector
//
- // The procedure is as follows:
+ // The message is deligated to AliFMDSimulator::Exec
//
- // - 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
- //
- //
- AliDebug(10, Form("Is inside %s", gMC->CurrentVolName()));
-
- // 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;
- Int_t copy;
- Int_t volumeId = gMC->CurrentVolID(copy);
- // The ring ID is encoded in the volume name
- Char_t ring = '\0';
- if (volumeId == fInner->GetStripId()) ring = 'I';
- else if (volumeId == fOuter->GetStripId()) ring = 'O';
- else return;
-
- // Get the strip number. Note, that GEANT numbers divisions from 1,
- // so we subtract one
- Int_t strip = copy - 1;
-
- // 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;
-
-
- // 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);
-
- AliDebug(2, Form("Is inside FMD%d%c[%02d,%03d]: particle is %s",
- detector, ring, sector, strip,
- (entering ? "entering" :
- (inside ? "inside" :
- "exiting"))));
-
- // 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;
+ if (!fSimulator) {
+ AliFatal("No simulator object made");
+ return;
}
+ fSimulator->Exec("");
}
//___________________________________________________________________
//
class AliFMDv1 : public AliFMD
{
public:
- AliFMDv1() {}
+ AliFMDv1() { fDetailed = kTRUE; }
AliFMDv1(const char *name, const char *title="Detailed geometry")
- : AliFMD(name, title, true)
- {}
+ : AliFMD(name, title)
+ { fDetailed = kTRUE; }
virtual ~AliFMDv1() {}
// Required member functions
TLorentzVector fCurrentP; // Current momentum vector
Int_t fCurrentPdg; // Current PDG code
- ClassDef(AliFMDv1,3) // Detailed FMD geometry
+ ClassDef(AliFMDv1,4) // Detailed FMD geometry
};
#endif
enum MC_t {
kFLUKA,
kGEANT3,
- kGEANT4
+ kGEANT4,
+ kGEANT3TGEO,
};
//____________________________________________________________________
Rad_t rad = kGluonRadiation;
Mag_t mag = k5kG;
Int_t seed = 12345; //Set 0 to use the current time
- MC_t mc = kGEANT3;
+ MC_t mc = kGEANT3TGEO;
//____________________________________________________________________
// Comment line
//
new TGeant3("C++ Interface to Geant3");
break;
+ case kGEANT3TGEO:
+ //
+ // Libraries needed by GEANT 3.21
+ //
+ gSystem->Load("libgeant321");
+
+ //
+ // GEANT 3.21 MC
+ //
+ new TGeant3TGeo("C++ Interface to Geant3");
+ Printf("Making a TGeant3TGeo objet");
+ break;
default:
gAlice->Fatal("Config.C", "No MC type chosen");
return;
//__________________________________________________________________
// Generator Configuration
- gAlice->SetDebug(0);
AliGenerator* gener = GeneratorFactory(eg, rad, comment);
gener->SetOrigin(0, 0, 0); // vertex position
gener->SetSigma(0, 0, 5.3); // Sigma in (X,Y,Z) (cm) on IP position
//
// Used detectors
//
- Bool_t useABSO = kFALSE;
- Bool_t useCRT = kFALSE;
- Bool_t useDIPO = kFALSE;
+ Bool_t useABSO = kTRUE;
+ Bool_t useCRT = kTRUE;
+ Bool_t useDIPO = kTRUE;
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 useVZERO = kFALSE;
+ Bool_t useFRAME = kTRUE;
+ Bool_t useHALL = kTRUE;
+ Bool_t useITS = kTRUE;
+ Bool_t useMAG = kTRUE;
+ Bool_t useMUON = kTRUE;
+ Bool_t usePHOS = kTRUE;
+ Bool_t usePIPE = kTRUE;
+ Bool_t usePMD = kTRUE;
+ Bool_t useRICH = kTRUE;
+ Bool_t useSHIL = kTRUE;
+ Bool_t useSTART = kTRUE;
+ Bool_t useTOF = kTRUE;
+ Bool_t useTPC = kTRUE;
+ Bool_t useTRD = kTRUE;
+ Bool_t useZDC = kTRUE;
+ Bool_t useEMCAL = kTRUE;
+ Bool_t useVZERO = kTRUE;
cout << "\t* Creating the detectors ..." << endl;
//=================== Alice BODY parameters =============================
if (useFMD) {
//=================== FMD parameters ============================
AliFMD *FMD = new AliFMDv1("FMD", "normal FMD");
+ AliLog::SetModuleDebugLevel("FMD", 10);
}
if (useMUON) {
case kParam_fmd:
{
comment = comment.Append("HIJINGparam N=100");
- AliGenHIJINGpara *gener = new AliGenHIJINGpara(100);
+ AliGenHIJINGpara *gener = new AliGenHIJINGpara(500);
gener->SetMomentumRange(0, 999999.);
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
+ Float_t thmin = EtaToTheta(6); // theta min. <---> eta max
+ Float_t thmax = EtaToTheta(2); // theta max. <---> eta min
gener->SetThetaRange(thmin,thmax);
gGener=gener;
}
#pragma link C++ class AliFMDDigit+;
#pragma link C++ class AliFMDSDigit+;
#pragma link C++ class AliFMDMap+;
+#pragma link C++ class AliFMD1+;
+#pragma link C++ class AliFMD2+;
+#pragma link C++ class AliFMD3+;
+#pragma link C++ class AliFMDRing+;
+#pragma link C++ class AliFMDDetector+;
+#pragma link C++ class AliFMDGeometry+;
+#pragma link C++ class AliFMDParameters+;
#else
# error Not for compilation
#pragma link C++ class AliFMD+;
#pragma link C++ class AliFMDv0+;
#pragma link C++ class AliFMDv1+;
-#pragma link C++ class AliFMDSubDetector+;
-#pragma link C++ class AliFMD1+;
-#pragma link C++ class AliFMD2+;
-#pragma link C++ class AliFMD3+;
-#pragma link C++ class AliFMD3Support+;
-#pragma link C++ class AliFMDRing+;
-#pragma link C++ class AliFMDPolygon+;
+#pragma link C++ class AliFMDSimulator+;
+#pragma link C++ class AliFMDGeoSimulator+;
+#pragma link C++ class AliFMDG3Simulator+;
#pragma link C++ class AliFMDBaseDigitizer+;
#pragma link C++ class AliFMDDigitizer+;
#pragma link C++ class AliFMDSDigitizer+;
// sim.SetMakeDigits("FMD");
sim.SetWriteRawData("FMD");
// sim.SetMakeDigitsFromHits("FMD");
- sim.Run();
+ sim.Run(2);
}
//
gMC->Gsatt("FMD1","seen",0);
gMC->Gsatt("FMD2","seen",0);
gMC->Gsatt("FMD3","seen",0);
- gMC->Gsatt("FSSL","seen",1);
- gMC->Gsatt("FSLL","seen",1);
TString name;
// Rings
case 1: c = 'O'; break;
}
- name = Form("F%cRG", c);
+ name = Form("FMD%c", c);
gMC->Gsatt(name.Data(),"seen",0); // Ring volume
- name = Form("F%cVF", c);
+ name = Form("F%cFV", c);
gMC->Gsatt(name.Data(),"seen",0); // Virtual volume front
- name = Form("F%cVB", c);
+ name = Form("F%cBV", c);
gMC->Gsatt(name.Data(),"seen",0); // Virtual volume back
name = Form("F%cAC", c);
gMC->Gsatt(name.Data(),"seen",-2); // Active volume
+ name = Form("F%cSL", c);
+ gMC->Gsatt(name.Data() ,"seen",1);
+
+ name = Form("F%cLL", c);
+ gMC->Gsatt(name.Data() ,"seen",1);
+
// name = Form("F%cAP", c);
// gMC->Gsatt(name.Data(),"seen",-1); // Phi segmentation of active
case 1: c = 'O'; break;
}
- name = Form("F%d%cH", i, c);
+ name = Form("F%d%cI", i, c);
gMC->Gsatt(name.Data(),"seen",-2); // Honeycomp top
- name = Form("F%d%cI", i, c);
+ name = Form("F%d%cJ", i, c);
gMC->Gsatt(name.Data(),"seen",-2); // Honeycomp bottom
- name = Form("F%d%cJ", i, c);
+ name = Form("F%d%cK", i, c);
gMC->Gsatt(name.Data(),"seen",0); // Honeycomp inner top
- name = Form("F%d%cK", i, c);
+ name = Form("F%d%cL", i, c);
gMC->Gsatt(name.Data(),"seen",0); // Honeycomp inner bottom
}
}
# $Id$
SRCS = AliFMDDigit.cxx \
- AliFMDMap.cxx
+ AliFMDMap.cxx \
+ AliFMDParameters.cxx \
+ AliFMDGeometry.cxx \
+ AliFMDRing.cxx \
+ AliFMDDetector.cxx \
+ AliFMD1.cxx \
+ AliFMD2.cxx \
+ AliFMD3.cxx
HDRS = $(SRCS:.cxx=.h)
DHDR := FMDbaseLinkDef.h
SRCS = AliFMD.cxx \
AliFMDv0.cxx \
AliFMDv1.cxx \
- AliFMDSubDetector.cxx \
- AliFMD1.cxx \
- AliFMD2.cxx \
- AliFMD3.cxx \
- AliFMD3Support.cxx \
- AliFMDRing.cxx \
- AliFMDPolygon.cxx \
+ AliFMDSimulator.cxx \
+ AliFMDGeoSimulator.cxx \
+ AliFMDG3Simulator.cxx \
AliFMDHit.cxx \
AliFMDDigitizer.cxx \
AliFMDEdepMap.cxx \
--- /dev/null
+//
+// Script to draw detail of the FMD
+//
+void DrawFMD2()
+{
+ // gAlice->Init("FMD/scripts/ConfigInner.C");
+ gAlice->Init("$(ALICE)/FMD/Config.C");
+ gMC->Gsatt("*", "seen", -1);
+ gMC->Gsatt("alic", "seen", 0);
+ gROOT->LoadMacro("$(ALICE)/FMD/ViewFMD.C");
+ gInterpreter->ProcessLine("ViewFMD()");
+ gMC->Gsatt("FMD3", "seen", -1);
+ gMC->Gsatt("FMD1", "seen", -1);
+ 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", 90, 0, 0, 28, 10, .25, .25);
+ // gMC->Gdraw("alic", 90, 0, 0, 28, 10, .25, .25);
+ gMC->Gdraw("alic", 179, 0, 0, 10, 10, .25, .25);
+
+#if 0
+ TArrow* a1 = new TArrow(13.5, 16, 15, 18., .03, "<|");
+ a1->SetAngle(30);
+ a1->SetFillColor(1);
+ a1->Draw();
+
+ TLatex* l1 = new TLatex(15, 18, "Honeycomb");
+ l1->SetTextAlign(12);
+ l1->SetTextFont(132);
+ l1->SetTextSize(.04);
+ l1->Draw();
+
+ a1->DrawArrow(13.4, 14., 15, 15, .03, "<|");
+ l1->DrawLatex(15, 15, "Support Leg");
+
+ a1->DrawArrow(10.7, 14.2, 15, 13, .03, "<|");
+ l1->DrawLatex(15, 13, "Print board");
+
+ a1->DrawArrow(9.7, 12.5, 15, 11, .03, "<|");
+ l1->DrawLatex(15, 11, "Silicon sensor");
+
+ a1->DrawArrow(8.3, 12.7, 7, 15, .03, "<|");
+ TLatex* l2 = new TLatex(7, 15, "Support Cone");
+ l2->SetTextSize(.04);
+ l2->SetTextFont(132);
+ l2->SetTextAlign(32);
+ l2->Draw();
+
+ TLatex* l3 = new TLatex(3, 3, "FMD2");
+ l3->SetTextSize(.06);
+ l3->SetTextFont(132);
+ l3->Draw();
+#endif
+
+ gPad->Modified();
+ gPad->cd();
+ gPad->Print("FMD2.png");
+}
gMC->SetClipBox(".");
gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
gMC->DefaultRange();
- gMC->Gdraw("alic", 60, 0, 0, -3, 10, .25, .25);
+ gMC->Gdraw("alic", 90, 0, 0, -3, 10, .25, .25);
TArrow* a1 = new TArrow(13.5, 16, 15, 18., .03, "<|");
a1->SetAngle(30);