/*
$Log$
+Revision 1.16.2.2 2000/02/28 17:53:24 cblume
+Introduce TRD geometry classes
+
+Revision 1.16.2.1 2000/02/28 17:04:19 cblume
+Include functions and data members for AliTRDrecPoint
+
+Revision 1.16 2000/01/19 17:17:35 fca
+Introducing a list of lists of hits -- more hits allowed for detector now
+
Revision 1.15 1999/11/02 17:04:25 fca
Small syntax change for HP compiler
#include "AliTRD.h"
#include "AliRun.h"
#include "AliConst.h"
+#include "AliTRDdigitizer.h"
+#include "AliTRDclusterizer.h"
+#include "AliTRDgeometryHole.h"
+#include "AliTRDgeometryFull.h"
+#include "AliTRDrecPoint.h"
ClassImp(AliTRD)
// Default constructor
//
- Int_t iplan;
-
fIshunt = 0;
fGasMix = 0;
fHits = 0;
fDigits = 0;
- fHole = 0;
-
- fClusters = 0;
- fNclusters = 0;
-
- // The chamber dimensions
- for (iplan = 0; iplan < kNplan; iplan++) {
- fClengthI[iplan] = 0.;
- fClengthM1[iplan] = 0.;
- fClengthM2[iplan] = 0.;
- fClengthO1[iplan] = 0.;
- fClengthO2[iplan] = 0.;
- fClengthO3[iplan] = 0.;
- fCwidth[iplan] = 0.;
- }
- for (iplan = 0; iplan < kNplan; iplan++) {
- for (Int_t icham = 0; icham < kNcham; icham++) {
- for (Int_t isect = 0; isect < kNsect; isect++) {
- fRowMax[iplan][icham][isect] = 0;
- }
- }
- fColMax[iplan] = 0;
- }
- fTimeMax = 0;
+ fRecPoints = 0;
+ fNRecPoints = 0;
- fRowPadSize = 0;
- fColPadSize = 0;
- fTimeBinSize = 0;
+ fGeometry = 0;
}
// Standard constructor for the TRD
//
- Int_t iplan;
-
// Check that FRAME is there otherwise we have no place where to
// put TRD
AliModule* FRAME=gAlice->GetModule("FRAME");
}
// Define the TRD geometry according to the FRAME geometry
- if (FRAME->IsVersion() == 0)
- // With hole
- fHole = 1;
- else
- // Without hole
- fHole = 0;
+ if (FRAME->IsVersion() == 0) {
+ // Geometry with hole
+ fGeometry = new AliTRDgeometryHole();
+ }
+ else if (FRAME->IsVersion() == 1) {
+ // Geometry without hole
+ fGeometry = new AliTRDgeometryFull();
+ }
+ else {
+ Error("Ctor","Could not find valid FRAME version\n");
+ exit(1);
+ }
// Allocate the hit array
- fHits = new TClonesArray("AliTRDhit" , 405);
+ fHits = new TClonesArray("AliTRDhit" , 405);
gAlice->AddHitList(fHits);
// Allocate the digits array
- fDigits = new TClonesArray("AliTRDdigit" ,10000);
+ fDigits = 0;
- // Allocate the cluster array
- fClusters = new TClonesArray("AliTRDcluster", 400);
- fNclusters = 0;
+ // Allocate the rec point array
+ fRecPoints = new TClonesArray("AliTRDrecPoint", 400);
+ fNRecPoints = 0;
fIshunt = 0;
fGasMix = 0;
- // The chamber dimensions
- for (iplan = 0; iplan < kNplan; iplan++) {
- fClengthI[iplan] = 0.;
- fClengthM1[iplan] = 0.;
- fClengthM2[iplan] = 0.;
- fClengthO1[iplan] = 0.;
- fClengthO2[iplan] = 0.;
- fClengthO3[iplan] = 0.;
- fCwidth[iplan] = 0.;
- }
-
- for (iplan = 0; iplan < kNplan; iplan++) {
- for (Int_t icham = 0; icham < kNcham; icham++) {
- for (Int_t isect = 0; isect < kNsect; isect++) {
- fRowMax[iplan][icham][isect] = 0;
- }
- }
- fColMax[iplan] = 0;
- }
- fTimeMax = 0;
-
- fRowPadSize = 0;
- fColPadSize = 0;
- fTimeBinSize = 0;
-
SetMarkerColor(kWhite);
}
fIshunt = 0;
+ delete fGeometry;
delete fHits;
- delete fDigits;
- delete fClusters;
+ delete fRecPoints;
}
//_____________________________________________________________________________
-void AliTRD::AddCluster(Int_t *tracks, Int_t *clusters, Float_t *position)
+void AliTRD::AddRecPoint(Float_t *pos, Int_t *digits, Int_t det, Float_t amp)
{
//
- // Add a cluster for the TRD
- //
+ // Add a reconstructed point for the TRD
+ //
- TClonesArray &lclusters = *fClusters;
- new(lclusters[fNclusters++]) AliTRDcluster(tracks,clusters,position);
+ TClonesArray &lRecPoints = *fRecPoints;
+ AliTRDrecPoint *RecPoint = new(lRecPoints[fNRecPoints++]) AliTRDrecPoint();
+ TVector3 posVec(pos[0],pos[1],pos[2]);
+ RecPoint->SetLocalPosition(posVec);
+ RecPoint->SetDetector(det);
+ RecPoint->SetAmplitude(amp);
+ for (Int_t iDigit = 0; iDigit < 3; iDigit++) {
+ RecPoint->AddDigit(digits[iDigit]);
+ }
}
//_____________________________________________________________________________
-void AliTRD::AddDigit(Int_t *tracks, Int_t *digits)
+void AliTRD::AddDigit(Int_t *digits)
{
//
// Add a digit for the TRD
//
TClonesArray &ldigits = *fDigits;
- new(ldigits[fNdigits++]) AliTRDdigit(tracks,digits);
+ new(ldigits[fNdigits++]) AliTRDdigit(digits);
}
//_____________________________________________________________________________
-void AliTRD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
+void AliTRD::AddHit(Int_t track, Int_t det, Float_t *hits)
{
//
// Add a hit for the TRD
//
TClonesArray &lhits = *fHits;
- new(lhits[fNhits++]) AliTRDhit(fIshunt,track,vol,hits);
+ new(lhits[fNhits++]) AliTRDhit(fIshunt,track,det,hits);
}
//
// Creates the volumes for the TRD chambers
//
- // Author: Christoph Blume (C.Blume@gsi.de) 20/07/99
- //
- // The volumes:
- // TRD1-3 (Air) --- The TRD mother volumes for one sector.
- // To be placed into the spaceframe.
- //
- // UAFI(/M/O) (Al) --- The aluminum frame of the inner(/middle/outer) chambers (readout)
- // UCFI(/M/O) (C) --- The carbon frame of the inner(/middle/outer) chambers
- // (driftchamber + radiator)
- // UAII(/M/O) (Air) --- The inner part of the readout of the inner(/middle/outer) chambers
- // UFII(/M/O) (Air) --- The inner part of the chamner and radiator of the
- // inner(/middle/outer) chambers
- //
- // The material layers in one chamber:
- // UL01 (G10) --- The gas seal of the radiator
- // UL02 (CO2) --- The gas in the radiator
- // UL03 (PE) --- The foil stack
- // UL04 (Mylar) --- Entrance window to the driftvolume and HV-cathode
- // UL05 (Xe) --- The driftvolume
- // UL06 (Xe) --- The amplification region
- //
- // UL07 (Cu) --- The pad plane
- // UL08 (G10) --- The Nomex honeycomb support structure
- // UL09 (Cu) --- FEE and signal lines
- // UL10 (PE) --- The cooling devices
- // UL11 (Water) --- The cooling water
// Check that FRAME is there otherwise we have no place where to put the TRD
AliModule* FRAME = gAlice->GetModule("FRAME");
- if (!FRAME) return;
-
- Int_t iplan;
-
- const Int_t npar_trd = 4;
- const Int_t npar_cha = 3;
-
- Float_t par_dum[3];
- Float_t par_trd[npar_trd];
- Float_t par_cha[npar_cha];
-
- Float_t xpos, ypos, zpos;
-
- Int_t *idtmed = fIdtmed->GetArray() - 1299;
-
- // The length of the inner chambers
- for (iplan = 0; iplan < kNplan; iplan++)
- fClengthI[iplan] = 110.0;
-
- // The length of the middle chambers
- fClengthM1[0] = 123.5;
- fClengthM1[1] = 131.0;
- fClengthM1[2] = 138.5;
- fClengthM1[3] = 146.0;
- fClengthM1[4] = 153.0;
- fClengthM1[5] = 160.5;
-
- fClengthM2[0] = 123.5 - 7.0;
- fClengthM2[1] = 131.0 - 7.0;
- fClengthM2[2] = 138.5 - 7.0;
- fClengthM2[3] = 146.0 - 7.0;
- fClengthM2[4] = 153.0 - 7.0;
- fClengthM2[5] = 160.4 - 7.0;
-
- // The length of the outer chambers
- fClengthO1[0] = 123.5;
- fClengthO1[1] = 131.0;
- fClengthO1[2] = 134.5;
- fClengthO1[3] = 142.0;
- fClengthO1[4] = 142.0;
- fClengthO1[5] = 134.5;
-
- fClengthO2[0] = 123.5;
- fClengthO2[1] = 131.0;
- fClengthO2[2] = 134.5;
- fClengthO2[3] = 142.0;
- fClengthO2[4] = 142.0;
- fClengthO2[5] = 134.5;
-
- fClengthO3[0] = 86.5;
- fClengthO3[1] = 101.5;
- fClengthO3[2] = 112.5;
- fClengthO3[3] = 127.5;
- fClengthO3[4] = 134.5;
- fClengthO3[5] = 134.5;
-
- // The width of the chambers
- fCwidth[0] = 99.6;
- fCwidth[1] = 104.1;
- fCwidth[2] = 108.5;
- fCwidth[3] = 112.9;
- fCwidth[4] = 117.4;
- fCwidth[5] = 121.8;
-
- // The TRD mother volume for one sector (Air) (dimensions identical to BTR1)
- par_trd[0] = kSwidth1/2.;
- par_trd[1] = kSwidth2/2.;
- par_trd[2] = kSlenTR1/2.;
- par_trd[3] = kSheight/2.;
- gMC->Gsvolu("TRD1","TRD1",idtmed[1302-1],par_trd,npar_trd);
-
- // The TRD mother volume for one sector (Air) (dimensions identical to BTR2 + BTR3).
- // Only used for the geometry with holes.
- if (fHole) {
-
- par_trd[0] = kSwidth1/2.;
- par_trd[1] = kSwidth2/2.;
- par_trd[2] = kSlenTR2/2.;
- par_trd[3] = kSheight/2.;
- gMC->Gsvolu("TRD2","TRD1",idtmed[1302-1],par_trd,npar_trd);
-
- par_trd[0] = kSwidth1/2.;
- par_trd[1] = kSwidth2/2.;
- par_trd[2] = kSlenTR3/2.;
- par_trd[3] = kSheight/2.;
- gMC->Gsvolu("TRD3","TRD1",idtmed[1302-1],par_trd,npar_trd);
-
- }
-
- // The aluminum frames - readout + electronics (Al)
- // The inner chambers
- gMC->Gsvolu("UAFI","BOX ",idtmed[1301-1],par_dum,0);
- // The middle chambers
- gMC->Gsvolu("UAFM","BOX ",idtmed[1301-1],par_dum,0);
- // The outer chambers
- gMC->Gsvolu("UAFO","BOX ",idtmed[1301-1],par_dum,0);
-
- // The inner part of the aluminum frames (Air)
- // The inner chambers
- gMC->Gsvolu("UAII","BOX ",idtmed[1302-1],par_dum,0);
- // The middle chambers
- gMC->Gsvolu("UAIM","BOX ",idtmed[1302-1],par_dum,0);
- // The outer chambers
- gMC->Gsvolu("UAIO","BOX ",idtmed[1302-1],par_dum,0);
-
- // The carbon frames - radiator + driftchamber (C)
- // The inner chambers
- gMC->Gsvolu("UCFI","BOX ",idtmed[1307-1],par_dum,0);
- // The middle chambers
- gMC->Gsvolu("UCFM","BOX ",idtmed[1307-1],par_dum,0);
- // The outer chambers
- gMC->Gsvolu("UCFO","BOX ",idtmed[1307-1],par_dum,0);
-
- // The inner part of the carbon frames (Air)
- // The inner chambers
- gMC->Gsvolu("UCII","BOX ",idtmed[1302-1],par_dum,0);
- // The middle chambers
- gMC->Gsvolu("UCIM","BOX ",idtmed[1302-1],par_dum,0);
- // The outer chambers
- gMC->Gsvolu("UCIO","BOX ",idtmed[1302-1],par_dum,0);
-
- // The material layers inside the chambers
- par_cha[0] = -1.;
- par_cha[1] = -1.;
- // G10 layer (radiator seal)
- par_cha[2] = kSeThick/2;
- gMC->Gsvolu("UL01","BOX ",idtmed[1313-1],par_cha,npar_cha);
- // CO2 layer (radiator)
- par_cha[2] = kRaThick/2;
- gMC->Gsvolu("UL02","BOX ",idtmed[1312-1],par_cha,npar_cha);
- // PE layer (radiator)
- par_cha[2] = kPeThick/2;
- gMC->Gsvolu("UL03","BOX ",idtmed[1303-1],par_cha,npar_cha);
- // Mylar layer (entrance window + HV cathode)
- par_cha[2] = kMyThick/2;
- gMC->Gsvolu("UL04","BOX ",idtmed[1308-1],par_cha,npar_cha);
- // Xe/Isobutane layer (drift volume, sensitive)
- par_cha[2] = kDrThick/2.;
- gMC->Gsvolu("UL05","BOX ",idtmed[1309-1],par_cha,npar_cha);
- // Xe/Isobutane layer (amplification volume, not sensitive)
- par_cha[2] = kAmThick/2.;
- gMC->Gsvolu("UL06","BOX ",idtmed[1309-1],par_cha,npar_cha);
-
- // Cu layer (pad plane)
- par_cha[2] = kCuThick/2;
- gMC->Gsvolu("UL07","BOX ",idtmed[1305-1],par_cha,npar_cha);
- // G10 layer (support structure)
- par_cha[2] = kSuThick/2;
- gMC->Gsvolu("UL08","BOX ",idtmed[1313-1],par_cha,npar_cha);
- // Cu layer (FEE + signal lines)
- par_cha[2] = kFeThick/2;
- gMC->Gsvolu("UL09","BOX ",idtmed[1305-1],par_cha,npar_cha);
- // PE layer (cooling devices)
- par_cha[2] = kCoThick/2;
- gMC->Gsvolu("UL10","BOX ",idtmed[1303-1],par_cha,npar_cha);
- // Water layer (cooling)
- par_cha[2] = kWaThick/2;
- gMC->Gsvolu("UL11","BOX ",idtmed[1314-1],par_cha,npar_cha);
-
- // Position the layers in the chambers
- xpos = 0;
- ypos = 0;
-
- // G10 layer (radiator seal)
- zpos = kSeZpos;
- gMC->Gspos("UL01",1,"UCII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL01",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL01",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
- // CO2 layer (radiator)
- zpos = kRaZpos;
- gMC->Gspos("UL02",1,"UCII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL02",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL02",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
- // PE layer (radiator)
- zpos = 0;
- gMC->Gspos("UL03",1,"UL02",xpos,ypos,zpos,0,"ONLY");
- // Mylar layer (entrance window + HV cathode)
- zpos = kMyZpos;
- gMC->Gspos("UL04",1,"UCII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL04",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL04",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
- // Xe/Isobutane layer (drift volume)
- zpos = kDrZpos;
- gMC->Gspos("UL05",1,"UCII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL05",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL05",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
- // Xe/Isobutane layer (amplification volume)
- zpos = kAmZpos;
- gMC->Gspos("UL06",1,"UCII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL06",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL06",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
-
- // Cu layer (pad plane)
- zpos = kCuZpos;
- gMC->Gspos("UL07",1,"UAII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL07",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL07",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
- // G10 layer (support structure)
- zpos = kSuZpos;
- gMC->Gspos("UL08",1,"UAII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL08",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL08",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
- // Cu layer (FEE + signal lines)
- zpos = kFeZpos;
- gMC->Gspos("UL09",1,"UAII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL09",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL09",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
- // PE layer (cooling devices)
- zpos = kCoZpos;
- gMC->Gspos("UL10",1,"UAII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL10",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL10",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
- // Water layer (cooling)
- zpos = kWaZpos;
- gMC->Gspos("UL11",1,"UAII",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL11",1,"UAIM",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("UL11",1,"UAIO",xpos,ypos,zpos,0,"ONLY");
-
- // Position the chambers in the TRD mother volume
- for (iplan = 1; iplan <= kNplan; iplan++) {
-
- // The inner chambers ---------------------------------------------------------------
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthI[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = 0.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFI",iplan ,"TRD1",xpos,ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthI[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = 0.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAII",iplan ,"TRD1",xpos,ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthI[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = 0.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFI",iplan ,"TRD1",xpos,ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthI[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = 0.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCII",iplan ,"TRD1",xpos,ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // The middle chambers --------------------------------------------------------------
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthM1[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1]/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFM",iplan ,"TRD1",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
- gMC->Gsposp("UAFM",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthM1[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1]/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAIM",iplan ,"TRD1",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
- gMC->Gsposp("UAIM",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthM1[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1]/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFM",iplan ,"TRD1",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
- gMC->Gsposp("UCFM",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthM1[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1]/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCIM",iplan ,"TRD1",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
- gMC->Gsposp("UCIM",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // Only for the geometry with holes
- if (fHole) {
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthM2[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFM",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthM2[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAIM",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthM2[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFM",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthM2[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCIM",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- }
-
- // The outer chambers ---------------------------------------------------------------
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO1[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1] + fClengthO1[iplan-1]/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFO",iplan ,"TRD1",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
- gMC->Gsposp("UAFO",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthO1[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1] + fClengthO1[iplan-1]/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAIO",iplan ,"TRD1",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
- gMC->Gsposp("UAIO",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO1[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1] + fClengthO1[iplan-1]/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFO",iplan, "TRD1",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
- gMC->Gsposp("UCFO",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthO1[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthI[iplan-1]/2. + fClengthM1[iplan-1] + fClengthO1[iplan-1]/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCIO",iplan ,"TRD1",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
- gMC->Gsposp("UCIO",iplan+ kNplan,"TRD1",xpos,-ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // Only for the geometry with holes
- if (fHole) {
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO2[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1] + fClengthO2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFO",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthO2[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1] + fClengthO2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAIO",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO2[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1] + fClengthO2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFO",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthO2[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthM2[iplan-1] + fClengthO2[iplan-1]/2. - kSlenTR2/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCIO",iplan+2*kNplan,"TRD2",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO3[iplan-1]/2.;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthO3[iplan-1]/2. - kSlenTR3/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAFO",iplan+4*kNplan,"TRD3",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the aluminum frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCathick;
- par_cha[1] = fClengthO3[iplan-1]/2. - kCathick;
- par_cha[2] = kCaframe/2.;
- xpos = 0.;
- ypos = fClengthO3[iplan-1]/2. - kSlenTR3/2.;
- zpos = kCheight - kCaframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UAIO",iplan+4*kNplan,"TRD3",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- // the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2.;
- par_cha[1] = fClengthO3[iplan-1]/2.;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthO3[iplan-1]/2. - kSlenTR3/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCFO",iplan+4*kNplan,"TRD3",xpos, ypos,zpos,0,"MANY",par_cha,npar_cha);
-
- // the inner part of the carbon frame
- par_cha[0] = fCwidth[iplan-1]/2. - kCcthick;
- par_cha[1] = fClengthO3[iplan-1]/2. - kCcthick;
- par_cha[2] = kCcframe/2.;
- xpos = 0.;
- ypos = fClengthO3[iplan-1]/2. - kSlenTR3/2.;
- zpos = kCcframe/2. - kSheight/2. + (iplan-1) * (kCheight + kCspace);
- gMC->Gsposp("UCIO",iplan+4*kNplan,"TRD3",xpos, ypos,zpos,0,"ONLY",par_cha,npar_cha);
-
- }
-
+ if (!FRAME) {
+ printf(" The TRD needs the FRAME to be defined first\n");
+ return;
}
- if (fHole) {
- xpos = 0.;
- ypos = 0.;
- zpos = 0.;
- gMC->Gspos("TRD1",1,"BTR1",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("TRD2",1,"BTR2",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("TRD3",1,"BTR3",xpos,ypos,zpos,0,"ONLY");
- }
- else {
- xpos = 0.;
- ypos = 0.;
- zpos = 0.;
- gMC->Gspos("TRD1",1,"BTR1",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("TRD1",2,"BTR2",xpos,ypos,zpos,0,"ONLY");
- gMC->Gspos("TRD1",3,"BTR3",xpos,ypos,zpos,0,"ONLY");
- }
+ fGeometry->CreateGeometry(fIdtmed->GetArray() - 1299);
}
gMC->Gsatt("ALIC","SEEN", 0);
// Set the volumes visible
- if (fHole) {
+ if (fGeometry->IsVersion() == 0) {
gMC->Gsatt("B071","SEEN", 0);
gMC->Gsatt("B074","SEEN", 0);
gMC->Gsatt("B075","SEEN", 0);
void AliTRD::Init()
{
//
- // Initialise the TRD detector after the geometry has been created
+ // Initialize the TRD detector after the geometry has been created
//
Int_t i;
- Int_t iplan;
-
+
printf("\n");
- for(i=0;i<35;i++) printf("*");
+ for (i = 0; i < 35; i++) printf("*");
printf(" TRD_INIT ");
- for(i=0;i<35;i++) printf("*");
+ for (i = 0; i < 35; i++) printf("*");
+ printf("\n");
printf("\n");
-
- // Here the TRD initialisation code (if any!)
- if (fGasMix == 1)
- printf(" Gas Mixture: 90%% Xe + 10%% CO2\n");
- else
- printf(" Gas Mixture: 97%% Xe + 3%% Isobutane\n");
-
- if (fHole)
- printf(" Geometry with holes\n");
- else
- printf(" Full geometry\n");
-
- // The default pad dimensions
- if (!(fRowPadSize)) fRowPadSize = 4.5;
- if (!(fColPadSize)) fColPadSize = 1.0;
- if (!(fTimeBinSize)) fTimeBinSize = 0.1;
-
- // The maximum number of pads
- // and the position of pad 0,0,0
- //
- // chambers seen from the top:
- // +----------------------------+
- // | |
- // | | ^
- // | | rphi|
- // | | |
- // |0 | |
- // +----------------------------+ +------>
- // z
- // chambers seen from the side: ^
- // +----------------------------+ time|
- // | | |
- // |0 | |
- // +----------------------------+ +------>
- // z
- //
- for (iplan = 0; iplan < kNplan; iplan++) {
-
- // The pad row (z-direction)
- for (Int_t isect = 0; isect < kNsect; isect++) {
- Float_t clengthI = fClengthI[iplan];
- Float_t clengthM = fClengthM1[iplan];
- Float_t clengthO = fClengthO1[iplan];
- if (fHole) {
- switch (isect) {
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- clengthM = fClengthM2[iplan];
- clengthO = fClengthO2[iplan];
- break;
- case 4:
- case 5:
- case 6:
- clengthO = fClengthO3[iplan];
- break;
- };
- }
- fRowMax[iplan][0][isect] = 1 + TMath::Nint((clengthO - 2. * kCcthick)
- / fRowPadSize - 0.5);
- fRowMax[iplan][1][isect] = 1 + TMath::Nint((clengthM - 2. * kCcthick)
- / fRowPadSize - 0.5);
- fRowMax[iplan][2][isect] = 1 + TMath::Nint((clengthI - 2. * kCcthick)
- / fRowPadSize - 0.5);
- fRowMax[iplan][3][isect] = 1 + TMath::Nint((clengthM - 2. * kCcthick)
- / fRowPadSize - 0.5);
- fRowMax[iplan][4][isect] = 1 + TMath::Nint((clengthO - 2. * kCcthick)
- / fRowPadSize - 0.5);
- fRow0[iplan][0][isect] = -clengthI/2. - clengthM - clengthO + kCcthick;
- fRow0[iplan][1][isect] = -clengthI/2. - clengthM + kCcthick;
- fRow0[iplan][2][isect] = -clengthI/2. + kCcthick;
- fRow0[iplan][3][isect] = clengthI/2. + kCcthick;
- fRow0[iplan][4][isect] = clengthI/2. + clengthM + kCcthick;
- }
-
- // The pad column (rphi-direction)
- fColMax[iplan] = 1 + TMath::Nint((fCwidth[iplan] - 2. * kCcthick)
- / fColPadSize - 0.5);
- fCol0[iplan] = -fCwidth[iplan]/2. + kCcthick;
+ if (fGeometry->IsVersion() == 0) {
+ printf(" Geometry with holes initialized.\n\n");
+ }
+ else if (fGeometry->IsVersion() == 1) {
+ printf(" Geometry without holes initialized.\n\n");
}
- // The time bucket
- fTimeMax = 1 + TMath::Nint(kDrThick / fTimeBinSize - 0.5);
- for (iplan = 0; iplan < kNplan; iplan++) {
- fTime0[iplan] = kRmin + kCcframe/2. + kDrZpos - 0.5 * kDrThick
- + iplan * (kCheight + kCspace);
- }
+ if (fGasMix == 1)
+ printf(" Gas Mixture: 90%% Xe + 10%% CO2\n\n");
+ else
+ printf(" Gas Mixture: 97%% Xe + 3%% Isobutane\n\n");
}
AliDetector::MakeBranch(option);
- Char_t *D = strstr(option,"D");
- sprintf(branchname,"%s",GetName());
- if (fDigits && gAlice->TreeD() && D) {
- gAlice->TreeD()->Branch(branchname,&fDigits, buffersize);
- printf("* AliTRD::MakeBranch * Making Branch %s for digits in TreeD\n",branchname);
+ //Char_t *D = strstr(option,"D");
+ //sprintf(branchname,"%s",GetName());
+ //if (fDigits && gAlice->TreeD() && D) {
+ // gAlice->TreeD()->Branch(branchname,&fDigits, buffersize);
+ // printf("* AliTRD::MakeBranch * Making Branch %s for digits in TreeD\n",branchname);
+ //}
+
+ Char_t *R = strstr(option,"R");
+ sprintf(branchname,"%srecPoints",GetName());
+ if (fRecPoints && gAlice->TreeR() && R) {
+ gAlice->TreeR()->Branch(branchname,&fRecPoints,buffersize);
+ printf("* AliTRD::MakeBranch * Making Branch %s for points in TreeR\n",branchname);
}
- sprintf(branchname,"%scluster",GetName());
- if (fClusters && gAlice->TreeD() && D) {
- gAlice->TreeD()->Branch(branchname,&fClusters,buffersize);
- printf("* AliTRD::MakeBranch * Making Branch %s for cluster in TreeD\n",branchname);
- }
+}
+
+//_____________________________________________________________________________
+void AliTRD::ResetRecPoints()
+{
+ //
+ // Reset number of reconstructed points and the point array
+ //
+
+ fNRecPoints = 0;
+ if (fRecPoints) fRecPoints->Clear();
}
AliDetector::SetTreeAddress();
TBranch *branch;
- TTree *treeD = gAlice->TreeD();
-
- if (treeD) {
- sprintf(branchname,"%scluster",GetName());
- if (fClusters) {
- branch = treeD->GetBranch(branchname);
- if (branch) branch->SetAddress(&fClusters);
+ TTree *treeR = gAlice->TreeR();
+
+ if (treeR) {
+ sprintf(branchname,"%srecPoints",GetName());
+ if (fRecPoints) {
+ branch = treeR->GetBranch(branchname);
+ if (branch) {
+ branch->SetAddress(&fRecPoints);
+ }
}
}
//______________________________________________________________________________
void AliTRD::Streamer(TBuffer &R__b)
{
- // Stream an object of class AliTRD.
-
- if (R__b.IsReading()) {
- Version_t R__v = R__b.ReadVersion(); if (R__v) { }
- AliDetector::Streamer(R__b);
- R__b >> fGasMix;
- R__b.ReadStaticArray(fClengthI);
- R__b.ReadStaticArray(fClengthM1);
- R__b.ReadStaticArray(fClengthM2);
- R__b.ReadStaticArray(fClengthO1);
- R__b.ReadStaticArray(fClengthO2);
- R__b.ReadStaticArray(fClengthO3);
- R__b.ReadStaticArray(fCwidth);
- R__b.ReadStaticArray((int*)fRowMax);
- R__b.ReadStaticArray(fColMax);
- R__b >> fTimeMax;
- R__b.ReadStaticArray((float*)fRow0);
- R__b.ReadStaticArray(fCol0);
- R__b.ReadStaticArray(fTime0);
- R__b >> fRowPadSize;
- R__b >> fColPadSize;
- R__b >> fTimeBinSize;
- R__b >> fHole;
- // Stream the pointers but not the TClonesArray
- R__b >> fClusters; // diff
- //R__b >> fNclusters;
- } else {
- R__b.WriteVersion(AliTRD::IsA());
- AliDetector::Streamer(R__b);
- R__b << fGasMix;
- R__b.WriteArray(fClengthI, 6);
- R__b.WriteArray(fClengthM1, 6);
- R__b.WriteArray(fClengthM2, 6);
- R__b.WriteArray(fClengthO1, 6);
- R__b.WriteArray(fClengthO2, 6);
- R__b.WriteArray(fClengthO3, 6);
- R__b.WriteArray(fCwidth, 6);
- R__b.WriteArray((int*)fRowMax, 540);
- R__b.WriteArray(fColMax, 6);
- R__b << fTimeMax;
- R__b.WriteArray((float*)fRow0, 540);
- R__b.WriteArray(fCol0, 6);
- R__b.WriteArray(fTime0, 6);
- R__b << fRowPadSize;
- R__b << fColPadSize;
- R__b << fTimeBinSize;
- R__b << fHole;
- // Stream the pointers but not the TClonesArrays
- R__b << fClusters; // diff
- //R__b << fNclusters;
- }
+ //
+ // Stream an object of class AliTRD.
+ //
+
+ if (R__b.IsReading()) {
+ Version_t R__v = R__b.ReadVersion(); if (R__v) { }
+ AliDetector::Streamer(R__b);
+ R__b >> fGasMix;
+ R__b >> fGeometry;
+ // Stream the pointers but not the TClonesArray
+ R__b >> fRecPoints; // diff
+ }
+ else {
+ R__b.WriteVersion(AliTRD::IsA());
+ AliDetector::Streamer(R__b);
+ R__b << fGasMix;
+ R__b << fGeometry;
+ // Stream the pointers but not the TClonesArrays
+ R__b << fRecPoints; // diff
+ }
}
ClassImp(AliTRDhit)
//_____________________________________________________________________________
-AliTRDhit::AliTRDhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits)
+AliTRDhit::AliTRDhit(Int_t shunt, Int_t track, Int_t det, Float_t *hits)
:AliHit(shunt, track)
{
//
//
// Store volume hierarchy
- fSector = vol[0];
- fChamber = vol[1];
- fPlane = vol[2];
-
- // Store position and charge
- fX = hits[0];
- fY = hits[1];
- fZ = hits[2];
- fQ = hits[3];
+ fDetector = det;
-}
-
-ClassImp(AliTRDdigit)
-
-//_____________________________________________________________________________
-AliTRDdigit::AliTRDdigit(Int_t *tracks, Int_t *digits)
- :AliDigit(tracks)
-{
- //
- // Create a TRD digit
- //
-
- // Store the volume hierarchy
- fSector = digits[0];
- fChamber = digits[1];
- fPlane = digits[2];
-
- // Store the row, pad, and time bucket number
- fRow = digits[3];
- fCol = digits[4];
- fTime = digits[5];
-
- // Store the signal amplitude
- fSignal = digits[6];
-
-}
-
-ClassImp(AliTRDcluster)
-
-//_____________________________________________________________________________
-AliTRDcluster::AliTRDcluster(Int_t *tracks, Int_t *cluster, Float_t* position)
- :TObject()
-{
- //
- // Create a TRD cluster
- //
-
- fSector = cluster[0];
- fChamber = cluster[1];
- fPlane = cluster[2];
-
- fTimeSlice = cluster[3];
- fEnergy = cluster[4];
-
- fX = position[0];
- fY = position[1];
- fZ = position[2];
-
- fTracks[0] = tracks[0];
- fTracks[1] = tracks[1];
- fTracks[2] = tracks[2];
+ // Store position and charge
+ fX = hits[0];
+ fY = hits[1];
+ fZ = hits[2];
+ fQ = hits[3];
}
// Manager and hits classes for set: TRD //
////////////////////////////////////////////////
+#include "AliRun.h"
#include "AliDetector.h"
#include "AliHit.h"
#include "AliDigit.h"
+
#include "AliTRDconst.h"
+//#include "AliTRDgeometry.h"
+
+class AliTRDgeometry;
//_____________________________________________________________________________
class AliTRD : public AliDetector {
-
-protected:
- Int_t fGasMix; // Gas mixture. 0: Xe/Isobutane 1: Xe/CO2
-
- Float_t fClengthI[kNplan]; // Length of the inner chambers
- Float_t fClengthM1[kNplan]; // Length of the middle chambers
- Float_t fClengthM2[kNplan]; //
- Float_t fClengthO1[kNplan]; // Length of the outer chambers
- Float_t fClengthO2[kNplan]; //
- Float_t fClengthO3[kNplan]; //
- Float_t fCwidth[kNplan]; // Width of the chambers
- Int_t fRowMax[kNplan][kNcham][kNsect]; // Number of pad-rows
- Int_t fColMax[kNplan]; // Number of pad-columns
- Int_t fTimeMax; // Number of time buckets
+ public:
- Float_t fRow0[kNplan][kNcham][kNsect]; // Row-position of pad 0
- Float_t fCol0[kNplan]; // Column-position of pad 0
- Float_t fTime0[kNplan]; // Time-position of pad 0
+ AliTRD();
+ AliTRD(const char *name, const char *title);
+ virtual ~AliTRD();
+ virtual void AddHit(Int_t, Int_t, Float_t*);
+ virtual void AddDigit(Int_t*);
+ virtual void AddRecPoint(Float_t*, Int_t*, Int_t, Float_t);
+ virtual void BuildGeometry();
+ virtual void CreateGeometry();
+ virtual void CreateMaterials();
+ virtual void DrawModule();
+ Int_t DistancetoPrimitive(Int_t px, Int_t py);
+ TClonesArray *RecPoints() { return fRecPoints; };
+ virtual void Init();
+ virtual Int_t IsVersion() const = 0;
+ virtual void MakeBranch(Option_t* option);
+ virtual void ResetRecPoints();
+ virtual void StepManager() = 0;
+ virtual void SetTreeAddress();
+
+ virtual void SetGasMix(Int_t imix = 0);
+ virtual void SetHits(Int_t ihit = 1) {};
+
+ AliTRDgeometry *GetGeometry() { return fGeometry; };
+
+ virtual Int_t GetSensChamber() = 0;
+ virtual Int_t GetSensPlane() = 0;
+ virtual Int_t GetSensSector() = 0;
+
+ protected:
- Float_t fRowPadSize; // Pad size in z-direction
- Float_t fColPadSize; // Pad size in rphi-direction
- Float_t fTimeBinSize; // Size of the time buckets
+ Int_t fGasMix; // Gas mixture. 0: Xe/Isobutane 1: Xe/CO2
- Int_t fHole; // Geometry without (0) / with (1) hole
+ AliTRDgeometry *fGeometry; // The TRD geometry
- TClonesArray *fClusters; // List of clusters
- Int_t fNclusters; // Number of clusters
+ TClonesArray *fRecPoints; // List of reconstructed points
+ Int_t fNRecPoints; //! Number of reconstructed points
-public:
- AliTRD();
- AliTRD(const char *name, const char *title);
- virtual ~AliTRD();
- virtual void AddHit(Int_t, Int_t*, Float_t*);
- virtual void AddDigit(Int_t*, Int_t*);
- virtual void AddCluster(Int_t*, Int_t*, Float_t*);
- virtual void BuildGeometry();
- virtual void CreateGeometry();
- virtual void CreateMaterials();
- virtual void DrawModule();
- Int_t DistancetoPrimitive(Int_t px, Int_t py);
- TClonesArray *Cluster() { return fClusters; };
- virtual void Init();
- virtual Int_t IsVersion() const = 0;
- virtual void MakeBranch(Option_t* option);
- virtual void StepManager() = 0;
- virtual void SetTreeAddress();
-
- virtual void SetHits(Int_t ) {};
- virtual void SetSensPlane(Int_t) {};
- virtual void SetSensChamber(Int_t) {};
- virtual void SetSensSector(Int_t ) {};
-
- virtual void SetGasMix(Int_t imix = 0);
-
- virtual void SetRowPadSize(Float_t size) { fRowPadSize = size; };
- virtual void SetColPadSize(Float_t size) { fColPadSize = size; };
- virtual void SetTimeBinSize(Float_t size) { fTimeBinSize = size; };
-
- virtual Float_t GetRowPadSize() { return fRowPadSize; };
- virtual Float_t GetColPadSize() { return fColPadSize; };
- virtual Float_t GetTimeBinSize() { return fTimeBinSize; };
-
- virtual Int_t GetRowMax(Int_t p, Int_t c, Int_t s) { return fRowMax[p-1][c-1][s-1]; };
- virtual Int_t GetColMax(Int_t p) { return fColMax[p-1]; };
- virtual Int_t GetTimeMax() { return fTimeMax; };
-
- virtual Int_t Hole() { return fHole; };
-
- ClassDef(AliTRD,1) // Transition Radiation Detector base class
+ ClassDef(AliTRD,1) // Transition Radiation Detector base class
};
class AliTRDhit : public AliHit {
public:
- Int_t fSector; // TRD sector number
- Int_t fChamber; // TRD chamber number
- Int_t fPlane; // TRD plane number
+ Int_t fDetector; // TRD detector number
Float_t fQ; // Charge created by a hit (slow simulator only)
public:
AliTRDhit() {}
- AliTRDhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits);
+ AliTRDhit(Int_t shunt, Int_t track, Int_t det, Float_t *hits);
virtual ~AliTRDhit() {};
- ClassDef(AliTRDhit,1) // Hits for Transition Radiation Detector
-
-};
-
-//_____________________________________________________________________________
-class AliTRDdigit : public AliDigit {
-
-public:
- Int_t fSector; // TRD sector number
- Int_t fChamber; // TRD chamber number
- Int_t fPlane; // TRD plane number
- Int_t fRow; // Pad row number
- Int_t fCol; // Pad col number
- Int_t fTime; // Time bucket
- Int_t fSignal; // Signal amplitude
-
-public:
- AliTRDdigit() {};
- AliTRDdigit(Int_t *tracks, Int_t *digits);
- virtual ~AliTRDdigit() {};
-
- ClassDef(AliTRDdigit,1) // Digits for Transition Radiation Detector
-
-};
-
-//_____________________________________________________________________________
-class AliTRDcluster : public TObject {
-
-public:
- Int_t fSector; // TRD sector number
- Int_t fChamber; // TRD chamber number
- Int_t fPlane; // TRD plane number
-
- Int_t fTimeSlice; // Timeslice in chamber where cluster has been found
- Int_t fEnergy; // Charge sum of this cluster
-
- Float_t fX; // X coord in ALICE reference frame
- Float_t fY; // Y coord in ALICE reference frame
- Float_t fZ; // Z coord in ALICE reference frame
-
- Int_t fTracks[3]; // Track information
-
-public:
- AliTRDcluster() {};
- AliTRDcluster(Int_t *tracks, Int_t *cluster, Float_t *pos);
- virtual ~AliTRDcluster() {};
-
- inline virtual Int_t *GetTracks() { return &fTracks[0]; }
-
- ClassDef(AliTRDcluster,1) // Cluster for Transition Radiation Detector
+ ClassDef(AliTRDhit,2) // Hits for Transition Radiation Detector
};
/*
$Log$
+Revision 1.3.4.1 2000/02/28 17:57:47 cblume
+GetTrack returns now -1 if no track is found
+
+Revision 1.3 1999/10/04 14:48:07 fca
+Avoid warnings on non-ansi compiler HP-UX CC
+
Revision 1.2 1999/09/29 09:24:35 fca
Introduction of the Copyright and cvs Log
//
if ((iRow < 0) || (iRow >= fRow)) {
+ printf("AliTRDmatrix::DrawRow -- ");
printf("Index out of bounds (%d/%d)\n",iRow,fRow);
return;
}
//
if ((iCol < 0) || (iCol >= fCol)) {
+ printf("AliTRDmatrix::DrawCol -- ");
printf("Index out of bounds (%d/%d)\n",iCol,fCol);
return;
}
//
if ((iTime < 0) || (iTime >= fTime)) {
+ printf("AliTRDmatrix::DrawTime -- ");
printf("Index out of bounds (%d/%d)\n",iTime,fTime);
return;
}
trackSet = kTRUE;
break;
}
- if (pixel->GetTrack(i) == 0) {
+ if (pixel->GetTrack(i) == -1) {
pixel->SetTrack(i,track);
trackSet = kTRUE;
break;
//
if ((iTrack < 0) || (iTrack >= kTrackPixel)) {
- printf("GetTrack: Index out of bounds (%d)\n",iTrack);
- return 0;
+ printf("AliTRDmatrix::GetTrack -- ");
+ printf("Index out of bounds (%d)\n",iTrack);
+ return -1;
}
AliTRDpixel *pixel = GetPixel(iRow,iCol,iTime);
return (pixel->GetTrack(iTrack));
}
else {
- return 0;
+ return -1;
}
}
#include <TH3.h>
#include <TStyle.h>
#include <TCanvas.h>
+
#include "AliTRDpixel.h"
///////////////////////////////////////////////////////
/*
$Log$
+Revision 1.2.4.1 2000/02/28 17:59:27 cblume
+Initialize fTrack with -1
+
+Revision 1.2 1999/09/29 09:24:35 fca
+Introduction of the Copyright and cvs Log
+
*/
///////////////////////////////////////////////////////////////////////////////
// Create a TRD pixel
//
- fSignal = 0;
- fTrack[0] = 0;
- fTrack[1] = 0;
- fTrack[2] = 0;
+ fSignal = 0;
+ fTrack[0] = -1;
+ fTrack[1] = -1;
+ fTrack[2] = -1;
}
/*
$Log$
+Revision 1.13.4.1 2000/02/28 18:01:53 cblume
+Change to new hit version and introduce geometry class
+
+Revision 1.13 1999/11/05 22:50:28 fca
+Do not use Atan, removed from ROOT too
+
Revision 1.12 1999/11/02 16:35:56 fca
New version of TRD introduced
#include <TRandom.h>
#include <TVector.h>
-#include "AliTRDv0.h"
#include "AliRun.h"
#include "AliMC.h"
#include "AliConst.h"
-ClassImp(AliTRDv0)
+#include "AliTRDv0.h"
+#include "AliTRDgeometry.h"
+ClassImp(AliTRDv0)
+
//_____________________________________________________________________________
AliTRDv0::AliTRDv0(const char *name, const char *title)
:AliTRD(name, title)
fIdChamber2 = 0;
fIdChamber3 = 0;
- fRphiSigma = 0;
- fRphiDist = 0;
-
}
-
+
//_____________________________________________________________________________
void AliTRDv0::CreateGeometry()
{
}
-//_____________________________________________________________________________
-void AliTRDv0::Hits2Clusters()
-{
- // A simple cluster generator. It takes the hits from the
- // fast simulator (one hit per plane) and transforms them
- // into cluster, by applying position smearing and merging
- // of nearby cluster. The searing is done uniformly in z-direction
- // over the length of a readout pad. In rphi-direction a Gaussian
- // smearing is applied with a sigma given by fRphiSigma.
- // Clusters are considered as overlapping when they are closer in
- // rphi-direction than the value defined in fRphiDist.
- // Use the macro fastClusterCreate.C to create the cluster.
-
- printf("AliTRDv0::Hits2Clusters -- Start creating cluster\n");
-
- Int_t nBytes = 0;
-
- AliTRDhit *TRDhit;
-
- // Get the pointer to the hit tree
- TTree *HitTree = gAlice->TreeH();
- // Get the pointer to the reconstruction tree
- TTree *ClusterTree = gAlice->TreeD();
-
- TObjArray *Chamber = new TObjArray();
-
- // Get the number of entries in the hit tree
- // (Number of primary particles creating a hit somewhere)
- Int_t nTrack = (Int_t) HitTree->GetEntries();
-
- // Loop through all the chambers
- for (Int_t icham = 0; icham < kNcham; icham++) {
- for (Int_t iplan = 0; iplan < kNplan; iplan++) {
- for (Int_t isect = 0; isect < kNsect; isect++) {
-
- // Loop through all entries in the tree
- for (Int_t iTrack = 0; iTrack < nTrack; iTrack++) {
-
- gAlice->ResetHits();
- nBytes += HitTree->GetEvent(iTrack);
-
- // Get the number of hits in the TRD created by this particle
- Int_t nHit = fHits->GetEntriesFast();
-
- // Loop through the TRD hits
- for (Int_t iHit = 0; iHit < nHit; iHit++) {
-
- if (!(TRDhit = (AliTRDhit *) fHits->UncheckedAt(iHit)))
- continue;
-
- Float_t x = TRDhit->fX;
- Float_t y = TRDhit->fY;
- Float_t z = TRDhit->fZ;
- Int_t track = TRDhit->fTrack;
- Int_t plane = TRDhit->fPlane;
- Int_t sector = TRDhit->fSector;
- Int_t chamber = TRDhit->fChamber;
-
- if ((sector != isect+1) ||
- (plane != iplan+1) ||
- (chamber != icham+1))
- continue;
-
- // Rotate the sectors on top of each other
- Float_t phi = 2.0 * kPI / (Float_t) kNsect
- * ((Float_t) sector - 0.5);
- Float_t xRot = -x * TMath::Cos(phi) + y * TMath::Sin(phi);
- Float_t yRot = x * TMath::Sin(phi) + y * TMath::Cos(phi);
- Float_t zRot = z;
-
- // Add this cluster to the temporary cluster-array for this chamber
- Int_t tracks[3];
- tracks[0] = track;
- Int_t clusters[5];
- clusters[0] = sector;
- clusters[1] = chamber;
- clusters[2] = plane;
- clusters[3] = 0;
- clusters[4] = 0;
- Float_t position[3];
- position[0] = zRot;
- position[1] = yRot;
- position[2] = xRot;
- AliTRDcluster *Cluster = new AliTRDcluster(tracks,clusters,position);
- Chamber->Add(Cluster);
-
- }
-
- }
-
- // Loop through the temporary cluster-array
- for (Int_t iClus1 = 0; iClus1 < Chamber->GetEntries(); iClus1++) {
-
- AliTRDcluster *Cluster1 = (AliTRDcluster *) Chamber->UncheckedAt(iClus1);
- Float_t x1 = Cluster1->fX;
- Float_t y1 = Cluster1->fY;
- Float_t z1 = Cluster1->fZ;
-
- if (!(z1)) continue; // Skip marked cluster
-
- const Int_t nSave = 2;
- Int_t idxSave[nSave];
- Int_t iSave = 0;
-
- Int_t tracks[3];
- tracks[0] = Cluster1->fTracks[0];
-
- // Check the other cluster to see, whether there are close ones
- for (Int_t iClus2 = iClus1 + 1; iClus2 < Chamber->GetEntries(); iClus2++) {
- AliTRDcluster *Cluster2 = (AliTRDcluster *) Chamber->UncheckedAt(iClus2);
- Float_t x2 = Cluster2->fX;
- Float_t y2 = Cluster2->fY;
- if ((TMath::Abs(x1 - x2) < fRowPadSize) ||
- (TMath::Abs(y1 - y2) < fRphiDist)) {
- if (iSave == nSave) {
- printf("AliTRDv0::Hits2Clusters -- Boundary error: iSave = %d, nSave = %d\n"
- ,iSave,nSave);
- }
- else {
- idxSave[iSave] = iClus2;
- tracks[iSave+1] = Cluster2->fTracks[0];
- }
- iSave++;
- }
- }
-
- // Merge close cluster
- Float_t yMerge = y1;
- Float_t xMerge = x1;
- if (iSave) {
- for (Int_t iMerge = 0; iMerge < iSave; iMerge++) {
- AliTRDcluster *Cluster2 = (AliTRDcluster *) Chamber->UncheckedAt(idxSave[iMerge]);
- xMerge += Cluster2->fX;
- yMerge += Cluster2->fY;
- Cluster2->fZ = 0; // Mark merged cluster
- }
- xMerge /= (iSave + 1);
- yMerge /= (iSave + 1);
- }
-
- // The position smearing in z-direction (uniform over pad width)
- Int_t row = (Int_t) ((xMerge - fRow0[iplan][icham][isect]) / fRowPadSize);
- Float_t xSmear = (row + gRandom->Rndm()) * fRowPadSize
- + fRow0[iplan][icham][isect];
-
- // The position smearing in rphi-direction (Gaussian)
- Float_t ySmear = 0;
- do
- ySmear = gRandom->Gaus(yMerge,fRphiSigma);
- while ((ySmear < fCol0[iplan]) ||
- (ySmear > fCol0[iplan] + fColMax[iplan] * fColPadSize));
-
- // Time direction stays unchanged
- Float_t zSmear = z1;
-
- Int_t clusters[5];
- clusters[0] = Cluster1->fSector;
- clusters[1] = Cluster1->fChamber;
- clusters[2] = Cluster1->fPlane;
- clusters[3] = 0;
- clusters[4] = 0;
- Float_t position[3];
- // Rotate the sectors back into their real position
- Float_t phi = 2*kPI / kNsect * ((Float_t) Cluster1->fSector - 0.5);
- position[0] = -zSmear * TMath::Cos(phi) + ySmear * TMath::Sin(phi);
- position[1] = zSmear * TMath::Sin(phi) + ySmear * TMath::Cos(phi);
- position[2] = xSmear;
-
- // Add the smeared cluster to the output array
- AddCluster(tracks,clusters,position);
-
- }
-
- // Clear the temporary cluster-array and delete the cluster
- Chamber->Delete();
-
- }
- }
- }
-
- printf("AliTRDv0::Hits2Clusters -- Found %d cluster\n",fClusters->GetEntries());
- printf("AliTRDv0::Hits2Clusters -- Fill the cluster tree\n");
- ClusterTree->Fill();
-
-}
-
//_____________________________________________________________________________
void AliTRDv0::Init()
{
//
- // Initialise Transition Radiation Detector after geometry is built
+ // Initialize Transition Radiation Detector after geometry is built
//
AliTRD::Init();
fIdChamber2 = gMC->VolId("UCIM");
fIdChamber3 = gMC->VolId("UCII");
- // Parameter for Hits2Cluster
-
- // Position resolution in rphi-direction
- fRphiSigma = 0.02;
- // Minimum distance of non-overlapping cluster
- fRphiDist = 1.0;
-
- printf(" Fast simulator\n");
+ printf(" Fast simulator\n\n");
for (Int_t i = 0; i < 80; i++) printf("*");
printf("\n");
// crosses the border between amplification region and pad plane.
//
- Int_t vol[3];
+ Int_t pla = 0;
+ Int_t cha = 0;
+ Int_t sec = 0;
Int_t iIdSens, icSens;
Int_t iIdChamber, icChamber;
// No charge created
hits[3] = 0;
- // The sector number
- Float_t phi = hits[1] != 0 ? kRaddeg*TMath::ATan2(hits[0],hits[1]) : (hits[0] > 0 ? 180. : 0.);
- vol[0] = ((Int_t) (phi / 20)) + 1;
+ // The sector number (0 - 17)
+ // The numbering goes clockwise and starts at y = 0
+ Float_t phi = kRaddeg*TMath::ATan2(hits[0],hits[1]);
+ if (phi < 90.)
+ phi = phi + 270.;
+ else
+ phi = phi - 90.;
+ sec = ((Int_t) (phi / 20));
// The chamber number
- // 1: outer left
- // 2: middle left
- // 3: inner
- // 4: middle right
- // 5: outer right
+ // 0: outer left
+ // 1: middle left
+ // 2: inner
+ // 3: middle right
+ // 4: outer right
iIdChamber = gMC->CurrentVolOffID(1,icChamber);
if (iIdChamber == fIdChamber1)
- vol[1] = (hits[2] < 0 ? 1 : 5);
+ cha = (hits[2] < 0 ? 0 : 4);
else if (iIdChamber == fIdChamber2)
- vol[1] = (hits[2] < 0 ? 2 : 4);
+ cha = (hits[2] < 0 ? 1 : 3);
else if (iIdChamber == fIdChamber3)
- vol[1] = 3;
+ cha = 2;
- // The plane number
- vol[2] = icChamber - TMath::Nint((Float_t) (icChamber / 7)) * 6;
+ // The plane number (0 - 5)
+ pla = icChamber - TMath::Nint((Float_t) (icChamber / 7)) * 6 - 1;
- new(lhits[fNhits++]) AliTRDhit(fIshunt,gAlice->CurrentTrack(),vol,hits);
+ new(lhits[fNhits++]) AliTRDhit(fIshunt
+ ,gAlice->CurrentTrack()
+ ,fGeometry->GetDetector(pla,cha,sec)
+ ,hits);
}
////////////////////////////////////////////////////////
#include "AliTRD.h"
-
+
+//_____________________________________________________________________________
class AliTRDv0 : public AliTRD {
-public:
- AliTRDv0() {}
+ public:
+
+ AliTRDv0() {};
AliTRDv0(const char *name, const char *title);
- virtual ~AliTRDv0() {}
+ ~AliTRDv0() {};
virtual void CreateGeometry();
virtual void CreateMaterials();
- virtual Int_t IsVersion() const { return 0; };
- virtual void Hits2Clusters();
- virtual void SetHits(Int_t ihit = 1) { fHitsOn = ihit; };
+ virtual Int_t IsVersion() const { return 0; };
virtual void StepManager();
virtual void Init();
-
- virtual void SetRphiSigma(Float_t sigma) { fRphiSigma = sigma; };
- virtual void SetRphiDist(Float_t dist) { fRphiDist = dist; };
- virtual Float_t GetRphiSigma() { return fRphiSigma; };
- virtual Float_t GetRphiDist() { return fRphiDist; };
+ virtual void SetHits(Int_t ihit = 1) { fHitsOn = ihit; };
+
+ virtual Int_t GetSensChamber() { return 0; };
+ virtual Int_t GetSensPlane() { return 0; };
+ virtual Int_t GetSensSector() { return 0; };
+
+ protected:
-protected:
Int_t fIdSens; // Sensitive volume identifier
Int_t fIdChamber1; // Driftchamber volume identifier
Int_t fHitsOn; // Used to switch hits on
- Float_t fRphiSigma; // Gaussian position smearing in rphi-direction
- Float_t fRphiDist; // Maximum distnace for non-overlapping cluster
-
ClassDef(AliTRDv0,1) // Transition Radiation Detector version 0 (fast simulator)
};
/*
$Log$
+Revision 1.16.4.1 2000/02/28 18:04:35 cblume
+Change to new hit version, introduce geometry class, and move digitization and clustering to AliTRDdigitizer/AliTRDclusterizerV1
+
+Revision 1.16 1999/11/05 22:50:28 fca
+Do not use Atan, removed from ROOT too
+
Revision 1.15 1999/11/02 17:20:19 fca
initialise nbytes before using it
#include <TVector.h>
#include <TRandom.h>
-#include "AliTRDv1.h"
-#include "AliTRDmatrix.h"
#include "AliRun.h"
#include "AliMC.h"
#include "AliConst.h"
+#include "AliTRDv1.h"
+#include "AliTRDmatrix.h"
+#include "AliTRDgeometry.h"
+
ClassImp(AliTRDv1)
//_____________________________________________________________________________
:AliTRD(name, title)
{
//
- // Standard constructor for Transition Radiation Detector version 2
+ // Standard constructor for Transition Radiation Detector version 1
//
- fIdSens = 0;
-
- fIdChamber1 = 0;
- fIdChamber2 = 0;
- fIdChamber3 = 0;
-
- fSensSelect = 0;
- fSensPlane = 0;
- fSensChamber = 0;
- fSensSector = 0;
+ fIdSens = 0;
- fGasGain = 0;
- fNoise = 0;
- fChipGain = 0;
- fADCoutRange = 0;
- fADCinRange = 0;
- fADCthreshold = 0;
+ fIdChamber1 = 0;
+ fIdChamber2 = 0;
+ fIdChamber3 = 0;
- fDiffusionT = 0;
- fDiffusionL = 0;
-
- fClusMaxThresh = 0;
- fClusSigThresh = 0;
- fClusMethod = 0;
+ fSensSelect = 0;
+ fSensPlane = -1;
+ fSensChamber = -1;
+ fSensSector = -1;
fDeltaE = NULL;
void AliTRDv1::CreateGeometry()
{
//
- // Create the GEANT geometry for the Transition Radiation Detector - Version 2
+ // Create the GEANT geometry for the Transition Radiation Detector - Version 1
// This version covers the full azimuth.
//
void AliTRDv1::CreateMaterials()
{
//
- // Create materials for the Transition Radiation Detector version 2
+ // Create materials for the Transition Radiation Detector version 1
//
AliTRD::CreateMaterials();
}
-//_____________________________________________________________________________
-void AliTRDv1::Diffusion(Float_t driftlength, Float_t *xyz)
-{
- //
- // Applies the diffusion smearing to the position of a single electron
- //
-
- if ((driftlength > 0) &&
- (driftlength < kDrThick)) {
- Float_t driftSqrt = TMath::Sqrt(driftlength);
- Float_t sigmaT = driftSqrt * fDiffusionT;
- Float_t sigmaL = driftSqrt * fDiffusionL;
- xyz[0] = gRandom->Gaus(xyz[0], sigmaL);
- xyz[1] = gRandom->Gaus(xyz[1], sigmaT);
- xyz[2] = gRandom->Gaus(xyz[2], sigmaT);
- }
- else {
- xyz[0] = 0.0;
- xyz[1] = 0.0;
- xyz[2] = 0.0;
- }
-
-}
-
-//_____________________________________________________________________________
-void AliTRDv1::Hits2Digits()
-{
- //
- // Creates TRD digits from hits. This procedure includes the following:
- // - Diffusion
- // - Gas gain including fluctuations
- // - Pad-response (simple Gaussian approximation)
- // - Electronics noise
- // - Electronics gain
- // - Digitization
- // - ADC threshold
- // The corresponding parameter can be adjusted via the various Set-functions.
- // If these parameters are not explicitly set, default values are used (see
- // Init-function).
- // To produce digits from a root-file with TRD-hits use the
- // slowDigitsCreate.C macro.
- //
-
- printf("AliTRDv1::Hits2Digits -- Start creating digits\n");
-
- ///////////////////////////////////////////////////////////////
- // Parameter
- ///////////////////////////////////////////////////////////////
-
- // Converts number of electrons to fC
- const Float_t el2fC = 1.602E-19 * 1.0E15;
-
- ///////////////////////////////////////////////////////////////
-
- Int_t nBytes = 0;
-
- Int_t iRow;
-
- AliTRDhit *TRDhit;
-
- // Get the pointer to the hit tree
- TTree *HitTree = gAlice->TreeH();
- // Get the pointer to the digits tree
- TTree *DigitsTree = gAlice->TreeD();
-
- // Get the number of entries in the hit tree
- // (Number of primary particles creating a hit somewhere)
- Int_t nTrack = (Int_t) HitTree->GetEntries();
-
- Int_t chamBeg = 0;
- Int_t chamEnd = kNcham;
- if (fSensChamber) chamEnd = chamBeg = fSensChamber;
- Int_t planBeg = 0;
- Int_t planEnd = kNplan;
- if (fSensPlane) planEnd = planBeg = fSensPlane;
- Int_t sectBeg = 0;
- Int_t sectEnd = kNsect;
- if (fSensSector) sectEnd = sectBeg = fSensSector;
-
- // Loop through all the chambers
- for (Int_t icham = chamBeg; icham < chamEnd; icham++) {
- for (Int_t iplan = planBeg; iplan < planEnd; iplan++) {
- for (Int_t isect = sectBeg; isect < sectEnd; isect++) {
-
- Int_t nDigits = 0;
-
- printf("AliTRDv1::Hits2Digits -- Digitizing chamber %d, plane %d, sector %d\n"
- ,icham+1,iplan+1,isect+1);
-
- // Create a detector matrix to keep the signal and track numbers
- AliTRDmatrix *matrix = new AliTRDmatrix(fRowMax[iplan][icham][isect]
- ,fColMax[iplan]
- ,fTimeMax
- ,isect+1,icham+1,iplan+1);
-
- // Loop through all entries in the tree
- for (Int_t iTrack = 0; iTrack < nTrack; iTrack++) {
-
- gAlice->ResetHits();
- nBytes += HitTree->GetEvent(iTrack);
-
- // Get the number of hits in the TRD created by this particle
- Int_t nHit = fHits->GetEntriesFast();
-
- // Loop through the TRD hits
- for (Int_t iHit = 0; iHit < nHit; iHit++) {
-
- if (!(TRDhit = (AliTRDhit *) fHits->UncheckedAt(iHit)))
- continue;
-
- Float_t x = TRDhit->fX;
- Float_t y = TRDhit->fY;
- Float_t z = TRDhit->fZ;
- Float_t q = TRDhit->fQ;
- Int_t track = TRDhit->fTrack;
- Int_t plane = TRDhit->fPlane;
- Int_t sector = TRDhit->fSector;
- Int_t chamber = TRDhit->fChamber;
-
- if ((sector != isect+1) ||
- (plane != iplan+1) ||
- (chamber != icham+1))
- continue;
-
- // Rotate the sectors on top of each other
- Float_t phi = 2.0 * kPI / (Float_t) kNsect
- * ((Float_t) sector - 0.5);
- Float_t xRot = -x * TMath::Cos(phi) + y * TMath::Sin(phi);
- Float_t yRot = x * TMath::Sin(phi) + y * TMath::Cos(phi);
- Float_t zRot = z;
-
- // The hit position in pad coordinates (center pad)
- // The pad row (z-direction)
- Int_t rowH = (Int_t) ((zRot - fRow0[iplan][icham][isect]) / fRowPadSize);
- // The pad column (rphi-direction)
- Int_t colH = (Int_t) ((yRot - fCol0[iplan] ) / fColPadSize);
- // The time bucket
- Int_t timeH = (Int_t) ((xRot - fTime0[iplan] ) / fTimeBinSize);
-
- // Array to sum up the signal in a box surrounding the
- // hit postition
- const Int_t timeBox = 5;
- const Int_t colBox = 7;
- const Int_t rowBox = 5;
- Float_t signalSum[rowBox][colBox][timeBox];
- for (iRow = 0; iRow < rowBox; iRow++ ) {
- for (Int_t iCol = 0; iCol < colBox; iCol++ ) {
- for (Int_t iTime = 0; iTime < timeBox; iTime++) {
- signalSum[iRow][iCol][iTime] = 0;
- }
- }
- }
-
- // Loop over all electrons of this hit
- Int_t nEl = (Int_t) q;
- for (Int_t iEl = 0; iEl < nEl; iEl++) {
-
- // Apply the diffusion smearing
- Float_t driftlength = xRot - fTime0[iplan];
- Float_t xyz[3];
- xyz[0] = xRot;
- xyz[1] = yRot;
- xyz[2] = zRot;
- Diffusion(driftlength,xyz);
-
- // At this point absorption effects that depend on the
- // driftlength could be taken into account.
-
- // The electron position and the distance to the hit position
- // in pad units
- // The pad row (z-direction)
- Int_t rowE = (Int_t) ((xyz[2] - fRow0[iplan][icham][isect]) / fRowPadSize);
- Int_t rowD = rowH - rowE;
- // The pad column (rphi-direction)
- Int_t colE = (Int_t) ((xyz[1] - fCol0[iplan] ) / fColPadSize);
- Int_t colD = colH - colE;
- // The time bucket
- Int_t timeE = (Int_t) ((xyz[0] - fTime0[iplan] ) / fTimeBinSize);
- Int_t timeD = timeH - timeE;
-
- // Apply the gas gain including fluctuations
- Int_t signal = (Int_t) (-fGasGain * TMath::Log(gRandom->Rndm()));
-
- // The distance of the electron to the center of the pad
- // in units of pad width
- Float_t dist = (xyz[1] - fCol0[iplan] - (colE + 0.5) * fColPadSize)
- / fColPadSize;
-
- // Sum up the signal in the different pixels
- // and apply the pad response
- Int_t rowIdx = rowD + (Int_t) ( rowBox / 2);
- Int_t colIdx = colD + (Int_t) ( colBox / 2);
- Int_t timeIdx = timeD + (Int_t) (timeBox / 2);
- signalSum[rowIdx][colIdx-1][timeIdx] += PadResponse(dist-1.) * signal;
- signalSum[rowIdx][colIdx ][timeIdx] += PadResponse(dist ) * signal;
- signalSum[rowIdx][colIdx+1][timeIdx] += PadResponse(dist+1.) * signal;
-
- }
-
- // Add the padcluster to the detector matrix
- for (iRow = 0; iRow < rowBox; iRow++ ) {
- for (Int_t iCol = 0; iCol < colBox; iCol++ ) {
- for (Int_t iTime = 0; iTime < timeBox; iTime++) {
-
- Int_t rowB = rowH + iRow - (Int_t) ( rowBox / 2);
- Int_t colB = colH + iCol - (Int_t) ( colBox / 2);
- Int_t timeB = timeH + iTime - (Int_t) (timeBox / 2);
-
- Float_t signalB = signalSum[iRow][iCol][iTime];
- if (signalB > 0.0) {
- matrix->AddSignal(rowB,colB,timeB,signalB);
- if (!(matrix->AddTrack(rowB,colB,timeB,track)))
- printf(" More than three tracks in a pixel!\n");
- }
-
- }
- }
- }
-
- }
-
- }
-
- // Create the hits for this chamber
- for (Int_t iRow = 0; iRow < fRowMax[iplan][icham][isect]; iRow++ ) {
- for (Int_t iCol = 0; iCol < fColMax[iplan] ; iCol++ ) {
- for (Int_t iTime = 0; iTime < fTimeMax ; iTime++) {
-
- Float_t signalAmp = matrix->GetSignal(iRow,iCol,iTime);
-
- // Add the noise
- signalAmp = TMath::Max(gRandom->Gaus(signalAmp,fNoise),(Float_t) 0.0);
- // Convert to fC
- signalAmp *= el2fC;
- // Convert to mV
- signalAmp *= fChipGain;
- // Convert to ADC counts
- Int_t adc = (Int_t) (signalAmp * (fADCoutRange / fADCinRange));
-
- // Apply threshold on ADC value
- if (adc > fADCthreshold) {
-
- Int_t trackSave[3];
- for (Int_t ii = 0; ii < 3; ii++) {
- trackSave[ii] = matrix->GetTrack(iRow,iCol,iTime,ii);
- }
-
- Int_t digits[7];
- digits[0] = matrix->GetSector();
- digits[1] = matrix->GetChamber();
- digits[2] = matrix->GetPlane();
- digits[3] = iRow;
- digits[4] = iCol;
- digits[5] = iTime;
- digits[6] = adc;
-
- // Add this digit to the TClonesArray
- AddDigit(trackSave,digits);
- nDigits++;
-
- }
-
- }
- }
- }
-
- printf("AliTRDv1::Hits2Digits -- Number of digits found: %d\n",nDigits);
-
- // Clean up
- delete matrix;
-
- }
- }
- }
-
- // Fill the digits-tree
- printf("AliTRDv1::Hits2Digits -- Fill the digits tree\n");
- DigitsTree->Fill();
-
-}
-
-//_____________________________________________________________________________
-void AliTRDv1::Digits2Clusters()
-{
-
- //
- // Method to convert AliTRDdigits created by AliTRDv1::Hits2Digits()
- // into AliTRDclusters
- // To produce cluster from a root-file with TRD-digits use the
- // slowClusterCreate.C macro.
- //
-
- Int_t row;
-
- printf("AliTRDv1::Digits2Clusters -- Start creating clusters\n");
-
- AliTRDdigit *TRDdigit;
- TClonesArray *TRDDigits;
-
- // Parameters
- Float_t maxThresh = fClusMaxThresh; // threshold value for maximum
- Float_t signalThresh = fClusSigThresh; // threshold value for digit signal
- Int_t clusteringMethod = fClusMethod; // clustering method option (for testing)
-
- const Float_t epsilon = 0.01; // iteration limit for unfolding procedure
-
- // Get the pointer to the digits tree
- TTree *DigitTree = gAlice->TreeD();
- // Get the pointer to the cluster tree
- TTree *ClusterTree = gAlice->TreeD();
-
- // Get the pointer to the digits container
- TRDDigits = Digits();
-
- Int_t chamBeg = 0;
- Int_t chamEnd = kNcham;
- if (fSensChamber) chamEnd = chamBeg = fSensChamber;
- Int_t planBeg = 0;
- Int_t planEnd = kNplan;
- if (fSensPlane) planEnd = planBeg = fSensPlane;
- Int_t sectBeg = 0;
- Int_t sectEnd = kNsect;
- if (fSensSector) sectEnd = sectBeg = fSensSector;
-
- // Import the digit tree
- gAlice->ResetDigits();
- Int_t nbytes=0;
- nbytes += DigitTree->GetEvent(1);
-
- // Get the number of digits in the detector
- Int_t nTRDDigits = TRDDigits->GetEntriesFast();
-
- // *** Start clustering *** in every chamber
- for (Int_t icham = chamBeg; icham < chamEnd; icham++) {
- for (Int_t iplan = planBeg; iplan < planEnd; iplan++) {
- for (Int_t isect = sectBeg; isect < sectEnd; isect++) {
-
- Int_t nClusters = 0;
- printf("AliTRDv1::Digits2Clusters -- Finding clusters in chamber %d, plane %d, sector %d\n"
- ,icham+1,iplan+1,isect+1);
-
- // Create a detector matrix to keep maxima
- AliTRDmatrix *digitMatrix = new AliTRDmatrix(fRowMax[iplan][icham][isect]
- ,fColMax[iplan]
- ,fTimeMax,isect+1
- ,icham+1,iplan+1);
- // Create a matrix to contain maximum flags
- AliTRDmatrix *maximaMatrix = new AliTRDmatrix(fRowMax[iplan][icham][isect]
- ,fColMax[iplan]
- ,fTimeMax
- ,isect+1,icham+1,iplan+1);
-
- // Loop through all TRD digits
- for (Int_t iTRDDigits = 0; iTRDDigits < nTRDDigits; iTRDDigits++) {
-
- // Get the information for this digit
- TRDdigit = (AliTRDdigit*) TRDDigits->UncheckedAt(iTRDDigits);
- Int_t signal = TRDdigit->fSignal;
- Int_t sector = TRDdigit->fSector;
- Int_t chamber = TRDdigit->fChamber;
- Int_t plane = TRDdigit->fPlane;
- Int_t row = TRDdigit->fRow;
- Int_t col = TRDdigit->fCol;
- Int_t time = TRDdigit->fTime;
-
- Int_t track[3];
- for (Int_t iTrack = 0; iTrack < 3; iTrack++) {
- track[iTrack] = TRDdigit->AliDigit::fTracks[iTrack];
- }
-
- if ((sector != isect+1) ||
- (plane != iplan+1) ||
- (chamber != icham+1))
- continue;
-
- // Fill the detector matrix
- if (signal > signalThresh) {
- digitMatrix->SetSignal(row,col,time,signal);
- for (Int_t iTrack = 0; iTrack < 3; iTrack++) {
- if (track[iTrack] > 0) {
- digitMatrix->AddTrack(row,col,time,track[iTrack]);
- }
- }
- }
-
- }
-
- // Loop chamber and find maxima in digitMatrix
- for (row = 0; row < fRowMax[iplan][icham][isect]; row++) {
- for (Int_t col = 1; col < fColMax[iplan] ; col++) {
- for (Int_t time = 0; time < fTimeMax ; time++) {
-
- if (digitMatrix->GetSignal(row,col,time)
- < digitMatrix->GetSignal(row,col - 1,time)) {
- // really maximum?
- if (col > 1) {
- if (digitMatrix->GetSignal(row,col - 2,time)
- < digitMatrix->GetSignal(row,col - 1,time)) {
- // yes, so set maximum flag
- maximaMatrix->SetSignal(row,col - 1,time,1);
- }
- else maximaMatrix->SetSignal(row,col - 1,time,0);
- }
- }
-
- } // time
- } // col
- } // row
-
- // now check maxima and calculate cluster position
- for (row = 0; row < fRowMax[iplan][icham][isect]; row++) {
- for (Int_t col = 1; col < fColMax[iplan] ; col++) {
- for (Int_t time = 0; time < fTimeMax ; time++) {
-
- if ((maximaMatrix->GetSignal(row,col,time) > 0)
- && (digitMatrix->GetSignal(row,col,time) > maxThresh)) {
-
- Int_t clusters[5] = {0}; // cluster-object data
-
- Float_t ratio = 0; // ratio resulting from unfolding
- Float_t padSignal[5] = {0}; // signals on max and neighbouring pads
- Float_t clusterSignal[3] = {0}; // signals from cluster
- Float_t clusterPos[3] = {0}; // cluster in ALICE refFrame coords
- Float_t clusterPads[6] = {0}; // cluster pad info
-
- // setting values
- clusters[0] = isect+1; // = isect ????
- clusters[1] = icham+1; // = ichamber ????
- clusters[2] = iplan+1; // = iplane ????
- clusters[3] = time;
-
- clusterPads[0] = icham+1;
- clusterPads[1] = isect+1;
- clusterPads[2] = iplan+1;
-
- for (Int_t iPad = 0; iPad < 3; iPad++) {
- clusterSignal[iPad] = digitMatrix->GetSignal(row,col-1+iPad,time);
- }
-
- // neighbouring maximum on right side?
- if (col < fColMax[iplan] - 2) {
- if (maximaMatrix->GetSignal(row,col + 2,time) > 0) {
- for (Int_t iPad = 0; iPad < 5; iPad++) {
- padSignal[iPad] = digitMatrix->GetSignal(row,col-1+iPad,time);
- }
-
- // unfold:
- ratio = Unfold(epsilon, padSignal);
-
- // set signal on overlapping pad to ratio
- clusterSignal[2] *= ratio;
- }
- }
-
- switch (clusteringMethod) {
- case 1:
- // method 1: simply center of mass
- clusterPads[3] = row + 0.5;
- clusterPads[4] = col - 0.5 + (clusterSignal[2] - clusterSignal[0]) /
- (clusterSignal[1] + clusterSignal[2] + clusterSignal[3]);
- clusterPads[5] = time + 0.5;
-
- nClusters++;
- break;
- case 2:
- // method 2: integral gauss fit on 3 pads
- TH1F *hPadCharges = new TH1F("hPadCharges", "Charges on center 3 pads"
- , 5, -1.5, 3.5);
- for (Int_t iCol = -1; iCol <= 3; iCol++) {
- if (clusterSignal[iCol] < 1) clusterSignal[iCol] = 1;
- hPadCharges->Fill(iCol, clusterSignal[iCol]);
- }
- hPadCharges->Fit("gaus", "IQ", "SAME", -0.5, 2.5);
- TF1 *fPadChargeFit = hPadCharges->GetFunction("gaus");
- Double_t colMean = fPadChargeFit->GetParameter(1);
-
- clusterPads[3] = row + 0.5;
- clusterPads[4] = col - 1.5 + colMean;
- clusterPads[5] = time + 0.5;
-
- delete hPadCharges;
-
- nClusters++;
- break;
- }
-
- Float_t clusterCharge = clusterSignal[0]
- + clusterSignal[1]
- + clusterSignal[2];
- clusters[4] = (Int_t)clusterCharge;
-
- Int_t trackSave[3];
- for (Int_t iTrack = 0; iTrack < 3; iTrack++) {
- trackSave[iTrack] = digitMatrix->GetTrack(row,col,time,iTrack);
- }
-
- // Calculate cluster position in ALICE refFrame coords
- // and set array clusterPos to calculated values
- Pads2XYZ(clusterPads, clusterPos);
-
- // Add cluster to reconstruction tree
- AddCluster(trackSave,clusters,clusterPos);
-
- }
-
- } // time
- } // col
- } // row
-
- printf("AliTRDv1::Digits2Clusters -- Number of clusters found: %d\n",nClusters);
-
- delete digitMatrix;
- delete maximaMatrix;
-
- } // isect
- } // iplan
- } // icham
-
- // Fill the cluster-tree
- printf("AliTRDv1::Digits2Clusters -- Total number of clusters found: %d\n"
- ,fClusters->GetEntries());
- printf("AliTRDv1::Digits2Clusters -- Fill the cluster tree\n");
- ClusterTree->Fill();
-
-}
-
//_____________________________________________________________________________
void AliTRDv1::Init()
{
//
// Initialise Transition Radiation Detector after geometry has been built.
- // Includes the default settings of all parameter for the digitization.
//
AliTRD::Init();
- printf(" Slow simulator\n");
- if (fSensPlane)
- printf(" Only plane %d is sensitive\n",fSensPlane);
- if (fSensChamber)
- printf(" Only chamber %d is sensitive\n",fSensChamber);
- if (fSensSector)
- printf(" Only sector %d is sensitive\n",fSensSector);
+ printf(" Slow simulator\n\n");
+ if (fSensSelect) {
+ if (fSensPlane >= 0)
+ printf(" Only plane %d is sensitive\n",fSensPlane);
+ if (fSensChamber >= 0)
+ printf(" Only chamber %d is sensitive\n",fSensChamber);
+ if (fSensSector >= 0)
+ printf(" Only sector %d is sensitive\n",fSensSector);
+ }
+ printf("\n");
// First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
const Float_t kPoti = 12.1;
fIdChamber2 = gMC->VolId("UCIM");
fIdChamber3 = gMC->VolId("UCII");
- // The default parameter for the digitization
- if (!(fGasGain)) fGasGain = 2.0E3;
- if (!(fNoise)) fNoise = 3000.;
- if (!(fChipGain)) fChipGain = 10.;
- if (!(fADCoutRange)) fADCoutRange = 255.;
- if (!(fADCinRange)) fADCinRange = 2000.;
- if (!(fADCthreshold)) fADCthreshold = 1;
-
- // Transverse and longitudinal diffusion coefficients (Xe/Isobutane)
- if (!(fDiffusionT)) fDiffusionT = 0.060;
- if (!(fDiffusionL)) fDiffusionL = 0.017;
-
- // The default parameter for the clustering
- if (!(fClusMaxThresh)) fClusMaxThresh = 5.0;
- if (!(fClusSigThresh)) fClusSigThresh = 2.0;
- if (!(fClusMethod)) fClusMethod = 1;
-
for (Int_t i = 0; i < 80; i++) printf("*");
printf("\n");
}
-//_____________________________________________________________________________
-Float_t AliTRDv1::PadResponse(Float_t x)
-{
- //
- // The pad response for the chevron pads.
- // We use a simple Gaussian approximation which should be good
- // enough for our purpose.
- //
-
- // The parameters for the response function
- const Float_t aa = 0.8872;
- const Float_t bb = -0.00573;
- const Float_t cc = 0.454;
- const Float_t cc2 = cc*cc;
-
- Float_t pr = aa * (bb + TMath::Exp(-x*x / (2. * cc2)));
-
- return (pr);
-
-}
-
//_____________________________________________________________________________
void AliTRDv1::SetSensPlane(Int_t iplane)
{
//
- // Defines the hit-sensitive plane (1-6)
+ // Defines the hit-sensitive plane (0-5)
//
- if ((iplane < 0) || (iplane > 6)) {
+ if ((iplane < 0) || (iplane > 5)) {
printf("Wrong input value: %d\n",iplane);
printf("Use standard setting\n");
- fSensPlane = 0;
- fSensSelect = 0;
+ fSensPlane = -1;
+ fSensSelect = 0;
return;
}
void AliTRDv1::SetSensChamber(Int_t ichamber)
{
//
- // Defines the hit-sensitive chamber (1-5)
+ // Defines the hit-sensitive chamber (0-4)
//
- if ((ichamber < 0) || (ichamber > 5)) {
+ if ((ichamber < 0) || (ichamber > 4)) {
printf("Wrong input value: %d\n",ichamber);
printf("Use standard setting\n");
- fSensChamber = 0;
- fSensSelect = 0;
+ fSensChamber = -1;
+ fSensSelect = 0;
return;
}
void AliTRDv1::SetSensSector(Int_t isector)
{
//
- // Defines the hit-sensitive sector (1-18)
+ // Defines the hit-sensitive sector (0-17)
//
- if ((isector < 0) || (isector > 18)) {
+ if ((isector < 0) || (isector > 17)) {
printf("Wrong input value: %d\n",isector);
printf("Use standard setting\n");
- fSensSector = 0;
- fSensSelect = 0;
+ fSensSector = -1;
+ fSensSelect = 0;
return;
}
void AliTRDv1::StepManager()
{
//
- // Called at every step in the Transition Radiation Detector version 2.
// Slow simulator. Every charged track produces electron cluster as hits
// along its path across the drift volume. The step size is set acording
// to Bethe-Bloch. The energy distribution of the delta electrons follows
Int_t iIdSens, icSens;
Int_t iIdSpace, icSpace;
Int_t iIdChamber, icChamber;
- Int_t vol[3];
- Int_t iPid;
+ Int_t pla = 0;
+ Int_t cha = 0;
+ Int_t sec = 0;
+ Int_t iPdg;
Float_t hits[4];
Float_t random[1];
TLorentzVector pos, mom;
TClonesArray &lhits = *fHits;
- const Double_t kBig = 1.0E+12;
+ const Double_t kBig = 1.0E+12;
// Ionization energy
- const Float_t kWion = 22.04;
+ const Float_t kWion = 22.04;
// Maximum energy for e+ e- g for the step-size calculation
- const Float_t kPTotMax = 0.002;
+ const Float_t kPTotMax = 0.002;
// Plateau value of the energy-loss for electron in xenon
// taken from: Allison + Comb, Ann. Rev. Nucl. Sci. (1980), 30, 253
//const Double_t kPlateau = 1.70;
// the averaged value (26/3/99)
- const Float_t kPlateau = 1.55;
+ const Float_t kPlateau = 1.55;
// dN1/dx|min for the gas mixture (90% Xe + 10% CO2)
- const Float_t kPrim = 48.0;
+ const Float_t kPrim = 48.0;
// First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
- const Float_t kPoti = 12.1;
+ const Float_t kPoti = 12.1;
+
+ // PDG code electron
+ const Int_t pdgElectron = 11;
// Set the maximum step size to a very large number for all
// neutral particles and those outside the driftvolume
hits[2] = pos[2];
hits[3] = qTot;
- // The sector number
- Float_t phi = pos[1] != 0 ? kRaddeg*TMath::ATan2(pos[0],pos[1]) : (pos[0] > 0 ? 180. : 0.);
- vol[0] = ((Int_t) (phi / 20)) + 1;
+ // The sector number (0 - 17)
+ // The numbering goes clockwise and starts at y = 0
+ Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
+ if (phi < 90.)
+ phi = phi + 270.;
+ else
+ phi = phi - 90.;
+ sec = ((Int_t) (phi / 20));
// The chamber number
- // 1: outer left
- // 2: middle left
- // 3: inner
- // 4: middle right
- // 5: outer right
+ // 0: outer left
+ // 1: middle left
+ // 2: inner
+ // 3: middle right
+ // 4: outer right
if (iIdChamber == fIdChamber1)
- vol[1] = (hits[2] < 0 ? 1 : 5);
+ cha = (hits[2] < 0 ? 0 : 4);
else if (iIdChamber == fIdChamber2)
- vol[1] = (hits[2] < 0 ? 2 : 4);
+ cha = (hits[2] < 0 ? 1 : 3);
else if (iIdChamber == fIdChamber3)
- vol[1] = 3;
+ cha = 2;
// The plane number
- vol[2] = icChamber - TMath::Nint((Float_t) (icChamber / 7)) * 6;
+ // The numbering starts at the innermost plane
+ pla = icChamber - TMath::Nint((Float_t) (icChamber / 7)) * 6 - 1;
// Check on selected volumes
Int_t addthishit = 1;
if (fSensSelect) {
- if ((fSensPlane) && (vol[2] != fSensPlane )) addthishit = 0;
- if ((fSensChamber) && (vol[1] != fSensChamber)) addthishit = 0;
- if ((fSensSector) && (vol[0] != fSensSector )) addthishit = 0;
+ if ((fSensPlane) && (pla != fSensPlane )) addthishit = 0;
+ if ((fSensChamber) && (cha != fSensChamber)) addthishit = 0;
+ if ((fSensSector) && (sec != fSensSector )) addthishit = 0;
}
// Add this hit
if (addthishit) {
- new(lhits[fNhits++]) AliTRDhit(fIshunt,gAlice->CurrentTrack(),vol,hits);
+ new(lhits[fNhits++]) AliTRDhit(fIshunt
+ ,gAlice->CurrentTrack()
+ ,fGeometry->GetDetector(pla,cha,sec)
+ ,hits);
// The energy loss according to Bethe Bloch
gMC->TrackMomentum(mom);
pTot = mom.Rho();
- iPid = gMC->TrackPid();
- if ( (iPid > 3) ||
- ((iPid <= 3) && (pTot < kPTotMax))) {
+ iPdg = TMath::Abs(gMC->TrackPid());
+ if ( (iPdg != pdgElectron) ||
+ ((iPdg == pdgElectron) && (pTot < kPTotMax))) {
aMass = gMC->TrackMass();
betaGamma = pTot / aMass;
pp = kPrim * BetheBloch(betaGamma);
return dnde;
}
-
-//_____________________________________________________________________________
-void AliTRDv1::Pads2XYZ(Float_t *pads, Float_t *pos)
-{
- // Method to convert pad coordinates (row,col,time)
- // into ALICE reference frame coordinates (x,y,z)
-
- Int_t chamber = (Int_t) pads[0]; // chamber info (1-5)
- Int_t sector = (Int_t) pads[1]; // sector info (1-18)
- Int_t plane = (Int_t) pads[2]; // plane info (1-6)
-
- Int_t icham = chamber - 1; // chamber info (0-4)
- Int_t isect = sector - 1; // sector info (0-17)
- Int_t iplan = plane - 1; // plane info (0-5)
-
- Float_t padRow = pads[3]; // Pad Row position
- Float_t padCol = pads[4]; // Pad Column position
- Float_t timeSlice = pads[5]; // Time "position"
-
- // calculate (x,y) position in rotated chamber
- Float_t yRot = fCol0[iplan] + padCol * fColPadSize;
- Float_t xRot = fTime0[iplan] + timeSlice * fTimeBinSize;
- // calculate z-position:
- Float_t z = fRow0[iplan][icham][isect] + padRow * fRowPadSize;
-
- /**
- rotate chamber back to original position
- 1. mirror at y-axis, 2. rotate back to position (-phi)
- / cos(phi) -sin(phi) \ / -1 0 \ / -cos(phi) -sin(phi) \
- \ sin(phi) cos(phi) / * \ 0 1 / = \ -sin(phi) cos(phi) /
- **/
- //Float_t phi = 2*kPI / kNsect * ((Float_t) sector - 0.5);
- //Float_t x = -xRot * TMath::Cos(phi) - yRot * TMath::Sin(phi);
- //Float_t y = -xRot * TMath::Sin(phi) + yRot * TMath::Cos(phi);
- Float_t phi = 2*kPI / kNsect * ((Float_t) sector - 0.5);
- Float_t x = -xRot * TMath::Cos(phi) + yRot * TMath::Sin(phi);
- Float_t y = xRot * TMath::Sin(phi) + yRot * TMath::Cos(phi);
-
- // Setting values
- pos[0] = x;
- pos[1] = y;
- pos[2] = z;
-
-}
-
-//_____________________________________________________________________________
-Float_t AliTRDv1::Unfold(Float_t eps, Float_t* padSignal)
-{
- // Method to unfold neighbouring maxima.
- // The charge ratio on the overlapping pad is calculated
- // until there is no more change within the range given by eps.
- // The resulting ratio is then returned to the calling method.
-
- Int_t itStep = 0; // count iteration steps
-
- Float_t ratio = 0.5; // start value for ratio
- Float_t prevRatio = 0; // store previous ratio
-
- Float_t newLeftSignal[3] = {0}; // array to store left cluster signal
- Float_t newRightSignal[3] = {0}; // array to store right cluster signal
-
- // start iteration:
- while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
-
- itStep++;
- prevRatio = ratio;
-
- // cluster position according to charge ratio
- Float_t maxLeft = (ratio*padSignal[2] - padSignal[0]) /
- (padSignal[0] + padSignal[1] + ratio*padSignal[2]);
- Float_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2]) /
- ((1-ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
-
- // set cluster charge ratio
- Float_t ampLeft = padSignal[1];
- Float_t ampRight = padSignal[3];
-
- // apply pad response to parameters
- newLeftSignal[0] = ampLeft*PadResponse(-1 - maxLeft);
- newLeftSignal[1] = ampLeft*PadResponse( 0 - maxLeft);
- newLeftSignal[2] = ampLeft*PadResponse( 1 - maxLeft);
-
- newRightSignal[0] = ampRight*PadResponse(-1 - maxRight);
- newRightSignal[1] = ampRight*PadResponse( 0 - maxRight);
- newRightSignal[2] = ampRight*PadResponse( 1 - maxRight);
-
- // calculate new overlapping ratio
- ratio = newLeftSignal[2]/(newLeftSignal[2] + newRightSignal[0]);
-
- }
-
- return ratio;
-
-}
-
////////////////////////////////////////////////////////
// Manager and hits classes for set:TRD version 1 //
////////////////////////////////////////////////////////
-
-#include <TF1.h>
-#include "AliTRD.h"
// Energy spectrum of the delta-rays
Double_t Ermilova(Double_t *x, Double_t *par);
+
+#include <TF1.h>
+
+#include "AliTRD.h"
+//_____________________________________________________________________________
class AliTRDv1 : public AliTRD {
-public:
- AliTRDv1() {}
+ public:
+
+ AliTRDv1() {};
AliTRDv1(const char *name, const char *title);
- virtual ~AliTRDv1();
+ ~AliTRDv1();
virtual void CreateGeometry();
virtual void CreateMaterials();
virtual Int_t IsVersion() const { return 1; };
virtual void StepManager();
+ virtual void Init();
+
virtual void SetSensPlane(Int_t iplane = 0);
virtual void SetSensChamber(Int_t ichamber = 0);
virtual void SetSensSector(Int_t isector = 0);
- virtual void Init();
- virtual void Hits2Digits();
- virtual void Digits2Clusters();
-
- virtual void SetGasGain(Float_t gasgain) { fGasGain = gasgain; };
- virtual void SetNoise(Float_t noise) { fNoise = noise; };
- virtual void SetChipGain(Float_t chipgain) { fChipGain = chipgain; };
- virtual void SetADCoutRange(Float_t range) { fADCoutRange = range; };
- virtual void SetADCinRange(Float_t range) { fADCinRange = range; };
- virtual void SetADCthreshold(Int_t thresh) { fADCthreshold = thresh; };
- virtual void SetDiffusionT(Float_t diff) { fDiffusionT = diff; };
- virtual void SetDiffusionL(Float_t diff) { fDiffusionL = diff; };
-
- virtual void SetClusMaxThresh(Float_t thresh) { fClusMaxThresh = thresh; };
- virtual void SetClusSigThresh(Float_t thresh) { fClusSigThresh = thresh; };
- virtual void SetClusMethod(Int_t meth) { fClusMethod = meth; };
-
- virtual Float_t GetGasGain() { return fGasGain; };
- virtual Float_t GetNoise() { return fNoise; };
- virtual Float_t GetChipGain() { return fChipGain; };
- virtual Float_t GetADCoutRange() { return fADCoutRange; };
- virtual Float_t GetADCinRange() { return fADCinRange; };
- virtual Int_t GetADCthreshold() { return fADCthreshold; };
- virtual Float_t GetDiffusionT() { return fDiffusionT; };
- virtual Float_t GetDiffusionL() { return fDiffusionL; };
-
- virtual Float_t GetClusMaxThresh() { return fClusMaxThresh; };
- virtual Float_t GetClusSigThresh() { return fClusSigThresh; };
- virtual Int_t GetClusMethod() { return fClusMethod; };
-
-protected:
+
+ virtual Int_t GetSensPlane() { return fSensPlane; };
+ virtual Int_t GetSensChamber() { return fSensChamber; };
+ virtual Int_t GetSensSector() { return fSensSector; };
+
+ protected:
+
Int_t fIdSens; // Sensitive volume identifier
Int_t fIdChamber1; // Driftchamber volume identifier
Int_t fSensChamber; // Sensitive detector chamber
Int_t fSensSector; // Sensitive detector sector
- Float_t fGasGain; // Gas gain
- Float_t fNoise; // Electronics noise
- Float_t fChipGain; // Electronics gain
- Float_t fADCoutRange; // ADC output range (number of channels)
- Float_t fADCinRange; // ADC input range (input charge)
- Int_t fADCthreshold; // ADC threshold in ADC channel
- Float_t fDiffusionT; // Diffusion in transverse direction
- Float_t fDiffusionL; // Diffusion in logitudinal direction
-
- Float_t fClusMaxThresh; // Threshold value for cluster maximum
- Float_t fClusSigThresh; // Threshold value for cluster signal
- Int_t fClusMethod; // Clustering method
+ private:
-private:
virtual Double_t BetheBloch(Double_t bg);
- virtual void Diffusion(Float_t driftlength, Float_t *xyz);
- virtual Float_t PadResponse(Float_t x);
- virtual void Pads2XYZ(Float_t *pads, Float_t *pos);
- virtual Float_t Unfold(Float_t eps, Float_t *padSignal);
TF1 *fDeltaE; // Energy distribution of the delta-electrons
# C++ sources
-SRCS = AliTRD.cxx AliTRDv0.cxx AliTRDv1.cxx \
- AliTRDpixel.cxx AliTRDmatrix.cxx
+SRCS = AliTRD.cxx AliTRDv0.cxx AliTRDv1.cxx \
+ AliTRDpixel.cxx AliTRDmatrix.cxx \
+ AliTRDgeometry.cxx AliTRDgeometryFull.cxx \
+ AliTRDgeometryHole.cxx AliTRDdigitizer.cxx \
+ AliTRDclusterizer.cxx AliTRDclusterizerV0.cxx \
+ AliTRDclusterizerV1.cxx AliTRDrecPoint.cxx \
+ AliTRDsegmentArray.cxx AliTRDdataArray.cxx \
+ AliTRDsegmentID.cxx AliTRDsegmentArrayBase.cxx \
+ AliTRDarrayI.cxx
# C++ Headers
#pragma link C++ class AliTRDcluster;
#pragma link C++ class AliTRDpixel;
#pragma link C++ class AliTRDmatrix;
+#pragma link C++ class AliTRDgeometry;
+#pragma link C++ class AliTRDgeometryFull;
+#pragma link C++ class AliTRDgeometryHole;
+#pragma link C++ class AliTRDdigitizer;
+#pragma link C++ class AliTRDclusterizer;
+#pragma link C++ class AliTRDclusterizerV0;
+#pragma link C++ class AliTRDclusterizerV1;
+#pragma link C++ class AliTRDrecPoint;
+#pragma link C++ class AliTRDsegmentArray;
+#pragma link C++ class AliTRDdataArray;
+
+#pragma link C++ class AliTRDsegmentID;
+#pragma link C++ class AliTRDsegmentArrayBase;
+#pragma link C++ class AliTRDarrayI;
#endif
/////////////////////////////////////////////////////////////////////////
//
-// Creates cluster from the digit information. An additional hit-tree
-// is added to the input file.
+// Creates cluster from the digit information.
//
/////////////////////////////////////////////////////////////////////////
if (gClassTable->GetID("AliRun") < 0) {
gROOT->LoadMacro("loadlibs.C");
loadlibs();
+ cout << "Loaded shared libraries" << endl;
}
// Input (and output) file name
Char_t *alifile = "galice_c_v1.root";
- // Event number
- Int_t nEvent = 0;
+ // Create the clusterizer
+ AliTRDclusterizerV1 *Clusterizer =
+ new AliTRDclusterizerV1("clusterizer","slow clusterizer class");
- // Connect the AliRoot file containing Geometry, Kine, Hits, and Digits
- TFile *gafl = (TFile*) gROOT->GetListOfFiles()->FindObject(alifile);
- if (!gafl) {
- cout << "Open the ALIROOT-file " << alifile << endl;
- gafl = new TFile(alifile,"UPDATE");
- }
- else {
- cout << alifile << " is already open" << endl;
- }
-
- // Get AliRun object from file or create it if not on file
- if (!gAlice) {
- gAlice = (AliRun*) gafl->Get("gAlice");
- if (gAlice)
- cout << "AliRun object found on file" << endl;
- else
- gAlice = new AliRun("gAlice","Alice test program");
- }
+ // Open the AliRoot file
+ Clusterizer->Open(alifile);
- // Import the Trees for the event nEvent in the file
- Int_t nparticles = gAlice->GetEvent(nEvent);
- if (nparticles <= 0) break;
+ // Load the digits
+ Clusterizer->ReadDigits();
- // Get the pointer to the detector classes
- AliTRDv1 *TRD = (AliTRDv1*) gAlice->GetDetector("TRD");
+ // Find the cluster
+ Clusterizer->MakeCluster();
- // Create the clusters
- TRD->Digits2Clusters();
+ // Write the cluster into the input file
+ Clusterizer->WriteCluster();
- // Write the new tree into the input file
- cout << "Entries in digits tree = " << gAlice->TreeD()->GetEntries() << endl;
- Char_t treeName[7];
- sprintf(treeName,"TreeD%d",nEvent);
- gAlice->TreeD()->Write(treeName);
+ // Save the clusterizer class in the AliROOT file
+ Clusterizer->Write();
}
}
// Input file name
-//Char_t *alifile = "galice_d_v1.root";
- Char_t *alifile = "galice_c_v1.root";
+ Char_t *alifile = "galice_d_v1.root";
// Event number
Int_t nEvent = 0;
// Define the objects
- AliTRDv1 *TRD;
- TClonesArray *TRDDigits;
- AliTRDdigit *OneTRDDigit;
+ AliTRDv1 *TRD;
+ AliTRDgeometry *TRDgeometry;
// Connect the AliRoot file containing Geometry, Kine, Hits, and Digits
TFile *gafl = (TFile*) gROOT->GetListOfFiles()->FindObject(alifile);
}
// Get AliRun object from file or create it if not on file
- if (!gAlice) {
- gAlice = (AliRun*) gafl->Get("gAlice");
- if (gAlice)
- cout << "AliRun object found on file" << endl;
- else
- gAlice = new AliRun("gAlice","Alice test program");
- }
+ gAlice = (AliRun*) gafl->Get("gAlice");
+ if (gAlice)
+ cout << "AliRun object found on file" << endl;
+ else
+ gAlice = new AliRun("gAlice","Alice test program");
// Import the Trees for the event nEvent in the file
Int_t nparticles = gAlice->GetEvent(nEvent);
if (nparticles <= 0) break;
- // Get the pointer to the hit-tree
- TTree *DigitsTree = gAlice->TreeD();
-
// Get the pointer to the detector classes
TRD = (AliTRDv1*) gAlice->GetDetector("TRD");
- // Get the pointer to the hit container
- if (TRD) TRDDigits = TRD->Digits();
+ // Get the pointer to the digits container and the geometry
+ if (TRD) {
+ TRDgeometry = TRD->GetGeometry();
+ }
+ else {
+ cout << "Cannot find the geometry" << endl;
+ break;
+ }
- DigitsTree->GetBranch("TRD")->SetAddress(&TRDDigits);
+ // Define the segment array for the digits
+ AliTRDsegmentArray *DigitsArray = new AliTRDsegmentArray(540);
- // Define the detector matrix for one chamber (Sector 6, Chamber 3, Plane 1)
- const Int_t iSec = 6;
+ // Load the digits from the tree
+ DigitsArray->LoadArray("TRDdigits");
+
+ // Define the detector matrix for one chamber
+ const Int_t iSec = 13;
const Int_t iCha = 3;
- const Int_t iPla = 1;
- Int_t rowMax = TRD->GetRowMax(iPla,iCha,iSec);
- Int_t colMax = TRD->GetColMax(iPla);
- Int_t timeMax = TRD->GetTimeMax();
- cout << " rowMax = " << rowMax
- << " colMax = " << colMax
- << " timeMax = " << timeMax << endl;
- AliTRDmatrix *TRDMatrix = new AliTRDmatrix(rowMax,colMax,timeMax,iSec,iCha,iPla);
-
- Int_t nEntries = DigitsTree->GetEntries();
- cout << "Number of entries in digits tree = " << nEntries << endl;
-
- // Loop through all entries in the tree
- Int_t nbytes;
- for (Int_t iEntry = 0; iEntry < nEntries; iEntry++) {
-
- cout << "iEntry = " << iEntry << endl;
-
- // Import the tree
- gAlice->ResetDigits();
- nbytes += DigitsTree->GetEvent(iEntry);
-
- // Get the number of digits in the detector
- Int_t nTRDDigits = TRDDigits->GetEntriesFast();
- cout << " nTRDDigits = " << nTRDDigits << endl;
-
- // Loop through all TRD digits
- for (Int_t iTRDDigits = 0; iTRDDigits < nTRDDigits; iTRDDigits++) {
-
- // Get the information for this digit
- OneTRDDigit = (AliTRDdigit*) TRDDigits->UncheckedAt(iTRDDigits);
- Int_t signal = OneTRDDigit->fSignal;
- Int_t sector = OneTRDDigit->fSector;
- Int_t chamber = OneTRDDigit->fChamber;
- Int_t plane = OneTRDDigit->fPlane;
- Int_t row = OneTRDDigit->fRow;
- Int_t col = OneTRDDigit->fCol;
- Int_t time = OneTRDDigit->fTime;
-
- // Fill the detector matrix
- if (signal > 1) {
- TRDMatrix->SetSignal(row,col,time,signal);
- }
+ const Int_t iPla = 3;
+ Int_t rowMax = TRDgeometry->GetRowMax(iPla,iCha,iSec);
+ Int_t colMax = TRDgeometry->GetColMax(iPla);
+ Int_t timeMax = TRDgeometry->GetTimeMax();
+ cout << "Geometry: rowMax = " << rowMax
+ << " colMax = " << colMax
+ << " timeMax = " << timeMax << endl;
+ AliTRDmatrix *TRDmatrix = new AliTRDmatrix(rowMax,colMax,timeMax,iSec,iCha,iPla);
+
+ // Get the digits for this detector
+ Int_t iDet = TRDgeometry->GetDetector(iPla,iCha,iSec);
+ AliTRDdataArray *Digits = (AliTRDdataArray *) DigitsArray->At(iDet);
+ Digits->Dump();
+ // Expand the digits array
+ //Digits->Expand();
+
+ //Float_t signal = Digits->GetData(0,0,29);
+
+ // Loop through the detector pixel
+ for (Int_t time = 0; time < timeMax; time++) {
+ for (Int_t col = 0; col < colMax; col++) {
+ for (Int_t row = 0; row < rowMax; row++) {
+
+ Float_t signal = Digits->GetData(row,col,time);
+ if (signal != 0) {
+ }
+ TRDmatrix->SetSignal(row,col,time,signal);
+ }
}
-
}
// Display the detector matrix
- TRDMatrix->Draw();
- TRDMatrix->DrawRow(18);
- TRDMatrix->DrawCol(58);
- TRDMatrix->DrawTime(20);
+ TRDmatrix->Draw();
+ TRDmatrix->DrawRow(18);
+ TRDmatrix->DrawCol(58);
+ TRDmatrix->DrawTime(20);
}
/////////////////////////////////////////////////////////////////////////
//
-// Creates the digits from the hit information. An additional hit-tree
-// is added to the input file.
+// Creates the digits from the hit information.
//
/////////////////////////////////////////////////////////////////////////
if (gClassTable->GetID("AliRun") < 0) {
gROOT->LoadMacro("loadlibs.C");
loadlibs();
+ cout << "Loaded shared libraries" << endl;
}
// Input (and output) file name
Char_t *alifile = "galice_d_v1.root";
- // Event number
- Int_t nEvent = 0;
+ // Create the TRD digitzer
+ AliTRDdigitizer *Digitizer = new AliTRDdigitizer("digitizer","Digitizer class");
- // Connect the AliRoot file containing Geometry, Kine, and Hits
- TFile *gafl = (TFile*) gROOT->GetListOfFiles()->FindObject(alifile);
- if (!gafl) {
- cout << "Open the ALIROOT-file " << alifile << endl;
- gafl = new TFile(alifile,"UPDATE");
- }
- else {
- cout << alifile << " is already open" << endl;
- }
-
- // Get AliRun object from file or create it if not on file
- if (!gAlice) {
- gAlice = (AliRun*) gafl->Get("gAlice");
- if (gAlice)
- cout << "AliRun object found on file" << endl;
- else
- gAlice = new AliRun("gAlice","Alice test program");
- }
+ // Set the parameter
+ Digitizer->SetDiffusion();
+ Digitizer->SetExB();
+ //Digitizer->SetElAttach();
+ //Digitizer->SetAttachProb();
- // Import the Trees for the event nEvent in the file
- Int_t nparticles = gAlice->GetEvent(nEvent);
- if (nparticles <= 0) break;
+ // Open the AliRoot file
+ Digitizer->Open(alifile);
- // Get the pointer to the detector class
- AliTRDv1 *TRD = (AliTRDv1*) gAlice->GetDetector("TRD");
+ // Create the digits
+ Digitizer->MakeDigits();
- // Create the digits and fill the digits-tree
- TRD->Hits2Digits();
+ // Write the digits into the input file
+ Digitizer->WriteDigits();
- // Write the new tree into the input file
- cout << "Entries in digits tree = " << gAlice->TreeD()->GetEntries() << endl;
- Char_t treeName[7];
- sprintf(treeName,"TreeD%d",nEvent);
- gAlice->TreeD()->Write(treeName);
+ // Save the digitizer class in the AliROOT file
+ Digitizer->Write();
}