/**************************************************************************
* 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. *
**************************************************************************/
/*
$Log$
Revision 1.54.4.3 2002/10/11 08:34:48 hristov
Updating VirtualMC to v3-09-02
Revision 1.62 2002/09/23 09:22:56 hristov
The address of the TrackReferences is set (M.Ivanov)
Revision 1.61 2002/09/10 07:06:42 kowal2
Corrected for the memory leak. Thanks to J. Chudoba and M. Ivanov
Revision 1.60 2002/06/12 14:56:56 kowal2
Added track length to the reference hits
Revision 1.59 2002/06/05 15:37:31 kowal2
Added cross-talk from the wires beyond the first and the last rows
Revision 1.58 2002/05/27 14:33:14 hristov
The new class AliTrackReference used (M.Ivanov)
Revision 1.57 2002/05/07 17:23:11 kowal2
Linear gain inefficiency instead of the step one at the wire edges.
Revision 1.56 2002/04/04 16:26:33 kowal2
Digits (Sdigits) go to separate files now.
Revision 1.55 2002/03/29 06:57:45 kowal2
Restored backward compatibility to use the hits from Dec. 2000 production.
Revision 1.54 2002/03/18 17:59:13 kowal2
Chnges in the pad geometry - 3 pad lengths introduced.
Revision 1.53 2002/02/25 11:02:56 kowal2
Changes towards speeding up the code. Thanks to Marian Ivanov.
Revision 1.52 2002/02/18 09:26:09 kowal2
Removed compiler warning
Revision 1.51 2002/01/21 17:13:21 kowal2
New track hits using root containers. Setting active sectors added.
Revision 1.50 2001/12/06 14:16:19 kowal2
meaningfull printouts
Revision 1.49 2001/11/30 11:55:37 hristov
Noise table created in Hits2SDigits (M.Ivanov)
Revision 1.48 2001/11/24 16:10:21 kowal2
Faster algorithms.
Revision 1.47 2001/11/19 10:25:34 kowal2
Nearest integer instead of integer when converting to ADC counts
Revision 1.46 2001/11/07 06:47:12 kowal2
Removed printouts
Revision 1.45 2001/11/03 13:33:48 kowal2
Updated algorithms in Hits2SDigits, SDigits2Digits,
Hits2ExactClusters.
Added method Merge
Revision 1.44 2001/08/30 09:28:48 hristov
TTree names are explicitly set via SetName(name) and then Write() is called
Revision 1.43 2001/07/28 12:02:54 hristov
Branch split level set to 99
Revision 1.42 2001/07/28 11:38:52 hristov
Loop variable declared once
Revision 1.41 2001/07/28 10:53:50 hristov
Digitisation done according to the general scheme (M.Ivanov)
Revision 1.40 2001/07/27 13:03:14 hristov
Default Branch split level set to 99
Revision 1.39 2001/07/26 09:09:34 kowal2
Hits2Reco method added
Revision 1.38 2001/07/20 14:32:43 kowal2
Processing of many events possible now
Revision 1.37 2001/06/12 07:17:18 kowal2
Hits2SDigits method implemented (summable digits)
Revision 1.36 2001/05/16 14:57:25 alibrary
New files for folders and Stack
Revision 1.35 2001/05/08 16:02:22 kowal2
Updated material specifications
Revision 1.34 2001/05/08 15:00:15 hristov
Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
Revision 1.33 2001/04/03 12:40:43 kowal2
Removed printouts
Revision 1.32 2001/03/12 17:47:36 hristov
Changes needed on Sun with CC 5.0
Revision 1.31 2001/03/12 08:21:50 kowal2
Corrected C++ bug in the material definitions
Revision 1.30 2001/03/01 17:34:47 kowal2
Correction due to the accuracy problem
Revision 1.29 2001/02/28 16:34:40 kowal2
Protection against nonphysical values of the avalanche size,
10**6 is the maximum
Revision 1.28 2001/01/26 19:57:19 hristov
Major upgrade of AliRoot code
Revision 1.27 2001/01/13 17:29:33 kowal2
Sun compiler correction
Revision 1.26 2001/01/10 07:59:43 kowal2
Corrections to load points from the noncompressed hits.
Revision 1.25 2000/11/02 07:25:31 kowal2
Changes due to the new hit structure.
Memory leak removed.
Revision 1.24 2000/10/05 16:06:09 kowal2
Forward declarations. Changes due to a new class AliComplexCluster.
Revision 1.23 2000/10/02 21:28:18 fca
Removal of useless dependecies via forward declarations
Revision 1.22 2000/07/10 20:57:39 hristov
Update of TPC code and macros by M.Kowalski
Revision 1.19.2.4 2000/06/26 07:39:42 kowal2
Changes to obey the coding rules
Revision 1.19.2.3 2000/06/25 08:38:41 kowal2
Splitted from AliTPCtracking
Revision 1.19.2.2 2000/06/16 12:59:28 kowal2
Changed parameter settings
Revision 1.19.2.1 2000/06/09 07:15:07 kowal2
Defaults loaded automatically (hard-wired)
Optional parameters can be set via macro called in the constructor
Revision 1.19 2000/04/18 19:00:59 fca
Small bug fixes to TPC files
Revision 1.18 2000/04/17 09:37:33 kowal2
removed obsolete AliTPCDigitsDisplay.C
Revision 1.17.2.2 2000/04/10 08:15:12 kowal2
New, experimental data structure from M. Ivanov
New tracking algorithm
Different pad geometry for different sectors
Digitization rewritten
Revision 1.17.2.1 2000/04/10 07:56:53 kowal2
Not used anymore - removed
Revision 1.17 2000/01/19 17:17:30 fca
Introducing a list of lists of hits -- more hits allowed for detector now
Revision 1.16 1999/11/05 09:29:23 fca
Accept only signals > 0
Revision 1.15 1999/10/08 06:26:53 fca
Removed ClustersIndex - not used anymore
Revision 1.14 1999/09/29 09:24:33 fca
Introduction of the Copyright and cvs Log
*/
///////////////////////////////////////////////////////////////////////////////
// //
// Time Projection Chamber //
// This class contains the basic functions for the Time Projection Chamber //
// detector. Functions specific to one particular geometry are //
// contained in the derived classes //
// //
//Begin_Html
/*
*/
//End_Html
// //
// //
///////////////////////////////////////////////////////////////////////////////
//
#include
#include
#include
#include
#include
#include
#include
#include
#include "TParticle.h"
#include "AliTPC.h"
#include
#include
#include
#include "AliRun.h"
#include
#include
#include
#include "AliMC.h"
#include "AliMagF.h"
#include "AliTrackReference.h"
#include "AliTPCParamSR.h"
#include "AliTPCPRF2D.h"
#include "AliTPCRF1D.h"
#include "AliDigits.h"
#include "AliSimDigits.h"
#include "AliTPCTrackHits.h"
#include "AliTPCTrackHitsV2.h"
#include "AliPoints.h"
#include "AliArrayBranch.h"
#include "AliTPCDigitsArray.h"
#include "AliComplexCluster.h"
#include "AliClusters.h"
#include "AliTPCClustersRow.h"
#include "AliTPCClustersArray.h"
#include "AliTPCcluster.h"
#include "AliTPCclusterer.h"
#include "AliTPCtracker.h"
#include
#include
ClassImp(AliTPC)
//_____________________________________________________________________________
// helper class for fast matrix and vector manipulation - no range checking
// origin - Marian Ivanov
class AliTPCFastMatrix : public TMatrix {
public :
AliTPCFastMatrix(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb);
inline Float_t & UncheckedAt(Int_t rown, Int_t coln) const {return (fIndex[coln])[rown];} //fast acces
inline Float_t UncheckedAtFast(Int_t rown, Int_t coln) const {return (fIndex[coln])[rown];} //fast acces
};
AliTPCFastMatrix::AliTPCFastMatrix(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb):
TMatrix(row_lwb, row_upb,col_lwb,col_upb)
{
};
//_____________________________________________________________________________
class AliTPCFastVector : public TVector {
public :
AliTPCFastVector(Int_t size);
virtual ~AliTPCFastVector(){;}
inline Float_t & UncheckedAt(Int_t index) const {return fElements[index];} //fast acces
};
AliTPCFastVector::AliTPCFastVector(Int_t size):TVector(size){
};
//_____________________________________________________________________________
AliTPC::AliTPC()
{
//
// Default constructor
//
fIshunt = 0;
fHits = 0;
fDigits = 0;
fNsectors = 0;
fDigitsArray = 0;
fClustersArray = 0;
fDefaults = 0;
fTrackHits = 0;
fTrackHitsOld = 0;
fHitType = 2; //default CONTAINERS - based on ROOT structure
fTPCParam = 0;
fNoiseTable = 0;
fActiveSectors =0;
}
//_____________________________________________________________________________
AliTPC::AliTPC(const char *name, const char *title)
: AliDetector(name,title)
{
//
// Standard constructor
//
//
// Initialise arrays of hits and digits
fHits = new TClonesArray("AliTPChit", 176);
gAlice->AddHitList(fHits);
fDigitsArray = 0;
fClustersArray= 0;
fDefaults = 0;
//
fTrackHits = new AliTPCTrackHitsV2;
fTrackHits->SetHitPrecision(0.002);
fTrackHits->SetStepPrecision(0.003);
fTrackHits->SetMaxDistance(100);
fTrackHitsOld = new AliTPCTrackHits; //MI - 13.09.2000
fTrackHitsOld->SetHitPrecision(0.002);
fTrackHitsOld->SetStepPrecision(0.003);
fTrackHitsOld->SetMaxDistance(100);
fNoiseTable =0;
fHitType = 2;
fActiveSectors = 0;
//
// Initialise counters
fNsectors = 0;
//
fIshunt = 0;
//
// Initialise color attributes
SetMarkerColor(kYellow);
//
// Set TPC parameters
//
if (!strcmp(title,"Default")) {
fTPCParam = new AliTPCParamSR;
} else {
cerr<<"AliTPC warning: in Config.C you must set non-default parameters\n";
fTPCParam=0;
}
}
//_____________________________________________________________________________
AliTPC::~AliTPC()
{
//
// TPC destructor
//
fIshunt = 0;
delete fHits;
delete fDigits;
delete fTPCParam;
delete fTrackHits; //MI 15.09.2000
delete fTrackHitsOld; //MI 10.12.2001
if (fNoiseTable) delete [] fNoiseTable;
}
//_____________________________________________________________________________
void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
{
//
// Add a hit to the list
//
// TClonesArray &lhits = *fHits;
// new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
if (fHitType&1){
TClonesArray &lhits = *fHits;
new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
}
if (fHitType>1)
AddHit2(track,vol,hits);
}
void AliTPC::AddTrackReference(Int_t lab, TLorentzVector p, TLorentzVector x, Float_t length){
//
// add a trackrefernce to the list
if (!fTrackReferences) {
cerr<<"Container trackrefernce not active\n";
return;
}
Int_t nref = fTrackReferences->GetEntriesFast();
TClonesArray &lref = *fTrackReferences;
AliTrackReference * ref = new(lref[nref]) AliTrackReference;
ref->SetMomentum(p[0],p[1],p[2]);
ref->SetPosition(x[0],x[1],x[2]);
ref->SetTrack(lab);
ref->SetLength(length);
}
//_____________________________________________________________________________
void AliTPC::BuildGeometry()
{
//
// Build TPC ROOT TNode geometry for the event display
//
TNode *nNode, *nTop;
TTUBS *tubs;
Int_t i;
const int kColorTPC=19;
char name[5], title[25];
const Double_t kDegrad=TMath::Pi()/180;
const Double_t kRaddeg=180./TMath::Pi();
Float_t innerOpenAngle = fTPCParam->GetInnerAngle();
Float_t outerOpenAngle = fTPCParam->GetOuterAngle();
Float_t innerAngleShift = fTPCParam->GetInnerAngleShift();
Float_t outerAngleShift = fTPCParam->GetOuterAngleShift();
Int_t nLo = fTPCParam->GetNInnerSector()/2;
Int_t nHi = fTPCParam->GetNOuterSector()/2;
const Double_t kloAng = (Double_t)TMath::Nint(innerOpenAngle*kRaddeg);
const Double_t khiAng = (Double_t)TMath::Nint(outerOpenAngle*kRaddeg);
const Double_t kloAngSh = (Double_t)TMath::Nint(innerAngleShift*kRaddeg);
const Double_t khiAngSh = (Double_t)TMath::Nint(outerAngleShift*kRaddeg);
const Double_t kloCorr = 1/TMath::Cos(0.5*kloAng*kDegrad);
const Double_t khiCorr = 1/TMath::Cos(0.5*khiAng*kDegrad);
Double_t rl,ru;
//
// Get ALICE top node
//
nTop=gAlice->GetGeometry()->GetNode("alice");
// inner sectors
rl = fTPCParam->GetInnerRadiusLow();
ru = fTPCParam->GetInnerRadiusUp();
for(i=0;iSetNumberOfDivisions(1);
nTop->cd();
nNode = new TNode(name,title,name,0,0,0,"");
nNode->SetLineColor(kColorTPC);
fNodes->Add(nNode);
}
// Outer sectors
rl = fTPCParam->GetOuterRadiusLow();
ru = fTPCParam->GetOuterRadiusUp();
for(i=0;iSetNumberOfDivisions(1);
nTop->cd();
nNode = new TNode(name,title,name,0,0,0,"");
nNode->SetLineColor(kColorTPC);
fNodes->Add(nNode);
}
}
//_____________________________________________________________________________
Int_t AliTPC::DistancetoPrimitive(Int_t , Int_t )
{
//
// Calculate distance from TPC to mouse on the display
// Dummy procedure
//
return 9999;
}
void AliTPC::Clusters2Tracks(TFile *of) {
//-----------------------------------------------------------------
// This is a track finder.
//-----------------------------------------------------------------
AliTPCtracker tracker(fTPCParam);
tracker.Clusters2Tracks(gFile,of);
}
//_____________________________________________________________________________
void AliTPC::CreateMaterials()
{
//-----------------------------------------------
// Create Materials for for TPC simulations
//-----------------------------------------------
//-----------------------------------------------------------------
// Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
//-----------------------------------------------------------------
Int_t iSXFLD=gAlice->Field()->Integ();
Float_t sXMGMX=gAlice->Field()->Max();
Float_t amat[5]; // atomic numbers
Float_t zmat[5]; // z
Float_t wmat[5]; // proportions
Float_t density;
Float_t apure[2];
//***************** Gases *************************
//-------------------------------------------------
// pure gases
//-------------------------------------------------
// Neon
amat[0]= 20.18;
zmat[0]= 10.;
density = 0.0009;
apure[0]=amat[0];
AliMaterial(20,"Ne",amat[0],zmat[0],density,999.,999.);
// Argon
amat[0]= 39.948;
zmat[0]= 18.;
density = 0.001782;
apure[1]=amat[0];
AliMaterial(21,"Ar",amat[0],zmat[0],density,999.,999.);
//--------------------------------------------------------------
// gases - compounds
//--------------------------------------------------------------
Float_t amol[3];
// CO2
amat[0]=12.011;
amat[1]=15.9994;
zmat[0]=6.;
zmat[1]=8.;
wmat[0]=1.;
wmat[1]=2.;
density=0.001977;
amol[0] = amat[0]*wmat[0]+amat[1]*wmat[1];
AliMixture(10,"CO2",amat,zmat,density,-2,wmat);
// CF4
amat[0]=12.011;
amat[1]=18.998;
zmat[0]=6.;
zmat[1]=9.;
wmat[0]=1.;
wmat[1]=4.;
density=0.003034;
amol[1] = amat[0]*wmat[0]+amat[1]*wmat[1];
AliMixture(11,"CF4",amat,zmat,density,-2,wmat);
// CH4
amat[0]=12.011;
amat[1]=1.;
zmat[0]=6.;
zmat[1]=1.;
wmat[0]=1.;
wmat[1]=4.;
density=0.000717;
amol[2] = amat[0]*wmat[0]+amat[1]*wmat[1];
AliMixture(12,"CH4",amat,zmat,density,-2,wmat);
//----------------------------------------------------------------
// gases - mixtures, ID >= 20 pure gases, <= 10 ID < 20 -compounds
//----------------------------------------------------------------
char namate[21];
density = 0.;
Float_t am=0;
Int_t nc;
Float_t rho,absl,X0,buf[1];
Int_t nbuf;
Float_t a,z;
for(nc = 0;ncGfmate((*fIdmate)[fMixtComp[nc]],namate,a,z,rho,X0,absl,buf,nbuf);
amat[nc] = a;
zmat[nc] = z;
Int_t nnc = (fMixtComp[nc]>=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
am += fMixtProp[nc]*((fMixtComp[nc]>=20) ? apure[nnc] : amol[nnc]);
density += fMixtProp[nc]*rho; // density of the mixture
}
// mixture proportions by weight!
for(nc = 0;nc=20) ? fMixtComp[nc]%20 : fMixtComp[nc]%10;
wmat[nc] = fMixtProp[nc]*((fMixtComp[nc]>=20) ?
apure[nnc] : amol[nnc])/am;
}
// Drift gases 1 - nonsensitive, 2 - sensitive
AliMixture(31,"Drift gas 1",amat,zmat,density,fNoComp,wmat);
AliMixture(32,"Drift gas 2",amat,zmat,density,fNoComp,wmat);
// Air
amat[0] = 14.61;
zmat[0] = 7.3;
density = 0.001205;
AliMaterial(24,"Air",amat[0],zmat[0],density,999.,999.);
//----------------------------------------------------------------------
// solid materials
//----------------------------------------------------------------------
// Kevlar C14H22O2N2
amat[0] = 12.011;
amat[1] = 1.;
amat[2] = 15.999;
amat[3] = 14.006;
zmat[0] = 6.;
zmat[1] = 1.;
zmat[2] = 8.;
zmat[3] = 7.;
wmat[0] = 14.;
wmat[1] = 22.;
wmat[2] = 2.;
wmat[3] = 2.;
density = 1.45;
AliMixture(34,"Kevlar",amat,zmat,density,-4,wmat);
// NOMEX
amat[0] = 12.011;
amat[1] = 1.;
amat[2] = 15.999;
amat[3] = 14.006;
zmat[0] = 6.;
zmat[1] = 1.;
zmat[2] = 8.;
zmat[3] = 7.;
wmat[0] = 14.;
wmat[1] = 22.;
wmat[2] = 2.;
wmat[3] = 2.;
density = 0.03;
AliMixture(35,"NOMEX",amat,zmat,density,-4,wmat);
// Makrolon C16H18O3
amat[0] = 12.011;
amat[1] = 1.;
amat[2] = 15.999;
zmat[0] = 6.;
zmat[1] = 1.;
zmat[2] = 8.;
wmat[0] = 16.;
wmat[1] = 18.;
wmat[2] = 3.;
density = 1.2;
AliMixture(36,"Makrolon",amat,zmat,density,-3,wmat);
// Mylar C5H4O2
amat[0]=12.011;
amat[1]=1.;
amat[2]=15.9994;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
wmat[0]=5.;
wmat[1]=4.;
wmat[2]=2.;
density = 1.39;
AliMixture(37, "Mylar",amat,zmat,density,-3,wmat);
// SiO2 - used later for the glass fiber
amat[0]=28.086;
amat[1]=15.9994;
zmat[0]=14.;
zmat[1]=8.;
wmat[0]=1.;
wmat[1]=2.;
AliMixture(38,"SiO2",amat,zmat,2.2,-2,wmat); //SiO2 - quartz (rho=2.2)
// Al
amat[0] = 26.98;
zmat[0] = 13.;
density = 2.7;
AliMaterial(40,"Al",amat[0],zmat[0],density,999.,999.);
// Si
amat[0] = 28.086;
zmat[0] = 14.;
density = 2.33;
AliMaterial(41,"Si",amat[0],zmat[0],density,999.,999.);
// Cu
amat[0] = 63.546;
zmat[0] = 29.;
density = 8.96;
AliMaterial(42,"Cu",amat[0],zmat[0],density,999.,999.);
// Tedlar C2H3F
amat[0] = 12.011;
amat[1] = 1.;
amat[2] = 18.998;
zmat[0] = 6.;
zmat[1] = 1.;
zmat[2] = 9.;
wmat[0] = 2.;
wmat[1] = 3.;
wmat[2] = 1.;
density = 1.71;
AliMixture(43, "Tedlar",amat,zmat,density,-3,wmat);
// Plexiglas C5H8O2
amat[0]=12.011;
amat[1]=1.;
amat[2]=15.9994;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
wmat[0]=5.;
wmat[1]=8.;
wmat[2]=2.;
density=1.18;
AliMixture(44,"Plexiglas",amat,zmat,density,-3,wmat);
// Epoxy - C14 H20 O3
amat[0]=12.011;
amat[1]=1.;
amat[2]=15.9994;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
wmat[0]=14.;
wmat[1]=20.;
wmat[2]=3.;
density=1.25;
AliMixture(45,"Epoxy",amat,zmat,density,-3,wmat);
// Carbon
amat[0]=12.011;
zmat[0]=6.;
density= 2.265;
AliMaterial(46,"C",amat[0],zmat[0],density,999.,999.);
// get epoxy
gMC->Gfmate((*fIdmate)[45],namate,amat[1],zmat[1],rho,X0,absl,buf,nbuf);
// Carbon fiber
wmat[0]=0.644; // by weight!
wmat[1]=0.356;
density=0.5*(1.25+2.265);
AliMixture(47,"Cfiber",amat,zmat,density,2,wmat);
// get SiO2
gMC->Gfmate((*fIdmate)[38],namate,amat[0],zmat[0],rho,X0,absl,buf,nbuf);
wmat[0]=0.725; // by weight!
wmat[1]=0.275;
density=1.7;
AliMixture(39,"G10",amat,zmat,density,2,wmat);
//----------------------------------------------------------
// tracking media for gases
//----------------------------------------------------------
AliMedium(0, "Air", 24, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
AliMedium(1, "Drift gas 1", 31, 0, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
AliMedium(2, "Drift gas 2", 32, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
AliMedium(3,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
//-----------------------------------------------------------
// tracking media for solids
//-----------------------------------------------------------
AliMedium(4,"Al",40,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(5,"Kevlar",34,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(6,"Nomex",35,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(7,"Makrolon",36,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(8,"Mylar",37,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(9,"Tedlar",43,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(10,"Cu",42,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(11,"Si",41,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(12,"G10",39,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(13,"Plexiglas",44,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(14,"Epoxy",45,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(15,"Cfiber",47,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
}
void AliTPC::GenerNoise(Int_t tablesize)
{
//
//Generate table with noise
//
if (fTPCParam==0) {
// error message
fNoiseDepth=0;
return;
}
if (fNoiseTable) delete[] fNoiseTable;
fNoiseTable = new Float_t[tablesize];
fNoiseDepth = tablesize;
fCurrentNoise =0; //!index of the noise in the noise table
Float_t norm = fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac();
for (Int_t i=0;iGaus(0,norm);
}
Float_t AliTPC::GetNoise()
{
// get noise from table
// if ((fCurrentNoise%10)==0)
// fCurrentNoise= gRandom->Rndm()*fNoiseDepth;
if (fCurrentNoise>=fNoiseDepth) fCurrentNoise=0;
return fNoiseTable[fCurrentNoise++];
//gRandom->Gaus(0, fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac());
}
Bool_t AliTPC::IsSectorActive(Int_t sec)
{
//
// check if the sector is active
if (!fActiveSectors) return kTRUE;
else return fActiveSectors[sec];
}
void AliTPC::SetActiveSectors(Int_t * sectors, Int_t n)
{
// activate interesting sectors
if (fActiveSectors) delete [] fActiveSectors;
fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
for (Int_t i=0;iGetNSector();i++) fActiveSectors[i]=kFALSE;
for (Int_t i=0;i=0) && sectors[i]GetNSector()) fActiveSectors[sectors[i]]=kTRUE;
}
void AliTPC::SetActiveSectors(Int_t flag)
{
//
// activate sectors which were hitted by tracks
//loop over tracks
if (fHitType==0) return; // if Clones hit - not short volume ID information
if (fActiveSectors) delete [] fActiveSectors;
fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
if (flag) {
for (Int_t i=0;iGetNSector();i++) fActiveSectors[i]=kTRUE;
return;
}
for (Int_t i=0;iGetNSector();i++) fActiveSectors[i]=kFALSE;
TBranch * branch=0;
if (fHitType>1) branch = gAlice->TreeH()->GetBranch("TPC2");
else branch = gAlice->TreeH()->GetBranch("TPC");
Stat_t ntracks = gAlice->TreeH()->GetEntries();
// loop over all hits
for(Int_t track=0;trackTreeH()->GetBranch("fVolumes");
TBranch * br2 = gAlice->TreeH()->GetBranch("fNVolumes");
br1->GetEvent(track);
br2->GetEvent(track);
Int_t *volumes = fTrackHits->GetVolumes();
for (Int_t j=0;jGetNVolumes(); j++)
fActiveSectors[volumes[j]]=kTRUE;
}
//
if (fTrackHitsOld && fHitType&2) {
TBranch * br = gAlice->TreeH()->GetBranch("fTrackHitsInfo");
br->GetEvent(track);
AliObjectArray * ar = fTrackHitsOld->fTrackHitsInfo;
for (UInt_t j=0;jGetSize();j++){
fActiveSectors[((AliTrackHitsInfo*)ar->At(j))->fVolumeID] =kTRUE;
}
}
}
}
void AliTPC::Digits2Clusters(TFile *of, Int_t eventnumber)
{
//-----------------------------------------------------------------
// This is a simple cluster finder.
//-----------------------------------------------------------------
AliTPCclusterer::Digits2Clusters(fTPCParam,of,eventnumber);
}
extern Double_t SigmaY2(Double_t, Double_t, Double_t);
extern Double_t SigmaZ2(Double_t, Double_t);
//_____________________________________________________________________________
void AliTPC::Hits2Clusters(TFile *of, Int_t eventn)
{
//--------------------------------------------------------
// TPC simple cluster generator from hits
// obtained from the TPC Fast Simulator
// The point errors are taken from the parametrization
//--------------------------------------------------------
//-----------------------------------------------------------------
// Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
//-----------------------------------------------------------------
// Adopted to Marian's cluster data structure by I.Belikov, CERN,
// Jouri.Belikov@cern.ch
//----------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
//---------------------------------------------------------------------
// ALICE TPC Cluster Parameters
//--------------------------------------------------------------------
// Cluster width in rphi
const Float_t kACrphi=0.18322;
const Float_t kBCrphi=0.59551e-3;
const Float_t kCCrphi=0.60952e-1;
// Cluster width in z
const Float_t kACz=0.19081;
const Float_t kBCz=0.55938e-3;
const Float_t kCCz=0.30428;
TDirectory *savedir=gDirectory;
if (!of->IsOpen()) {
cerr<<"AliTPC::Hits2Clusters(): output file not open !\n";
return;
}
//if(fDefaults == 0) SetDefaults();
Float_t sigmaRphi,sigmaZ,clRphi,clZ;
//
TParticle *particle; // pointer to a given particle
AliTPChit *tpcHit; // pointer to a sigle TPC hit
Int_t sector;
Int_t ipart;
Float_t xyz[5];
Float_t pl,pt,tanth,rpad,ratio;
Float_t cph,sph;
//---------------------------------------------------------------
// Get the access to the tracks
//---------------------------------------------------------------
TTree *tH = gAlice->TreeH();
Stat_t ntracks = tH->GetEntries();
//Switch to the output file
of->cd();
char cname[100];
sprintf(cname,"TreeC_TPC_%d",eventn);
fTPCParam->Write(fTPCParam->GetTitle());
AliTPCClustersArray carray;
carray.Setup(fTPCParam);
carray.SetClusterType("AliTPCcluster");
carray.MakeTree();
Int_t nclusters=0; //cluster counter
//------------------------------------------------------------
// Loop over all sectors (72 sectors for 20 deg
// segmentation for both lower and upper sectors)
// Sectors 0-35 are lower sectors, 0-17 z>0, 17-35 z<0
// Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0
//
// First cluster for sector 0 starts at "0"
//------------------------------------------------------------
for(Int_t isec=0;isecGetNSector();isec++){
//MI change
fTPCParam->AdjustCosSin(isec,cph,sph);
//------------------------------------------------------------
// Loop over tracks
//------------------------------------------------------------
for(Int_t track=0;trackGetEvent(track);
//
// Get number of the TPC hits
//
tpcHit = (AliTPChit*)FirstHit(-1);
// Loop over hits
//
while(tpcHit){
if (tpcHit->fQ == 0.) {
tpcHit = (AliTPChit*) NextHit();
continue; //information about track (I.Belikov)
}
sector=tpcHit->fSector; // sector number
if(sector != isec){
tpcHit = (AliTPChit*) NextHit();
continue;
}
ipart=tpcHit->Track();
particle=gAlice->Particle(ipart);
pl=particle->Pz();
pt=particle->Pt();
if(pt < 1.e-9) pt=1.e-9;
tanth=pl/pt;
tanth = TMath::Abs(tanth);
rpad=TMath::Sqrt(tpcHit->X()*tpcHit->X() + tpcHit->Y()*tpcHit->Y());
ratio=0.001*rpad/pt; // pt must be in MeV/c - historical reason
// space-point resolutions
sigmaRphi=SigmaY2(rpad,tanth,pt);
sigmaZ =SigmaZ2(rpad,tanth );
// cluster widths
clRphi=kACrphi-kBCrphi*rpad*tanth+kCCrphi*ratio*ratio;
clZ=kACz-kBCz*rpad*tanth+kCCz*tanth*tanth;
// temporary protection
if(sigmaRphi < 0.) sigmaRphi=0.4e-3;
if(sigmaZ < 0.) sigmaZ=0.4e-3;
if(clRphi < 0.) clRphi=2.5e-3;
if(clZ < 0.) clZ=2.5e-5;
//
//
// smearing --> rotate to the 1 (13) or to the 25 (49) sector,
// then the inaccuracy in a X-Y plane is only along Y (pad row)!
//
Float_t xprim= tpcHit->X()*cph + tpcHit->Y()*sph;
Float_t yprim=-tpcHit->X()*sph + tpcHit->Y()*cph;
xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigmaRphi)); // y
Float_t alpha=(isec < fTPCParam->GetNInnerSector()) ?
fTPCParam->GetInnerAngle() : fTPCParam->GetOuterAngle();
Float_t ymax=xprim*TMath::Tan(0.5*alpha);
if (TMath::Abs(xyz[0])>ymax) xyz[0]=yprim;
xyz[1]=gRandom->Gaus(tpcHit->Z(),TMath::Sqrt(sigmaZ)); // z
if (TMath::Abs(xyz[1])>fTPCParam->GetZLength()) xyz[1]=tpcHit->Z();
xyz[2]=sigmaRphi; // fSigmaY2
xyz[3]=sigmaZ; // fSigmaZ2
xyz[4]=tpcHit->fQ; // q
AliTPCClustersRow *clrow=carray.GetRow(sector,tpcHit->fPadRow);
if (!clrow) clrow=carray.CreateRow(sector,tpcHit->fPadRow);
Int_t tracks[3]={tpcHit->Track(), -1, -1};
AliTPCcluster cluster(tracks,xyz);
clrow->InsertCluster(&cluster); nclusters++;
tpcHit = (AliTPChit*)NextHit();
} // end of loop over hits
} // end of loop over tracks
Int_t nrows=fTPCParam->GetNRow(isec);
for (Int_t irow=0; irowSetName(cname);
carray.GetTree()->Write();
savedir->cd(); //switch back to the input file
} // end of function
//_________________________________________________________________
void AliTPC::Hits2ExactClustersSector(Int_t isec)
{
//--------------------------------------------------------
//calculate exact cross point of track and given pad row
//resulting values are expressed in "digit" coordinata
//--------------------------------------------------------
//-----------------------------------------------------------------
// Origin: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
//-----------------------------------------------------------------
//
if (fClustersArray==0){
return;
}
//
TParticle *particle; // pointer to a given particle
AliTPChit *tpcHit; // pointer to a sigle TPC hit
// Int_t sector,nhits;
Int_t ipart;
const Int_t kcmaxhits=30000;
AliTPCFastVector * xxxx = new AliTPCFastVector(kcmaxhits*4);
AliTPCFastVector & xxx = *xxxx;
Int_t maxhits = kcmaxhits;
//construct array for each padrow
for (Int_t i=0; iGetNRow(isec);i++)
fClustersArray->CreateRow(isec,i);
//---------------------------------------------------------------
// Get the access to the tracks
//---------------------------------------------------------------
TTree *tH = gAlice->TreeH();
Stat_t ntracks = tH->GetEntries();
Int_t npart = gAlice->GetNtrack();
//MI change
TBranch * branch=0;
if (fHitType>1) branch = tH->GetBranch("TPC2");
else branch = tH->GetBranch("TPC");
//------------------------------------------------------------
// Loop over tracks
//------------------------------------------------------------
for(Int_t track=0;trackGetEntry(track); // get next track
//
// Get number of the TPC hits and a pointer
// to the particles
// Loop over hits
//
Int_t currentIndex=0;
Int_t lastrow=-1; //last writen row
//M.I. changes
tpcHit = (AliTPChit*)FirstHit(-1);
while(tpcHit){
Int_t sector=tpcHit->fSector; // sector number
if(sector != isec){
tpcHit = (AliTPChit*) NextHit();
continue;
}
ipart=tpcHit->Track();
if (ipartParticle(ipart);
//find row number
Float_t x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()};
Int_t index[3]={1,isec,0};
Int_t currentrow = fTPCParam->GetPadRow(x,index) ;
if (currentrow<0) {tpcHit = (AliTPChit*)NextHit(); continue;}
if (lastrow<0) lastrow=currentrow;
if (currentrow==lastrow){
if ( currentIndex>=maxhits){
maxhits+=kcmaxhits;
xxx.ResizeTo(4*maxhits);
}
xxx(currentIndex*4)=x[0];
xxx(currentIndex*4+1)=x[1];
xxx(currentIndex*4+2)=x[2];
xxx(currentIndex*4+3)=tpcHit->fQ;
currentIndex++;
}
else
if (currentIndex>2){
Float_t sumx=0;
Float_t sumx2=0;
Float_t sumx3=0;
Float_t sumx4=0;
Float_t sumy=0;
Float_t sumxy=0;
Float_t sumx2y=0;
Float_t sumz=0;
Float_t sumxz=0;
Float_t sumx2z=0;
Float_t sumq=0;
for (Int_t index=0;indexGetNPads(isec,lastrow)-1)/2;
Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+
sumx2*(sumx*sumx3-sumx2*sumx2);
Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+
sumx2*(sumxy*sumx3-sumx2y*sumx2);
Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+
sumx2*(sumxz*sumx3-sumx2z*sumx2);
Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+
sumx2*(sumx*sumx2y-sumx2*sumxy);
Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+
sumx2*(sumx*sumx2z-sumx2*sumxz);
if (TMath::Abs(det)<0.00001){
tpcHit = (AliTPChit*)NextHit();
continue;
}
Float_t y=detay/det+centralPad;
Float_t z=detaz/det;
Float_t by=detby/det; //y angle
Float_t bz=detbz/det; //z angle
sumy/=Float_t(currentIndex);
sumz/=Float_t(currentIndex);
AliTPCClustersRow * row = (fClustersArray->GetRow(isec,lastrow));
if (row!=0) {
AliComplexCluster* cl = new((AliComplexCluster*)row->Append()) AliComplexCluster ;
// AliComplexCluster cl;
cl->fX=z;
cl->fY=y;
cl->fQ=sumq;
cl->fSigmaX2=bz;
cl->fSigmaY2=by;
cl->fTracks[0]=ipart;
}
currentIndex=0;
lastrow=currentrow;
} //end of calculating cluster for given row
tpcHit = (AliTPChit*)NextHit();
} // end of loop over hits
} // end of loop over tracks
//write padrows to tree
for (Int_t ii=0; iiGetNRow(isec);ii++) {
fClustersArray->StoreRow(isec,ii);
fClustersArray->ClearRow(isec,ii);
}
xxxx->Delete();
}
//__
void AliTPC::SDigits2Digits2(Int_t eventnumber)
{
//create digits from summable digits
GenerNoise(500000); //create teble with noise
char sname[100];
char dname[100];
sprintf(sname,"TreeS_%s_%d",fTPCParam->GetTitle(),eventnumber);
sprintf(dname,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
//conect tree with sSDigits
TTree *t;
if (gAlice->GetTreeDFile()) {
t = (TTree *)gAlice->GetTreeDFile()->Get(sname);
} else {
t = (TTree *)gDirectory->Get(sname);
}
if (!t) {
cerr<<"TPC tree with sdigits not found"<GetBranch("Segment")->SetAddress(&dummy);
Stat_t nentries = t->GetEntries();
// set zero suppression
fTPCParam->SetZeroSup(2);
// get zero suppression
Int_t zerosup = fTPCParam->GetZeroSup();
//make tree with digits
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
// Note that methods arr->MakeTree have different signatures
if (gAlice->GetTreeDFile()) {
arr->MakeTree(gAlice->GetTreeDFile());
} else {
arr->MakeTree(fDigitsFile);
}
AliTPCParam * par =fTPCParam;
//Loop over segments of the TPC
for (Int_t n=0; nGetEvent(n);
Int_t sec, row;
if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) {
cerr<<"AliTPC warning: invalid segment ID ! "<CreateRow(sec,row);
Int_t nrows = digrow->GetNRows();
Int_t ncols = digrow->GetNCols();
digrow->ExpandBuffer();
digarr.ExpandBuffer();
digrow->ExpandTrackBuffer();
digarr.ExpandTrackBuffer();
Short_t * pamp0 = digarr.GetDigits();
Int_t * ptracks0 = digarr.GetTracks();
Short_t * pamp1 = digrow->GetDigits();
Int_t * ptracks1 = digrow->GetTracks();
Int_t nelems =nrows*ncols;
Int_t saturation = fTPCParam->GetADCSat();
//use internal structure of the AliDigits - for speed reason
//if you cahnge implementation
//of the Alidigits - it must be rewriten -
for (Int_t i= 0; izerosup){
if (q>saturation) q=saturation;
*pamp1=(Short_t)q;
//if (ptracks0[0]==0)
// ptracks1[0]=1;
//else
ptracks1[0]=ptracks0[0];
ptracks1[nelems]=ptracks0[nelems];
ptracks1[2*nelems]=ptracks0[2*nelems];
}
pamp0++;
pamp1++;
ptracks0++;
ptracks1++;
}
arr->StoreRow(sec,row);
arr->ClearRow(sec,row);
// cerr<GetTree()->SetName(dname);
arr->GetTree()->AutoSave();
delete arr;
}
//_________________________________________
void AliTPC::Merge(TTree * intree, Int_t *mask, Int_t nin, Int_t outid)
{
//intree - pointer to array of trees with s digits
//mask - mask for each
//nin - number of inputs
//outid - event number of the output event
//create digits from summable digits
//conect tree with sSDigits
AliSimDigits ** digarr = new AliSimDigits*[nin];
for (Int_t i1=0;i1SetAddress(&digarr[i1]);
}
Stat_t nentries = intree[0].GetEntries();
//make tree with digits
char dname[100];
sprintf(dname,"TreeD_%s_%d",fTPCParam->GetTitle(),outid);
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
arr->MakeTree(fDigitsFile);
// set zero suppression
fTPCParam->SetZeroSup(2);
// get zero suppression
Int_t zerosup = fTPCParam->GetZeroSup();
AliTPCParam * par =fTPCParam;
//Loop over segments of the TPC
for (Int_t n=0; nExpandBuffer();
digarr[i]->ExpandTrackBuffer();
}
Int_t sec, row;
if (!par->AdjustSectorRow(digarr[0]->GetID(),sec,row)) {
cerr<<"AliTPC warning: invalid segment ID ! "<GetID()<CreateRow(sec,row);
Int_t nrows = digrow->GetNRows();
Int_t ncols = digrow->GetNCols();
digrow->ExpandBuffer();
digrow->ExpandTrackBuffer();
for (Int_t rows=0;rowsGetDigitFast(rows,col);
for (Int_t tr=0;tr<3;tr++) {
Int_t lab = digarr[i]->GetTrackIDFast(rows,col,tr);
if ( lab > 1) {
label[labptr]=lab+mask[i]-2;
labptr++;
}
}
}
//add noise
q = gRandom->Gaus(q,fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac()*16);
q/=16; //conversion faktor
q=(Short_t)q;
if (q> zerosup){
if(q > fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat();
digrow->SetDigitFast((Short_t)q,rows,col);
for (Int_t tr=0;tr<3;tr++){
if (trSetTrackIDFast(label[tr],rows,col,tr);
else
((AliSimDigits*)digrow)->SetTrackIDFast(-1,rows,col,tr);
}
}
}
}
arr->StoreRow(sec,row);
arr->ClearRow(sec,row);
}
delete digarr;
arr->GetTree()->SetName(dname);
arr->GetTree()->Write();
delete arr;
}
/*_________________________________________
void AliTPC::SDigits2Digits(Int_t eventnumber)
{
cerr<<"Digitizing TPC...\n";
Hits2Digits(eventnumber);
//write results
// char treeName[100];
// sprintf(treeName,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
// GetDigitsArray()->GetTree()->Write(treeName);
}
*/
//__________________________________________________________________
void AliTPC::SetDefaults(){
cerr<<"Setting default parameters...\n";
// Set response functions
AliTPCParamSR *param=(AliTPCParamSR*)gDirectory->Get("75x40_100x60");
if(param){
printf("You are using 2 pad-length geom hits with 3 pad-lenght geom digits...\n");
delete param;
param = new AliTPCParamSR();
}
else {
param=(AliTPCParamSR*)gDirectory->Get("75x40_100x60_150x60");
}
if(!param){
printf("No TPC parameters found\n");
exit(4);
}
AliTPCPRF2D * prfinner = new AliTPCPRF2D;
AliTPCPRF2D * prfouter1 = new AliTPCPRF2D;
AliTPCPRF2D * prfouter2 = new AliTPCPRF2D;
AliTPCRF1D * rf = new AliTPCRF1D(kTRUE);
rf->SetGauss(param->GetZSigma(),param->GetZWidth(),1.);
rf->SetOffset(3*param->GetZSigma());
rf->Update();
TDirectory *savedir=gDirectory;
TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
if (!f->IsOpen()) {
cerr<<"Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !\n" ;
exit(3);
}
prfinner->Read("prf_07504_Gati_056068_d02");
prfouter1->Read("prf_10006_Gati_047051_d03");
prfouter2->Read("prf_15006_Gati_047051_d03");
f->Close();
savedir->cd();
param->SetInnerPRF(prfinner);
param->SetOuter1PRF(prfouter1);
param->SetOuter2PRF(prfouter2);
param->SetTimeRF(rf);
// set fTPCParam
SetParam(param);
fDefaults = 1;
}
//__________________________________________________________________
void AliTPC::Hits2Digits(Int_t eventnumber)
{
//----------------------------------------------------
// Loop over all sectors for a single event
//----------------------------------------------------
if(fDefaults == 0) SetDefaults(); // check if the parameters are set
GenerNoise(500000); //create teble with noise
//setup TPCDigitsArray
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
// Note that methods arr->MakeTree have different signatures
if (gAlice->GetTreeDFile()) {
arr->MakeTree(gAlice->GetTreeDFile());
} else {
arr->MakeTree(fDigitsFile);
}
SetDigitsArray(arr);
fDigitsSwitch=0; // standard digits
cerr<<"Digitizing TPC -- normal digits...\n";
for(Int_t isec=0;isecGetNSector();isec++) if (IsSectorActive(isec)) Hits2DigitsSector(isec);
// write results
char treeName[100];
sprintf(treeName,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
GetDigitsArray()->GetTree()->SetName(treeName);
GetDigitsArray()->GetTree()->AutoSave();
}
//__________________________________________________________________
void AliTPC::Hits2SDigits2(Int_t eventnumber)
{
//-----------------------------------------------------------
// summable digits - 16 bit "ADC", no noise, no saturation
//-----------------------------------------------------------
//----------------------------------------------------
// Loop over all sectors for a single event
//----------------------------------------------------
if(fDefaults == 0) SetDefaults();
GenerNoise(500000); //create table with noise
//setup TPCDigitsArray
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
// Note that methods arr->MakeTree have different signatures
if (gAlice->GetTreeSFile()) {
arr->MakeTree(gAlice->GetTreeSFile());
} else {
arr->MakeTree(fDigitsFile);
}
SetDigitsArray(arr);
cerr<<"Digitizing TPC -- summable digits...\n";
fDigitsSwitch=1; // summable digits
// set zero suppression to "0"
fTPCParam->SetZeroSup(0);
for(Int_t isec=0;isecGetNSector();isec++) if (IsSectorActive(isec)) Hits2DigitsSector(isec);
// write results
char treeName[100];
sprintf(treeName,"TreeS_%s_%d",fTPCParam->GetTitle(),eventnumber);
GetDigitsArray()->GetTree()->SetName(treeName);
GetDigitsArray()->GetTree()->AutoSave();
}
//__________________________________________________________________
void AliTPC::Hits2SDigits()
{
//-----------------------------------------------------------
// summable digits - 16 bit "ADC", no noise, no saturation
//-----------------------------------------------------------
//----------------------------------------------------
// Loop over all sectors for a single event
//----------------------------------------------------
//MI change - for pp run
Int_t eventnumber = gAlice->GetEvNumber();
if(fDefaults == 0) SetDefaults();
GenerNoise(500000); //create table with noise
//setup TPCDigitsArray
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
// Note that methods arr->MakeTree have different signatures
if (gAlice->GetTreeSFile()) {
arr->MakeTree(gAlice->GetTreeSFile());
} else {
arr->MakeTree(fDigitsFile);
}
SetDigitsArray(arr);
cerr<<"Digitizing TPC -- summable digits...\n";
// fDigitsSwitch=1; // summable digits -for the moment direct
for(Int_t isec=0;isecGetNSector();isec++) if (IsSectorActive(isec)) Hits2DigitsSector(isec);
// write results
char treeName[100];
sprintf(treeName,"TreeD_%s_%d",fTPCParam->GetTitle(),eventnumber);
GetDigitsArray()->GetTree()->SetName(treeName);
GetDigitsArray()->GetTree()->AutoSave();
}
//_____________________________________________________________________________
void AliTPC::Hits2DigitsSector(Int_t isec)
{
//-------------------------------------------------------------------
// TPC conversion from hits to digits.
//-------------------------------------------------------------------
//-----------------------------------------------------------------
// Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
//-----------------------------------------------------------------
//-------------------------------------------------------
// Get the access to the track hits
//-------------------------------------------------------
// check if the parameters are set - important if one calls this method
// directly, not from the Hits2Digits
if(fDefaults == 0) SetDefaults();
TTree *tH = gAlice->TreeH(); // pointer to the hits tree
Stat_t ntracks = tH->GetEntries();
if( ntracks > 0){
//-------------------------------------------
// Only if there are any tracks...
//-------------------------------------------
TObjArray **row;
//printf("*** Processing sector number %d ***\n",isec);
Int_t nrows =fTPCParam->GetNRow(isec);
row= new TObjArray* [nrows+2]; // 2 extra rows for cross talk
MakeSector(isec,nrows,tH,ntracks,row);
//--------------------------------------------------------
// Digitize this sector, row by row
// row[i] is the pointer to the TObjArray of AliTPCFastVectors,
// each one containing electrons accepted on this
// row, assigned into tracks
//--------------------------------------------------------
Int_t i;
if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree(fDigitsFile);
for (i=0;iCreateRow(isec,i);
DigitizeRow(i,isec,row);
fDigitsArray->StoreRow(isec,i);
Int_t ndig = dig->GetDigitSize();
if (gDebug > 10) printf("*** Sector, row, compressed digits %d %d %d ***\n",isec,i,ndig);
fDigitsArray->ClearRow(isec,i);
} // end of the sector digitization
for(i=0;iDelete();
delete row[i];
}
delete [] row; // delete the array of pointers to TObjArray-s
} // ntracks >0
} // end of Hits2DigitsSector
//_____________________________________________________________________________
void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows)
{
//-----------------------------------------------------------
// Single row digitization, coupling from the neighbouring
// rows taken into account
//-----------------------------------------------------------
//-----------------------------------------------------------------
// Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
// Modified: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
//-----------------------------------------------------------------
Float_t zerosup = fTPCParam->GetZeroSup();
// Int_t nrows =fTPCParam->GetNRow(isec);
fCurrentIndex[1]= isec;
Int_t nofPads = fTPCParam->GetNPads(isec,irow);
Int_t nofTbins = fTPCParam->GetMaxTBin();
Int_t indexRange[4];
//
// Integrated signal for this row
// and a single track signal
//
AliTPCFastMatrix *m1 = new AliTPCFastMatrix(0,nofPads,0,nofTbins); // integrated
AliTPCFastMatrix *m2 = new AliTPCFastMatrix(0,nofPads,0,nofTbins); // single
//
AliTPCFastMatrix &total = *m1;
// Array of pointers to the label-signal list
Int_t nofDigits = nofPads*nofTbins; // number of digits for this row
Float_t **pList = new Float_t* [nofDigits];
Int_t lp;
Int_t i1;
for(lp=0;lpGetNCrossRows(),0);
//Int_t row2 = TMath::Min(irow+fTPCParam->GetNCrossRows(),nrows-1);
Int_t row1=irow;
Int_t row2=irow+2;
for (Int_t row= row1;row<=row2;row++){
Int_t nTracks= rows[row]->GetEntries();
for (i1=0;i1Zero(); // clear single track signal matrix
Float_t trackLabel = GetSignal(rows[row],i1,m2,m1,indexRange);
GetList(trackLabel,nofPads,m2,indexRange,pList);
}
else GetSignal(rows[row],i1,0,m1,indexRange);
}
}
Int_t tracks[3];
AliDigits *dig = fDigitsArray->GetRow(isec,irow);
Int_t gi=-1;
Float_t fzerosup = zerosup+0.5;
for(Int_t it=0;it fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat(); // saturation
}
else {
if(q <= 0.) continue; // do not fill zeros
if(q>2000.) q=2000.;
q *= 16.;
q = TMath::Nint(q);
}
//
// "real" signal or electronic noise (list = -1)?
//
for(Int_t j1=0;j1<3;j1++){
tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -2;
}
//Begin_Html
/*
using of AliDigits object
*/
//End_Html
dig->SetDigitFast((Short_t)q,it,ip);
if (fDigitsArray->IsSimulated())
{
((AliSimDigits*)dig)->SetTrackIDFast(tracks[0],it,ip,0);
((AliSimDigits*)dig)->SetTrackIDFast(tracks[1],it,ip,1);
((AliSimDigits*)dig)->SetTrackIDFast(tracks[2],it,ip,2);
}
} // end of loop over time buckets
} // end of lop over pads
//
// This row has been digitized, delete nonused stuff
//
for(lp=0;lpAt(ntr); // pointer to a track
AliTPCFastVector &v = *tv;
Float_t label = v(0);
Int_t centralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3]-1)-1)/2;
Int_t nElectrons = (tv->GetNrows()-1)/4;
indexRange[0]=9999; // min pad
indexRange[1]=-1; // max pad
indexRange[2]=9999; //min time
indexRange[3]=-1; // max time
AliTPCFastMatrix &signal = *m1;
AliTPCFastMatrix &total = *m2;
//
// Loop over all electrons
//
for(Int_t nel=0; nelGetTotalNormFac();
Float_t xyz[3]={v(idx+1),v(idx+2),v(idx+3)};
Int_t n = ((AliTPCParamSR*)fTPCParam)->CalcResponseFast(xyz,fCurrentIndex,fCurrentIndex[3]);
Int_t *index = fTPCParam->GetResBin(0);
Float_t *weight = & (fTPCParam->GetResWeight(0));
if (n>0) for (Int_t i =0; i=0){
Int_t time=index[2];
Float_t qweight = *(weight)*eltoadcfac;
if (m1!=0) signal.UncheckedAt(pad,time)+=qweight;
total.UncheckedAt(pad,time)+=qweight;
if (indexRange[0]>pad) indexRange[0]=pad;
if (indexRange[1]time) indexRange[2]=time;
if (indexRange[3]