/*
<img src="picts/AliTPCClass.gif">
*/
//End_Html
#include <Riostream.h>
#include <stdlib.h>
#include <TF2.h>
#include <TFile.h>
#include <TGeoGlobalMagField.h>
#include <TInterpreter.h>
#include <TMath.h>
#include <TMatrixF.h>
#include <TObjectTable.h>
#include <TParticle.h>
#include <TROOT.h>
#include <TRandom.h>
#include <TStopwatch.h>
#include <TString.h>
#include <TSystem.h>
#include <TTree.h>
#include <TVector.h>
#include <TVirtualMC.h>
#include <TParameter.h>
#include "AliDigits.h"
#include "AliHeader.h"
#include "AliMagF.h"
#include "AliRun.h"
#include "AliRunLoader.h"
#include "AliSimDigits.h"
#include "AliTPC.h"
#include "AliTPC.h"
#include "AliTPCDigitsArray.h"
#include "AliTPCLoader.h"
#include "AliTPCPRF2D.h"
#include "AliTPCParamSR.h"
#include "AliTPCRF1D.h"
#include "AliTPCTrackHitsV2.h"
#include "AliTrackReference.h"
#include "AliMC.h"
#include "AliStack.h"
#include "AliTPCDigitizer.h"
#include "AliTPCBuffer.h"
#include "AliTPCDDLRawData.h"
#include "AliLog.h"
#include "AliTPCcalibDB.h"
#include "AliTPCRecoParam.h"
#include "AliTPCCalPad.h"
#include "AliTPCCalROC.h"
#include "AliTPCExB.h"
#include "AliTPCCorrection.h"
#include "AliCTPTimeParams.h"
#include "AliRawReader.h"
#include "AliTPCRawStreamV3.h"
#include "TTreeStream.h"
ClassImp(AliTPC)
AliTPC::AliTPC():AliDetector(),
fDefaults(0),
fSens(0),
fNsectors(0),
fDigitsArray(0),
fTPCParam(0),
fTrackHits(0),
fHitType(0),
fDigitsSwitch(0),
fSide(0),
fPrimaryIonisation(0),
fNoiseDepth(0),
fNoiseTable(0),
fCurrentNoise(0),
fActiveSectors(0),
fGainFactor(1.),
fDebugStreamer(0),
fLHCclockPhaseSw(0),
fIsGEM(0)
{
fIshunt = 0;
for(Int_t i=0;i<4;i++) fCurrentIndex[i]=0;
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
fHitType = 4;
#else
fHitType = 2;
#endif
}
AliTPC::AliTPC(const char *name, const char *title)
: AliDetector(name,title),
fDefaults(0),
fSens(0),
fNsectors(0),
fDigitsArray(0),
fTPCParam(0),
fTrackHits(0),
fHitType(0),
fDigitsSwitch(0),
fSide(0),
fPrimaryIonisation(0),
fNoiseDepth(0),
fNoiseTable(0),
fCurrentNoise(0),
fActiveSectors(0),
fGainFactor(1.),
fDebugStreamer(0),
fLHCclockPhaseSw(0),
fIsGEM(0)
{
fHits = new TClonesArray("AliTPChit", 176);
gAlice->GetMCApp()->AddHitList(fHits);
fTrackHits = new AliTPCTrackHitsV2;
fTrackHits->SetHitPrecision(0.002);
fTrackHits->SetStepPrecision(0.003);
fTrackHits->SetMaxDistance(100);
#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
fHitType = 4;
#else
fHitType = 2;
#endif
for(Int_t i=0;i<4;i++) fCurrentIndex[i]=0;
fIshunt = 0;
if (!strcmp(title,"Ne-CO2") || !strcmp(title,"Ne-CO2-N") || !strcmp(title,"Default") ) {
fTPCParam = AliTPCcalibDB::Instance()->GetParameters();
} else {
AliWarning("In Config.C you must set non-default parameters.");
fTPCParam=0;
}
}
void AliTPC::CreateDebugStremer(){
fDebugStreamer = new TTreeSRedirector("TPCSimdebug.root");
}
AliTPC::~AliTPC()
{
fIshunt = 0;
delete fHits;
delete fDigits;
delete fTrackHits;
fDigitsArray = 0x0;
delete [] fNoiseTable;
delete [] fActiveSectors;
if (fDebugStreamer) delete fDebugStreamer;
}
void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
{
if (fHitType&1){
TClonesArray &lhits = *fHits;
new(lhits[fNhits++]) AliTPChit(fIshunt,track,vol,hits);
}
if (fHitType>1)
AddHit2(track,vol,hits);
}
void AliTPC::CreateMaterials()
{
Int_t iSXFLD=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
Float_t sXMGMX=((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
Float_t amat[7];
Float_t zmat[7];
Float_t wmat[7];
Float_t density;
amat[0]=12.011;
amat[1]=15.9994;
zmat[0]=6.;
zmat[1]=8.;
wmat[0]=0.2729;
wmat[1]=0.7271;
density=1.842e-3;
AliMixture(10,"CO2",amat,zmat,density,2,wmat);
amat[0]=15.9994;
amat[1]=14.007;
zmat[0]=8.;
zmat[1]=7.;
wmat[0]=0.233;
wmat[1]=0.767;
density=0.001205;
AliMixture(11,"Air",amat,zmat,density,2,wmat);
TString names[6]={"Ne","Ar","CO2","N","CF4","CH4"};
TString gname;
Float_t *comp = fTPCParam->GetComposition();
amat[0]=20.18;
amat[1]=39.95;
amat[2]=12.011;
amat[3]=15.9994;
amat[4]=14.007;
amat[5]=18.998;
amat[6]=1.;
zmat[0]=10.;
zmat[1]=18.;
zmat[2]=6.;
zmat[3]=8.;
zmat[4]=7.;
zmat[5]=9.;
zmat[6]=1.;
Float_t wmol[6];
wmol[0]=20.18;
wmol[1]=39.948;
wmol[2]=44.0098;
wmol[3]=2.*14.0067;
wmol[4]=88.0046;
wmol[5]=16.011;
Float_t wtot=0.;
for(Int_t i =0;i<6;i++){
wtot += *(comp+i)*wmol[i];
}
wmat[0]=comp[0]*amat[0]/wtot;
wmat[1]=comp[1]*amat[1]/wtot;
wmat[2]=(comp[2]*amat[2]+comp[4]*amat[2]+comp[5]*amat[2])/wtot;
wmat[3]=comp[2]*amat[3]*2./wtot;
wmat[4]=comp[3]*amat[4]*2./wtot;
wmat[5]=comp[4]*amat[5]*4./wtot;
wmat[6]=comp[5]*amat[6]*4./wtot;
Float_t dens[6]={0.839e-3,1.661e-3,1.842e-3,1.251e-3,3.466e-3,0.668e-3};
density=0.;
for(Int_t i=0;i<6;i++){
density += comp[i]*dens[i];
}
Int_t cnt=0;
for(Int_t i =0;i<6;i++){
if(comp[i]){
if(cnt)gname+="-";
gname+=names[i];
cnt++;
}
}
TString gname1,gname2,gname3;
gname1 = gname + "-1";
gname2 = gname + "-2";
gname3 = gname + "-3";
Float_t amat1[6],zmat1[6],wmat1[6];
cnt=0;
for(Int_t i=0;i<7;i++){
if(wmat[i]){
zmat1[cnt]=zmat[i];
amat1[cnt]=amat[i];
wmat1[cnt]=wmat[i];
cnt++;
}
}
AliMixture(12,gname1.Data(),amat1,zmat1,density,cnt,wmat1);
AliMixture(13,gname2.Data(),amat1,zmat1,density,cnt,wmat1);
AliMixture(40,gname3.Data(),amat1,zmat1,density,cnt,wmat1);
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(14,"Kevlar",amat,zmat,density,-4,wmat);
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.029;
AliMixture(15,"NOMEX",amat,zmat,density,-4,wmat);
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(16,"Makrolon",amat,zmat,density,-3,wmat);
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(17, "Tedlar",amat,zmat,density,-3,wmat);
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(18, "Mylar",amat,zmat,density,-3,wmat);
amat[0]=12.011;
amat[1]=1.;
amat[2]=15.994;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
wmat[0]=0.923;
wmat[1]=0.023;
wmat[2]=0.054;
density=1.859;
AliMixture(19, "Prepreg1",amat,zmat,density,3,wmat);
amat[0]=12.01;
amat[1]=1.;
amat[2]=15.994;
amat[3]=28.086;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
zmat[3]=14.;
wmat[0]=0.194;
wmat[1]=0.023;
wmat[2]=0.443;
wmat[3]=0.34;
density=1.82;
AliMixture(20, "Prepreg2",amat,zmat,density,4,wmat);
amat[0]=12.01;
amat[1]=1.;
amat[2]=15.994;
amat[3]=28.086;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
zmat[3]=14.;
wmat[0]=0.257;
wmat[1]=0.03;
wmat[2]=0.412;
wmat[3]=0.3;
density=1.725;
AliMixture(21, "Prepreg3",amat,zmat,density,4,wmat);
amat[0]=12.01;
amat[1]=1.;
amat[2]=15.994;
amat[3]=28.086;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
zmat[3]=14.;
wmat[0]=0.194;
wmat[1]=0.023;
wmat[2]=0.443;
wmat[3]=0.340;
density=1.7;
AliMixture(22, "G10",amat,zmat,density,4,wmat);
amat[0] = 26.98;
zmat[0] = 13.;
density = 2.7;
AliMaterial(23,"Al",amat[0],zmat[0],density,999.,999.);
amat[0] = 28.086;
zmat[0] = 14.;
density = 2.33;
AliMaterial(24,"Si",amat[0],zmat[0],density,999.,999.);
amat[0] = 63.546;
zmat[0] = 29.;
density = 8.96;
AliMaterial(25,"Cu",amat[0],zmat[0],density,999.,999.);
amat[0] = 63.546;
zmat[0] = 29.;
amat[1]= 65.409;
zmat[1]= 30.;
wmat[0]= 0.6;
wmat[1]= 0.4;
density = 8.23;
AliMixture(33,"Brass",amat,zmat,density,2,wmat);
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(26,"Epoxy",amat,zmat,density,-3,wmat);
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;
density *= 1.25;
AliMixture(35,"Epoxy1",amat,zmat,density,-3,wmat);
amat[0]=12.01;
amat[1]=1.;
amat[2]=15.994;
amat[3]=28.086;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
zmat[3]=14.;
wmat[0]=0.596;
wmat[1]=0.071;
wmat[2]=0.257;
wmat[3]=0.076;
density=1.345;
AliMixture(34, "Epoxy-film",amat,zmat,density,4,wmat);
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(27,"Plexiglas",amat,zmat,density,-3,wmat);
amat[0]=12.011;
zmat[0]=6.;
density= 2.265;
AliMaterial(28,"C",amat[0],zmat[0],density,999.,999.);
amat[0]=55.845;
zmat[0]=26.;
density=7.87;
AliMaterial(29,"Fe",amat[0],zmat[0],density,999.,999.);
amat[0]=12.011;
amat[1]=1.;
amat[2]=15.9994;
zmat[0]=6.;
zmat[1]=1.;
zmat[2]=8.;
wmat[0]=19.;
wmat[1]=12.;
wmat[2]=3.;
density=1.3;
AliMixture(30,"Peek",amat,zmat,density,-3,wmat);
amat[0] = 26.98;
amat[1]= 15.9994;
zmat[0] = 13.;
zmat[1]=8.;
wmat[0]=2.;
wmat[1]=3.;
density = 3.97;
AliMixture(31,"Alumina",amat,zmat,density,-2,wmat);
amat[0] = 26.98;
amat[1]= 15.9994;
zmat[0] = 13.;
zmat[1]=8.;
wmat[0]=2.;
wmat[1]=3.;
density = 3.97;
density *=1.25;
AliMixture(36,"Alumina1",amat,zmat,density,-2,wmat);
amat[0]=1.;
amat[1]=15.9994;
zmat[0]=1.;
zmat[1]=8.;
wmat[0]=2.;
wmat[1]=1.;
density=1.;
AliMixture(32,"Water",amat,zmat,density,-2,wmat);
AliMedium(0, "Air", 11, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
AliMedium(1, "DriftGas1", 12, 0, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
AliMedium(2, "DriftGas2", 13, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
AliMedium(3,"CO2",10,0, iSXFLD, sXMGMX, 10., 999.,.1, .001, .001);
AliMedium(20, "DriftGas3", 40, 1, iSXFLD, sXMGMX, 10., 999.,.1,.001, .001);
AliMedium(4,"Al",23,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(5,"Kevlar",14,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(6,"Nomex",15,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(7,"Makrolon",16,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(8,"Mylar",18,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(9,"Tedlar",17,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(10,"Prepreg1",19,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(11,"Prepreg2",20,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(12,"Prepreg3",21,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(13,"Epoxy",26,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(14,"Cu",25,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(15,"Si",24,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(16,"G10",22,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(17,"Plexiglas",27,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(18,"Steel",29,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(19,"Peek",30,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(21,"Alumina",31,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(22,"Water",32,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(23,"Brass",33,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
AliMedium(24,"Epoxyfm",34,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(25,"Epoxy1",35,0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
AliMedium(26,"Alumina1",36,0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
}
void AliTPC::GenerNoise(Int_t tablesize)
{
if (fTPCParam==0) {
fNoiseDepth=0;
return;
}
if (fNoiseTable) delete[] fNoiseTable;
fNoiseTable = new Float_t[tablesize];
fNoiseDepth = tablesize;
fCurrentNoise =0;
Float_t norm = fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac();
for (Int_t i=0;i<tablesize;i++) fNoiseTable[i]= gRandom->Gaus(0,norm);
}
Float_t AliTPC::GetNoise()
{
if (fCurrentNoise>=fNoiseDepth) fCurrentNoise=0;
return fNoiseTable[fCurrentNoise++];
}
Bool_t AliTPC::IsSectorActive(Int_t sec) const
{
if (!fActiveSectors) return kTRUE;
else return fActiveSectors[sec];
}
void AliTPC::SetActiveSectors(Int_t * sectors, Int_t n)
{
SetTreeAddress();
if (!fActiveSectors) fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kFALSE;
for (Int_t i=0;i<n;i++)
if ((sectors[i]>=0) && sectors[i]<fTPCParam->GetNSector()) fActiveSectors[sectors[i]]=kTRUE;
}
void AliTPC::SetActiveSectors(Int_t flag)
{
SetTreeAddress();
if (fHitType==0) return;
if (!fActiveSectors) fActiveSectors = new Bool_t[fTPCParam->GetNSector()];
if (flag) {
for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kTRUE;
return;
}
for (Int_t i=0;i<fTPCParam->GetNSector();i++) fActiveSectors[i]=kFALSE;
if (fLoader->TreeH() == 0x0)
{
AliFatal("Can not find TreeH in folder");
return;
}
if (fHitType>1) fLoader->TreeH()->GetBranch("TPC2");
else fLoader->TreeH()->GetBranch("TPC");
Stat_t ntracks = fLoader->TreeH()->GetEntries();
AliDebug(1,Form("Got %d tracks", (Int_t) ntracks));
for(Int_t track=0;track<ntracks;track++) {
ResetHits();
if (fTrackHits && fHitType&4) {
TBranch * br1 = fLoader->TreeH()->GetBranch("fVolumes");
TBranch * br2 = fLoader->TreeH()->GetBranch("fNVolumes");
br1->GetEvent(track);
br2->GetEvent(track);
Int_t *volumes = fTrackHits->GetVolumes();
for (Int_t j=0;j<fTrackHits->GetNVolumes(); j++) {
if (volumes[j]>-1 && volumes[j]<fTPCParam->GetNSector()) {
fActiveSectors[volumes[j]]=kTRUE;
}
else {
AliError(Form("Volume %d -> sector number %d is outside (0..%d)",
j,
volumes[j],
fTPCParam->GetNSector()));
}
}
}
}
}
void AliTPC::Digits2Raw()
{
static const Int_t kThreshold = 0;
fLoader->LoadDigits();
TTree* digits = fLoader->TreeD();
if (!digits) {
AliError("No digits tree");
return;
}
AliSimDigits digarr;
AliSimDigits* digrow = &digarr;
digits->GetBranch("Segment")->SetAddress(&digrow);
const char* fileName = "AliTPCDDL.dat";
AliTPCBuffer* buffer = new AliTPCBuffer(fileName);
buffer->SetVerbose(0);
Int_t nEntries = Int_t(digits->GetEntries());
Int_t previousSector = -1;
Int_t subSector = 0;
for (Int_t i = 0; i < nEntries; i++) {
digits->GetEntry(i);
Int_t sector, row;
fTPCParam->AdjustSectorRow(digarr.GetID(), sector, row);
if(previousSector != sector) {
subSector = 0;
previousSector = sector;
}
if (sector < 36) {
if (row != 30) {
buffer->WriteRowBinary(kThreshold, digrow, 0, 0, 0,
sector, subSector, row);
} else {
buffer->WriteRowBinary(kThreshold, digrow, 37, 48, 1,
sector, subSector, row);
subSector = 1;
buffer->WriteRowBinary(kThreshold, digrow, 37, 48, 2,
sector, subSector, row);
}
} else {
if (row == 54) subSector = 2;
if ((row != 27) && (row != 76)) {
buffer->WriteRowBinary(kThreshold, digrow, 0, 0, 0,
sector, subSector, row);
} else if (row == 27) {
buffer->WriteRowBinary(kThreshold, digrow, 43, 46, 2,
sector, subSector, row);
subSector = 1;
buffer->WriteRowBinary(kThreshold, digrow, 43, 46, 1,
sector, subSector, row);
} else if (row == 76) {
buffer->WriteRowBinary(kThreshold, digrow, 33, 88, 2,
sector, subSector, row);
subSector = 3;
buffer->WriteRowBinary(kThreshold, digrow, 33, 88, 1,
sector, subSector, row);
}
}
}
delete buffer;
fLoader->UnloadDigits();
AliTPCDDLRawData rawWriter;
rawWriter.SetVerbose(0);
rawWriter.RawData(fileName);
gSystem->Unlink(fileName);
}
Bool_t AliTPC::Raw2SDigits(AliRawReader* rawReader){
if (fLoader->TreeS() == 0x0 ) {
fLoader->MakeTree("S");
}
if(fDefaults == 0) SetDefaults();
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
arr->MakeTree(fLoader->TreeS());
SetDigitsArray(arr);
fTPCParam->SetZeroSup(0);
const Int_t kmaxTime = fTPCParam->GetMaxTBin();
const Int_t kNIS = fTPCParam->GetNInnerSector();
const Int_t kNOS = fTPCParam->GetNOuterSector();
const Int_t kNS = kNIS + kNOS;
AliTPCROC * roc = AliTPCROC::Instance();
Int_t nRowsMax = roc->GetNRows(roc->GetNSector()-1);
Int_t nPadsMax = roc->GetNPads(roc->GetNSector()-1,nRowsMax-1);
Short_t** allBins = new Short_t*[nRowsMax];
for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
Int_t maxBin = kmaxTime*nPadsMax;
allBins[iRow] = new Short_t[maxBin];
memset(allBins[iRow],0,sizeof(Short_t)*maxBin);
}
for(Int_t iSector = 0; iSector < kNS; iSector++) {
Int_t nRows = fTPCParam->GetNRow(iSector);
Int_t nDDLs = 0, indexDDL = 0;
if (iSector < kNIS) {
nDDLs = 2;
indexDDL = iSector * 2;
}
else {
nDDLs = 4;
indexDDL = (iSector-kNIS) * 4 + kNIS * 2;
}
rawReader->Reset();
AliTPCAltroMapping** mapping =AliTPCcalibDB::Instance()->GetMapping();
AliTPCRawStreamV3 input(rawReader,(AliAltroMapping**)mapping);
rawReader->Select("TPC",indexDDL,indexDDL+nDDLs-1);
for (Int_t iRow = 0; iRow < nRowsMax; iRow++) {
Int_t maxBin = kmaxTime*nPadsMax;
memset(allBins[iRow],0,sizeof(Short_t)*maxBin);
}
while (input.NextDDL()) {
if (input.GetSector() != iSector)
AliFatal(Form("Sector index mismatch ! Expected (%d), but got (%d) !",iSector,input.GetSector()));
while ( input.NextChannel() ) {
Int_t iRow = input.GetRow();
if (iRow < 0 || iRow >= nRows)
AliFatal(Form("Pad-row index (%d) outside the range (%d -> %d) !",
iRow, 0, nRows -1));
Int_t iPad = input.GetPad();
Int_t maxPad = fTPCParam->GetNPads(iSector,iRow);
if (iPad < 0 || iPad >= maxPad)
AliFatal(Form("Pad index (%d) outside the range (%d -> %d) !",
iPad, 0, maxPad -1));
while ( input.NextBunch() ){
Int_t startTbin = (Int_t)input.GetStartTimeBin();
Int_t bunchlength = (Int_t)input.GetBunchLength();
const UShort_t *sig = input.GetSignals();
for (Int_t iTime = 0; iTime<bunchlength; iTime++){
Int_t iTimeBin=startTbin-iTime;
if ( iTimeBin < 0 || iTimeBin >= kmaxTime) {
continue;
}
Int_t maxBin = kmaxTime*maxPad;
if (((iPad*kmaxTime+iTimeBin) >= maxBin) ||
((iPad*kmaxTime+iTimeBin) < 0))
AliFatal(Form("Index outside the allowed range"
" Sector=%d Row=%d Pad=%d Timebin=%d"
" (Max.index=%d)",iSector,iRow,iPad,iTimeBin,maxBin));
allBins[iRow][iPad*kmaxTime+iTimeBin] = sig[iTime];
}
}
}
}
if (fDigitsArray->GetTree()==0) {
AliFatal("Tree not set in fDigitsArray");
}
for (Int_t iRow = 0; iRow < nRows; iRow++) {
AliDigits * dig = fDigitsArray->CreateRow(iSector,iRow);
Int_t maxPad = fTPCParam->GetNPads(iSector,iRow);
for(Int_t iPad = 0; iPad < maxPad; iPad++) {
for(Int_t iTimeBin = 0; iTimeBin < kmaxTime; iTimeBin++) {
Short_t q = allBins[iRow][iPad*kmaxTime + iTimeBin];
if (q <= 0) continue;
q *= 16;
dig->SetDigitFast((Short_t)q,iTimeBin,iPad);
((AliSimDigits*)dig)->SetTrackIDFast( 3141593, iTimeBin,iPad,0);
}
}
fDigitsArray->StoreRow(iSector,iRow);
Int_t ndig = dig->GetDigitSize();
AliDebug(10,
Form("*** Sector, row, compressed digits %d %d %d ***\n",
iSector,iRow,ndig));
fDigitsArray->ClearRow(iSector,iRow);
}
}
TParameter<float> *ph;
Float_t phase;
TTree *digtree = fLoader->TreeD();
if(digtree){
ph = (TParameter<float>*)digtree->GetUserInfo()->FindObject("lhcphase0");
phase = ph->GetVal();
}
else{
phase = 0.;
}
fLoader->TreeS()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",phase));
fLoader->WriteSDigits("OVERWRITE");
if(GetDigitsArray()) delete GetDigitsArray();
SetDigitsArray(0x0);
for (Int_t iRow = 0; iRow < nRowsMax; iRow++)
delete [] allBins[iRow];
delete [] allBins;
return kTRUE;
}
AliDigitizer* AliTPC::CreateDigitizer(AliDigitizationInput* digInput) const
{
return new AliTPCDigitizer(digInput);
}
void AliTPC::SDigits2Digits2(Int_t )
{
GenerNoise(500000);
TTree *t = fLoader->TreeS();
if (t == 0x0) {
fLoader->LoadSDigits("READ");
t = fLoader->TreeS();
if (t == 0x0) {
AliError("Can not get input TreeS");
return;
}
}
if (fLoader->TreeD() == 0x0) fLoader->MakeTree("D");
AliSimDigits digarr, *dummy=&digarr;
TBranch* sdb = t->GetBranch("Segment");
if (sdb == 0x0) {
AliError("Can not find branch with segments in TreeS.");
return;
}
sdb->SetAddress(&dummy);
Stat_t nentries = t->GetEntries();
fTPCParam->SetZeroSup(2);
Int_t zerosup = fTPCParam->GetZeroSup();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
arr->MakeTree(fLoader->TreeD());
AliTPCParam * par = fTPCParam;
for (Int_t n=0; n<nentries; n++) {
t->GetEvent(n);
Int_t sec, row;
if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) {
AliWarning(Form("Invalid segment ID ! %d",digarr.GetID()));
continue;
}
if (!IsSectorActive(sec)) continue;
AliSimDigits * digrow =(AliSimDigits*) arr->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() - 1;
for (Int_t i= 0; i<nelems; i++){
Float_t q = TMath::Nint(Float_t(*pamp0)/16.+GetNoise());
if (q>zerosup){
if (q>saturation) q=saturation;
*pamp1=(Short_t)q;
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);
}
fLoader->WriteDigits("OVERWRITE");
delete arr;
}
void AliTPC::SetDefaults(){
AliRunLoader* rl = (AliRunLoader*)fLoader->GetEventFolder()->FindObject(AliRunLoader::GetRunLoaderName());
rl->CdGAFile();
AliTPCParamSR *param = (AliTPCParamSR*)AliTPCcalibDB::Instance()->GetParameters();
if(!param){
AliFatal("No TPC parameters found");
return;
}
if (!param->IsGeoRead()){
param->ReadGeoMatrices();
}
AliTPCPRF2D * prfinner = new AliTPCPRF2D;
AliTPCPRF2D * prfouter1 = new AliTPCPRF2D;
AliTPCPRF2D * prfouter2 = new AliTPCPRF2D;
char strgamma4[1000];
snprintf(strgamma4,1000,"AliTPCRF1D::Gamma4((x-0.135+%f)*%f,55,160)",3*param->GetZSigma(), 1000000000*param->GetTSample()/param->GetZWidth());
TF1 * fgamma4 = new TF1("fgamma4",strgamma4, -1,1);
AliTPCRF1D * rf = new AliTPCRF1D(kTRUE,1000);
rf->SetParam(fgamma4,param->GetZWidth(), 1,0.2);
rf->SetOffset(3*param->GetZSigma());
rf->Update();
TDirectory *savedir=gDirectory;
if (fIsGEM==0){
printf ("TPC MWPC readout\n");
TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
if (!f->IsOpen())
AliFatal("Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !");
TString s;
prfinner->Read("prf_07504_Gati_056068_d02");
s=prfinner->GetGRF()->GetName();
s+="in";
prfinner->GetGRF()->SetName(s.Data());
prfouter1->Read("prf_10006_Gati_047051_d03");
s=prfouter1->GetGRF()->GetName();
s+="out1";
prfouter1->GetGRF()->SetName(s.Data());
prfouter2->Read("prf_15006_Gati_047051_d03");
s=prfouter2->GetGRF()->GetName();
s+="out2";
prfouter2->GetGRF()->SetName(s.Data());
f->Close();
}
if (fIsGEM==1){
printf ("TPC GEM readout\n");
TFile *f=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2dGEM.root");
if (!f->IsOpen())
AliFatal("Can't open $ALICE_ROOT/TPC/AliTPCprf2dGEM.root !");
TString s;
prfinner->Read("prf0");
s=prfinner->GetGRF()->GetName();
s+="in";
prfinner->GetGRF()->SetName(s.Data());
prfouter1->Read("prf1");
s=prfouter1->GetGRF()->GetName();
s+="out1";
prfouter1->GetGRF()->SetName(s.Data());
prfouter2->Read("prf2");
s=prfouter2->GetGRF()->GetName();
s+="out2";
prfouter2->GetGRF()->SetName(s.Data());
f->Close();
}
savedir->cd();
param->SetInnerPRF(prfinner);
param->SetOuter1PRF(prfouter1);
param->SetOuter2PRF(prfouter2);
param->SetTimeRF(rf);
SetParam(param);
fDefaults = 1;
}
void AliTPC::Hits2Digits()
{
if (!fTPCParam->IsGeoRead()){
fTPCParam->ReadGeoMatrices();
}
fLoader->LoadHits("read");
fLoader->LoadDigits("recreate");
AliRunLoader* runLoader = fLoader->GetRunLoader();
for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
Hits2Digits(iEvent);
}
fLoader->UnloadHits();
fLoader->UnloadDigits();
}
void AliTPC::Hits2Digits(Int_t eventnumber)
{
AliRunLoader* rl = (AliRunLoader*)fLoader->GetEventFolder()->FindObject(AliRunLoader::GetRunLoaderName());
rl->GetEvent(eventnumber);
SetActiveSectors();
if (fLoader->TreeH() == 0x0) {
if(fLoader->LoadHits()) {
AliError("Can not load hits.");
}
}
SetTreeAddress();
if (fLoader->TreeD() == 0x0 ) {
fLoader->MakeTree("D");
if (fLoader->TreeD() == 0x0 ) {
AliError("Can not get TreeD");
return;
}
}
if(fDefaults == 0) SetDefaults();
GenerNoise(500000);
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
arr->MakeTree(fLoader->TreeD());
SetDigitsArray(arr);
fDigitsSwitch=0;
Float_t lhcph = 0.;
switch (fLHCclockPhaseSw){
case 0:
lhcph=0.;
break;
case 1:
lhcph = (Int_t)(gRandom->Rndm()/0.25);
break;
case 2:
lhcph=0.;
break;
}
fLoader->TreeD()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",lhcph));
for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++)
if (IsSectorActive(isec)) {
AliDebug(1,Form("Hits2Digits: Sector %d is active.",isec));
Hits2DigitsSector(isec);
}
else {
AliDebug(1,Form("Hits2Digits: Sector %d is NOT active.",isec));
}
fLoader->WriteDigits("OVERWRITE");
if(GetDigitsArray()) delete GetDigitsArray();
SetDigitsArray(0x0);
}
void AliTPC::Hits2SDigits2(Int_t eventnumber)
{
AliRunLoader* rl = fLoader->GetRunLoader();
rl->GetEvent(eventnumber);
if (fLoader->TreeH() == 0x0) {
if(fLoader->LoadHits()) {
AliError("Can not load hits.");
return;
}
}
SetTreeAddress();
if (fLoader->TreeS() == 0x0 ) {
fLoader->MakeTree("S");
}
if(fDefaults == 0) SetDefaults();
GenerNoise(500000);
if(GetDigitsArray()) delete GetDigitsArray();
AliTPCDigitsArray *arr = new AliTPCDigitsArray;
arr->SetClass("AliSimDigits");
arr->Setup(fTPCParam);
arr->MakeTree(fLoader->TreeS());
SetDigitsArray(arr);
fDigitsSwitch=1;
Float_t lhcph = 0.;
switch (fLHCclockPhaseSw){
case 0:
lhcph=0.;
break;
case 1:
lhcph = (Int_t)(gRandom->Rndm()/0.25);
break;
case 2:
lhcph=0.;
break;
}
fLoader->TreeS()->GetUserInfo()->Add(new TParameter<float>("lhcphase0",lhcph));
fTPCParam->SetZeroSup(0);
for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++)
if (IsSectorActive(isec)) {
Hits2DigitsSector(isec);
}
fLoader->WriteSDigits("OVERWRITE");
if(GetDigitsArray()) delete GetDigitsArray();
SetDigitsArray(0x0);
}
void AliTPC::Hits2SDigits()
{
if (!fTPCParam->IsGeoRead()){
fTPCParam->ReadGeoMatrices();
}
fLoader->LoadHits("read");
fLoader->LoadSDigits("recreate");
AliRunLoader* runLoader = fLoader->GetRunLoader();
for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
runLoader->GetEvent(iEvent);
SetTreeAddress();
SetActiveSectors();
Hits2SDigits2(iEvent);
}
fLoader->UnloadHits();
fLoader->UnloadSDigits();
if (fDebugStreamer) {
delete fDebugStreamer;
fDebugStreamer=0;
}
}
void AliTPC::Hits2DigitsSector(Int_t isec)
{
if(fDefaults == 0) SetDefaults();
TTree *tH = fLoader->TreeH();
if (tH == 0x0) {
AliFatal("Can not find TreeH in folder");
return;
}
Stat_t ntracks = tH->GetEntries();
Int_t nrows =fTPCParam->GetNRow(isec);
TObjArray **row=new TObjArray* [nrows+2];
for(Int_t j=0;j<nrows+2;j++) row[j]=0;
MakeSector(isec,nrows,tH,ntracks,row);
Int_t i;
if (fDigitsArray->GetTree()==0) {
AliFatal("Tree not set in fDigitsArray");
}
for (i=0;i<nrows;i++){
AliDigits * dig = fDigitsArray->CreateRow(isec,i);
DigitizeRow(i,isec,row);
fDigitsArray->StoreRow(isec,i);
Int_t ndig = dig->GetDigitSize();
AliDebug(10,
Form("*** Sector, row, compressed digits %d %d %d ***\n",
isec,i,ndig));
fDigitsArray->ClearRow(isec,i);
}
for(i=0;i<nrows+2;i++){
row[i]->Delete();
delete row[i];
}
delete [] row;
}
void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows)
{
Float_t zerosup = fTPCParam->GetZeroSup();
AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetDedxGainFactor();
AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
AliTPCCalROC * gainROC = gainTPC->GetCalROC(isec);
AliTPCCalROC * noiseROC = noiseTPC->GetCalROC(isec);
fCurrentIndex[1]= isec;
Int_t nofPads = fTPCParam->GetNPads(isec,irow);
Int_t nofTbins = fTPCParam->GetMaxTBin();
Int_t indexRange[4];
TMatrixF *m1 = new TMatrixF(0,nofPads,0,nofTbins);
TMatrixF *m2 = new TMatrixF(0,nofPads,0,nofTbins);
TMatrixF &total = *m1;
Int_t nofDigits = nofPads*nofTbins;
Float_t **pList = new Float_t* [nofDigits];
Int_t lp;
Int_t i1;
for(lp=0;lp<nofDigits;lp++)pList[lp]=0;
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;i1<nTracks;i1++){
fCurrentIndex[2]= row;
fCurrentIndex[3]=irow+1;
if (row==irow+1){
m2->Zero();
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<nofTbins;it++){
for(Int_t ip=0;ip<nofPads;ip++){
gi++;
Float_t q=total(ip,it);
if(fDigitsSwitch == 0){
Float_t gain = gainROC->GetValue(irow,ip);
Float_t noisePad = noiseROC->GetValue(irow,ip);
q*=gain;
q+=GetNoise()*noisePad;
if(q <=fzerosup) continue;
q = TMath::Nint(q);
if(q >= fTPCParam->GetADCSat()) q = fTPCParam->GetADCSat() - 1;
}
else {
if(q <= 0.) continue;
if(q>2000.) q=2000.;
q *= 16.;
q = TMath::Nint(q);
}
for(Int_t j1=0;j1<3;j1++){
tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -2;
}
/*
<A NAME="AliDigits"></A>
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);
}
}
}
if(!fDigitsSwitch) ((AliSimDigits*)dig)->GlitchFilter();
for(lp=0;lp<nofDigits;lp++){
if(pList[lp]) delete [] pList[lp];
}
delete [] pList;
delete m1;
delete m2;
}
Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr,
TMatrixF *m1, TMatrixF *m2,Int_t *indexRange)
{
TVector *tv;
tv = (TVector*)p1->At(ntr);
TVector &v = *tv;
Float_t label = v(0);
Int_t centralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3]-1))/2;
Int_t nElectrons = (tv->GetNrows()-1)/5;
indexRange[0]=9999;
indexRange[1]=-1;
indexRange[2]=9999;
indexRange[3]=-1;
TMatrixF &signal = *m1;
TMatrixF &total = *m2;
TParameter<float> *ph;
if(fDigitsSwitch){
ph = (TParameter<float>*)fLoader->TreeS()->GetUserInfo()->FindObject("lhcphase0");
}
else{
ph = (TParameter<float>*)fLoader->TreeD()->GetUserInfo()->FindObject("lhcphase0");
}
for(Int_t nel=0; nel<nElectrons; nel++){
Int_t idx=nel*5;
Float_t aval = v(idx+4);
Float_t eltoadcfac=aval*fTPCParam->GetTotalNormFac();
Float_t xyz[4]={v(idx+1),v(idx+2),v(idx+3),v(idx+5)};
Int_t n = ((AliTPCParamSR*)fTPCParam)->CalcResponseFast(xyz,fCurrentIndex,
fCurrentIndex[3],ph->GetVal());
Int_t *index = fTPCParam->GetResBin(0);
Float_t *weight = & (fTPCParam->GetResWeight(0));
if (n>0) for (Int_t i =0; i<n; i++){
Int_t pad=index[1]+centralPad;
if (pad>=0){
Int_t time=index[2];
Float_t qweight = *(weight)*eltoadcfac;
if (m1!=0) signal(pad,time)+=qweight;
total(pad,time)+=qweight;
if (indexRange[0]>pad) indexRange[0]=pad;
if (indexRange[1]<pad) indexRange[1]=pad;
if (indexRange[2]>time) indexRange[2]=time;
if (indexRange[3]<time) indexRange[3]=time;
index+=3;
weight++;
}
}
}
return label;
}
void AliTPC::GetList(Float_t label,Int_t np,TMatrixF *m,
Int_t *indexRange, Float_t **pList)
{
TMatrixF &signal = *m;
for(Int_t it=indexRange[2];it<indexRange[3]+1;it++){
for(Int_t ip=indexRange[0];ip<indexRange[1]+1;ip++){
if(signal(ip,it)<0.5) continue;
Int_t globalIndex = it*np+ip;
if(!pList[globalIndex]){
pList[globalIndex] = new Float_t [6];
*pList[globalIndex] = -1.;
*(pList[globalIndex]+1) = -1.;
*(pList[globalIndex]+2) = -1.;
*(pList[globalIndex]+3) = -1.;
*(pList[globalIndex]+4) = -1.;
*(pList[globalIndex]+5) = -1.;
*pList[globalIndex] = label;
*(pList[globalIndex]+3) = signal(ip,it);
}
else {
Float_t highest = *(pList[globalIndex]+3);
Float_t middle = *(pList[globalIndex]+4);
Float_t lowest = *(pList[globalIndex]+5);
if(signal(ip,it)<lowest) continue;
if (signal(ip,it)>highest){
*(pList[globalIndex]+5) = middle;
*(pList[globalIndex]+4) = highest;
*(pList[globalIndex]+3) = signal(ip,it);
*(pList[globalIndex]+2) = *(pList[globalIndex]+1);
*(pList[globalIndex]+1) = *pList[globalIndex];
*pList[globalIndex] = label;
}
else if (signal(ip,it)>middle){
*(pList[globalIndex]+5) = middle;
*(pList[globalIndex]+4) = signal(ip,it);
*(pList[globalIndex]+2) = *(pList[globalIndex]+1);
*(pList[globalIndex]+1) = label;
}
else{
*(pList[globalIndex]+5) = signal(ip,it);
*(pList[globalIndex]+2) = label;
}
}
}
}
}
void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
Stat_t ntracks,TObjArray **row)
{
AliTPCcalibDB* const calib=AliTPCcalibDB::Instance();
AliTPCCorrection * correctionDist = calib->GetTPCComposedCorrection();
AliTPCRecoParam *tpcrecoparam = calib->GetRecoParam(0);
if (tpcrecoparam->GetUseExBCorrection()) {
if (gAlice){
if (!calib->GetExB()){
AliMagF * field = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField());
if (field) {
calib->SetExBField(field);
}
}
}
} else if (tpcrecoparam->GetUseComposedCorrection()) {
AliMagF * field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
Double_t bzpos[3]={0,0,0};
if (!correctionDist) correctionDist = calib->GetTPCComposedCorrection(field->GetBz(bzpos));
if (!correctionDist){
AliFatal("Correction map does not exist. Check the OCDB or your setup");
}
}
Float_t gasgain = fTPCParam->GetGasGain();
gasgain = gasgain/fGainFactor;
const Int_t timeStamp = fLoader->GetRunLoader()->GetHeader()->GetTimeStamp();
Double_t correctionHVandPT = calib->GetGainCorrectionHVandPT(timeStamp, calib->GetRun(), isec, 5 ,tpcrecoparam->GetGainCorrectionHVandPTMode());
gasgain*=correctionHVandPT;
Int_t i;
Float_t xyz[5]={0,0,0,0,0};
AliTPChit *tpcHit;
TBranch * branch=0;
if (fHitType>1) branch = TH->GetBranch("TPC2");
else branch = TH->GetBranch("TPC");
Int_t *nofElectrons = new Int_t [nrows+2];
TVector **tracks = new TVector* [nrows+2];
for(i=0; i<nrows+2; i++){
row[i] = new TObjArray;
nofElectrons[i]=0;
tracks[i]=0;
}
Int_t previousTrack,currentTrack;
previousTrack = -1;
for(Int_t track=0;track<ntracks;track++){
Bool_t isInSector=kTRUE;
ResetHits();
isInSector = TrackInVolume(isec,track);
if (!isInSector) continue;
branch->GetEntry(track);
tpcHit = (AliTPChit*)FirstHit(-1);
while(tpcHit){
Int_t sector=tpcHit->fSector;
if(sector != isec){
tpcHit = (AliTPChit*) NextHit();
continue;
}
if(((fTPCParam->GetZLength(isec)-TMath::Abs(tpcHit->Z()))
/fTPCParam->GetDriftV()+tpcHit->Time())<fTPCParam->GetGateDelay()) {
tpcHit = (AliTPChit*) NextHit();
continue;
}
currentTrack = tpcHit->Track();
if(currentTrack != previousTrack){
for(i=0;i<nrows+2;i++){
if(previousTrack != -1){
if(nofElectrons[i]>0){
TVector &v = *tracks[i];
v(0) = previousTrack;
tracks[i]->ResizeTo(5*nofElectrons[i]+1);
row[i]->Add(tracks[i]);
}
else {
delete tracks[i];
tracks[i]=0;
}
}
nofElectrons[i]=0;
tracks[i] = new TVector(601);
}
previousTrack=currentTrack;
}
Int_t qI = (Int_t) (tpcHit->fQ);
Float_t time = 1.e6*(fTPCParam->GetZLength(isec)-TMath::Abs(tpcHit->Z()))
/fTPCParam->GetDriftV();
Float_t attProb = fTPCParam->GetAttCoef()*
fTPCParam->GetOxyCont()*time;
Int_t index[3];
index[1]=isec;
for(Int_t nel=0;nel<qI;nel++){
if((gRandom->Rndm(0)) < attProb) continue;
xyz[0]=tpcHit->X();
xyz[1]=tpcHit->Y();
xyz[2]=tpcHit->Z();
if (tpcrecoparam->GetUseExBCorrection()) {
Double_t dxyz0[3],dxyz1[3];
dxyz0[0]=tpcHit->X();
dxyz0[1]=tpcHit->Y();
dxyz0[2]=tpcHit->Z();
if (calib->GetExB()){
calib->GetExB()->CorrectInverse(dxyz0,dxyz1);
}else{
AliError("Not valid ExB calibration");
dxyz1[0]=tpcHit->X();
dxyz1[1]=tpcHit->Y();
dxyz1[2]=tpcHit->Z();
}
xyz[0]=dxyz1[0];
xyz[1]=dxyz1[1];
xyz[2]=dxyz1[2];
} else if (tpcrecoparam->GetUseComposedCorrection()) {
if (correctionDist){
Float_t distPoint[3]={tpcHit->X(),tpcHit->Y(), tpcHit->Z()};
correctionDist->DistortPoint(distPoint, isec);
xyz[0]=distPoint[0];
xyz[1]=distPoint[1];
xyz[2]=distPoint[2];
}
}
Double_t rn=TMath::Max(gRandom->Rndm(0),1.93e-22);
xyz[3]= (Float_t) (-gasgain*TMath::Log(rn));
index[0]=1;
TransportElectron(xyz,index);
Int_t rowNumber;
Int_t padrow = fTPCParam->GetPadRow(xyz,index);
Float_t correction =0;
if (tpcrecoparam->GetUseExBCorrection()) {
if (calib->GetPadTime0()){
if (!calib->GetPadTime0()->GetCalROC(isec)) continue;
Int_t npads = fTPCParam->GetNPads(isec,padrow);
Int_t pad = TMath::Nint(xyz[1]+npads/2);
if (pad<0) pad=0;
if (pad>=npads) pad=npads-1;
correction = calib->GetPadTime0()->GetCalROC(isec)->GetValue(padrow,pad);
if (fDebugStreamer){
(*fDebugStreamer)<<"Time0"<<
"isec="<<isec<<
"padrow="<<padrow<<
"pad="<<pad<<
"x0="<<xyz[0]<<
"x1="<<xyz[1]<<
"x2="<<xyz[2]<<
"hit.="<<tpcHit<<
"cor="<<correction<<
"\n";
}
}
}
if (AliTPCcalibDB::Instance()->IsTrgL0()){
AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
if (ctp){
Double_t delay = ctp->GetDelayL1L0()*0.000000025;
xyz[2]+=delay/fTPCParam->GetTSample();
}
}
if (tpcrecoparam->GetUseExBCorrection()) xyz[2]+=correction;
xyz[2]+=fTPCParam->GetNTBinsL1();
xyz[2]+=tpcHit->Time()/fTPCParam->GetTSample();
xyz[4] =0;
rowNumber = index[2]+1;
if ((rowNumber<0)||rowNumber>fTPCParam->GetNRow(isec)+1) continue;
nofElectrons[rowNumber]++;
if(nofElectrons[rowNumber]>120){
Int_t range = tracks[rowNumber]->GetNrows();
if((nofElectrons[rowNumber])>(range-1)/5){
tracks[rowNumber]->ResizeTo(range+500);
}
}
TVector &v = *tracks[rowNumber];
Int_t idx = 5*nofElectrons[rowNumber]-4;
Real_t * position = &(((TVector&)v)(idx));
memcpy(position,xyz,5*sizeof(Float_t));
}
tpcHit = (AliTPChit*)NextHit();
}
}
for(i=0;i<nrows+2;i++){
if(nofElectrons[i]>0){
TVector &v = *tracks[i];
v(0) = previousTrack;
tracks[i]->ResizeTo(5*nofElectrons[i]+1);
row[i]->Add(tracks[i]);
}
else{
delete tracks[i];
tracks[i]=0;
}
}
delete [] tracks;
delete [] nofElectrons;
}
void AliTPC::Init()
{
AliDebug(1,"*********************************************");
}
void AliTPC::ResetDigits()
{
fNdigits = 0;
if (fDigits) fDigits->Clear();
}
void AliTPC::SetSens(Int_t sens)
{
fSens = sens;
}
void AliTPC::SetSide(Float_t side=0.)
{
fSide = side;
}
void AliTPC::TransportElectron(Float_t *xyz, Int_t *index)
{
fTPCParam->Transform1to2(xyz,index);
Float_t driftl=xyz[2];
if(driftl<0.01) driftl=0.01;
driftl=TMath::Sqrt(driftl);
Float_t sigT = driftl*(fTPCParam->GetDiffT());
Float_t sigL = driftl*(fTPCParam->GetDiffL());
xyz[0]=gRandom->Gaus(xyz[0],sigT);
xyz[1]=gRandom->Gaus(xyz[1],sigT);
xyz[2]=gRandom->Gaus(xyz[2],sigL);
if (fTPCParam->GetMWPCReadout()==kTRUE){
Float_t dx = fTPCParam->Transform2to2NearestWire(xyz,index);
xyz[1]+=dx*(fTPCParam->GetOmegaTau());
}
}
ClassImp(AliTPChit)
AliTPChit::AliTPChit()
:AliHit(),
fSector(0),
fPadRow(0),
fQ(0),
fTime(0)
{
}
AliTPChit::AliTPChit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits)
:AliHit(shunt,track),
fSector(0),
fPadRow(0),
fQ(0),
fTime(0)
{
fSector = vol[0];
fPadRow = vol[1];
fX = hits[0];
fY = hits[1];
fZ = hits[2];
fQ = hits[3];
fTime = hits[4];
}
void AliTPC::MakeBranch(Option_t *option)
{
AliDebug(1,"");
if (fHitType<2) return;
char branchname[10];
snprintf(branchname,10,"%s2",GetName());
const char *cH = strstr(option,"H");
if (fTrackHits && fLoader->TreeH() && cH && fHitType&4) {
AliDebug(1,"Making branch for Type 4 Hits");
fLoader->TreeH()->Branch(branchname,"AliTPCTrackHitsV2",&fTrackHits,fBufferSize,99);
}
}
void AliTPC::SetTreeAddress()
{
if (fHitType<=1) {
if (fHits == 0x0 ) fHits = new TClonesArray("AliTPChit", 176);
AliDetector::SetTreeAddress();
}
if (fHitType>1) SetTreeAddress2();
}
void AliTPC::SetTreeAddress2()
{
AliDebug(1,"");
TBranch *branch;
char branchname[20];
snprintf(branchname,20,"%s2",GetName());
TTree *treeH = fLoader->TreeH();
if ((treeH)&&(fHitType&4)) {
branch = treeH->GetBranch(branchname);
if (branch) {
branch->SetAddress(&fTrackHits);
AliDebug(1,"fHitType&4 Setting");
}
else
AliDebug(1,"fHitType&4 Failed (can not find branch)");
}
}
void AliTPC::FinishPrimary()
{
if (fTrackHits &&fHitType&4) fTrackHits->FlushHitStack();
}
void AliTPC::AddHit2(Int_t track, Int_t *vol, Float_t *hits)
{
Int_t rtrack;
if (fIshunt) {
int primary = gAlice->GetMCApp()->GetPrimary(track);
gAlice->GetMCApp()->Particle(primary)->SetBit(kKeepBit);
rtrack=primary;
} else {
rtrack=track;
gAlice->GetMCApp()->FlagTrack(track);
}
if (fTrackHits && fHitType&4)
fTrackHits->AddHitKartez(vol[0],rtrack, hits[0],
hits[1],hits[2],(Int_t)hits[3],hits[4]);
}
void AliTPC::ResetHits()
{
if (fHitType&1) AliDetector::ResetHits();
if (fHitType>1) ResetHits2();
}
void AliTPC::ResetHits2()
{
if (fTrackHits && fHitType&4) fTrackHits->Clear();
}
AliHit* AliTPC::FirstHit(Int_t track)
{
if (fHitType>1) return FirstHit2(track);
return AliDetector::FirstHit(track);
}
AliHit* AliTPC::NextHit()
{
if (fHitType>1) return NextHit2();
return AliDetector::NextHit();
}
AliHit* AliTPC::FirstHit2(Int_t track)
{
if(track>=0) {
gAlice->GetMCApp()->ResetHits();
fLoader->TreeH()->GetEvent(track);
}
if (fTrackHits && fHitType&4) {
fTrackHits->First();
return fTrackHits->GetHit();
}
else return 0;
}
AliHit* AliTPC::NextHit2()
{
if (fTrackHits) {
fTrackHits->Next();
return fTrackHits->GetHit();
}
else
return 0;
}
void AliTPC::RemapTrackHitIDs(Int_t *map)
{
if (!fTrackHits) return;
if (fTrackHits && fHitType&4){
TClonesArray * arr = fTrackHits->GetArray();;
for (Int_t i=0;i<arr->GetEntriesFast();i++){
AliTrackHitsParamV2 * info = (AliTrackHitsParamV2 *)(arr->At(i));
info->SetTrackID(map[info->GetTrackID()]);
}
}
}
Bool_t AliTPC::TrackInVolume(Int_t id,Int_t track)
{
if (fTrackHits && fHitType&4) {
TBranch * br1 = fLoader->TreeH()->GetBranch("fVolumes");
TBranch * br2 = fLoader->TreeH()->GetBranch("fNVolumes");
br2->GetEvent(track);
br1->GetEvent(track);
Int_t *volumes = fTrackHits->GetVolumes();
Int_t nvolumes = fTrackHits->GetNVolumes();
if (!volumes && nvolumes>0) {
AliWarning(Form("Problematic track\t%d\t%d",track,nvolumes));
return kFALSE;
}
for (Int_t j=0;j<nvolumes; j++)
if (volumes[j]==id) return kTRUE;
}
if (fHitType&1) {
TBranch * br = fLoader->TreeH()->GetBranch("fSector");
br->GetEvent(track);
for (Int_t j=0;j<fHits->GetEntriesFast();j++){
if ( ((AliTPChit*)fHits->At(j))->fSector==id) return kTRUE;
}
}
return kFALSE;
}
AliLoader* AliTPC::MakeLoader(const char* topfoldername)
{
fLoader = new AliTPCLoader(GetName(),topfoldername);
return fLoader;
}
AliTPCParam* AliTPC::LoadTPCParam(TFile *file) {
char paramName[50];
snprintf(paramName,50,"75x40_100x60_150x60");
AliTPCParam *paramTPC=(AliTPCParam*)file->Get(paramName);
if (paramTPC) {
AliDebugClass(1,Form("TPC parameters %s found.",paramName));
} else {
AliWarningClass("TPC parameters not found. Create new (they may be incorrect)");
paramTPC = AliTPCcalibDB::Instance()->GetParameters();
if (!paramTPC->IsGeoRead()){
paramTPC->ReadGeoMatrices();
}
}
return paramTPC;
}