/*
<img src="picts/ITS/ITS_Analysis_schema.gif">
</pre>
<br clear=left>
<font size=+2 color=red>
<p>Roberto Barbera is in charge of the ITS Offline code (1999).
<a href="mailto:roberto.barbera@ct.infn.it">Roberto Barbera</a>.
</font>
<pre>
*/
//End_Html
/*
<img src="picts/ITS/AliITS_Class_Diagram.gif">
</pre>
<br clear=left>
<font size=+2 color=red>
<p>This show the class diagram of the different elements that are part of
the AliITS class.
</font>
<pre>
*/
//End_Html
#include <stdlib.h>
#include <TClonesArray.h>
#include <TFile.h>
#include <TParticle.h>
#include <TString.h>
#include <TTree.h>
#include <TVirtualMC.h>
#include <TMath.h>
#include "AliDetector.h"
#include "AliITSU.h"
#include "AliITSLoader.h"
#include "AliITSULoader.h"
#include "AliITSUHit.h"
#include "AliITSUSDigit.h"
#include "AliITSUSimulation.h"
#include "AliITSUSimulationPix.h"
#include "AliITSsimulationFastPoints.h"
#include "AliMC.h"
#include "AliITSUDigitizer.h"
#include "AliITSRecPoint.h"
#include "AliRawReader.h"
#include "AliRun.h"
#include "AliLog.h"
#include "AliITSdigit.h"
#include "AliITSUChip.h"
#include "AliITSUDigitPix.h"
#include "AliITSsegmentation.h"
#include "AliITSUSegmentationPix.h"
#include "AliITSUSimuParam.h"
#include "AliITSFOSignalsSPD.h"
#include "AliITSUParamList.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
using namespace TMath;
ClassImp(AliITSU)
AliITSU::AliITSU() :
AliDetector()
,fEuclidOut(0)
,fNLayers(0)
,fIdSens(0)
,fLayerName(0)
,fTiming(kFALSE)
,fGeomTGeo(0)
,fSimuParam(0)
,fModA(0)
,fpSDigits(0)
,fSDigits(0)
,fDetHits(0)
,fChipHits(0)
,fDetDigits(0)
,fSensMap(0)
,fSimModelLr(0)
,fSegModelLr(0)
,fResponseLr(0)
,fCalibration(0)
,fRunNumber(0)
,fSimInitDone(kFALSE)
{
}
AliITSU::AliITSU(const Char_t *title, Int_t nlay) :
AliDetector("ITS",title)
,fEuclidOut(0)
,fNLayers(nlay)
,fIdSens(0)
,fLayerName(0)
,fTiming(kFALSE)
,fGeomTGeo(0)
,fSimuParam(0)
,fModA(0)
,fpSDigits(0)
,fSDigits(0)
,fDetHits(0)
,fChipHits(0)
,fDetDigits(0)
,fSensMap(0)
,fSimModelLr(0)
,fSegModelLr(0)
,fResponseLr(0)
,fCalibration(0)
,fRunNumber(0)
,fSimInitDone(kFALSE)
{
AliMC* mc = gAlice->GetMCApp();
if( mc && mc->GetHitLists() ) {
fHits = new TClonesArray("AliITSUHit",100);
mc->AddHitList(fHits);
}
}
AliITSU::~AliITSU()
{
delete fHits;
delete fSensMap;
if (fSimModelLr) {
for (int i=fNLayers;i--;) {
for (int j=i;j--;) if (fSimModelLr[j]==fSimModelLr[i]) fSimModelLr[j] = 0;
delete fSimModelLr[i];
}
delete[] fSimModelLr;
}
if (fSegModelLr) {
for (int i=fNLayers;i--;) {
for (int j=i;j--;) if (fSegModelLr[j]==fSegModelLr[i]) fSegModelLr[j] = 0;
delete fSegModelLr[i];
}
delete[] fSegModelLr;
}
delete[] fResponseLr;
delete[] fLayerName;
delete[] fIdSens;
int nmod = fGeomTGeo ? fGeomTGeo->GetNChips() : 0;
if (fChipHits) fChipHits->Delete();
delete fChipHits;
if(fModA){
for(Int_t j=0; j<nmod; j++){
fModA[j]->Delete();
delete fModA[j];
}
delete[] fModA;
}
if (fpSDigits) { fpSDigits->Delete(); delete fpSDigits; }
if (fSDigits) { fSDigits->Delete(); delete fSDigits; }
delete fGeomTGeo;
}
AliDigitizer* AliITSU::CreateDigitizer(AliDigitizationInput* manager) const
{
return new AliITSUDigitizer(manager);
}
void AliITSU::Init()
{
if (!fIdSens) fIdSens = new Int_t[fNLayers];
for(int i=0;i<fNLayers;i++) fIdSens[i] = TVirtualMC::GetMC() ? TVirtualMC::GetMC()->VolId(fLayerName[i]) : 0;
fGeomTGeo = new AliITSUGeomTGeo(kTRUE);
InitSimulation();
}
void AliITSU::MakeBranch(Option_t* option)
{
Bool_t cH = (strstr(option,"H")!=0);
Bool_t cS = (strstr(option,"S")!=0);
Bool_t cD = (strstr(option,"D")!=0);
if(cH && (fHits == 0x0)) fHits = new TClonesArray("AliITSUHit", 1560);
AliDetector::MakeBranch(option);
if(cS) MakeBranchS(0);
if(cD) MakeBranchD(0);
}
void AliITSU::MakeBranchS(const char* fl)
{
Int_t buffersize = 4000;
char branchname[31];
snprintf(branchname,30,"%s",GetName());
if(fLoader->TreeS()) MakeBranchInTree(fLoader->TreeS(),branchname,&fSDigits,buffersize,fl);
}
void AliITSU::MakeBranchD(const char* file)
{
MakeBranchInTreeD(fLoader->TreeD(),file);
}
void AliITSU:: MakeBranchInTreeD(TTree* treeD, const char* file)
{
if (!treeD) {AliFatal("No tree provided");}
Int_t buffersize = 4000;
if (!fDetDigits) InitArrays();
for (Int_t i=0;i<kNChipTypes;i++) {
ResetDigits(i);
TClonesArray* darr = (TClonesArray*)fDetDigits->At(i);
AliDetector::MakeBranchInTree(treeD,Form("%sDigits%s",GetName(),fGeomTGeo->GetChipTypeName(i)),
&darr,buffersize,file);
}
}
void AliITSU::InitArrays()
{
if(!fLoader) MakeLoader(AliConfig::GetDefaultEventFolderName());
fDetDigits = new TObjArray(kNChipTypes);
for (Int_t i=0;i<kNChipTypes;i++) fDetDigits->AddAt(new TClonesArray(GetDigitClassName(i),100),i);
fSDigits = new TClonesArray("AliITSUSDigit",100);
fDetHits = new TClonesArray("AliITSUHit",100);
fChipHits = new TObjArray(fGeomTGeo->GetNChips());
for (int i=0;i<fGeomTGeo->GetNChips();i++) fChipHits->AddLast( new AliITSUChip(i,fGeomTGeo) );
}
void AliITSU::SetTreeAddress()
{
TTree *treeS = fLoader->TreeS();
if (treeS) {
TBranch* br = treeS->GetBranch(GetName());
if (br) br->SetAddress(&fSDigits);
}
TTree *treeD = fLoader->TreeD();
if (treeD) {
if (!fDetDigits) InitArrays();
for (int i=0;i<kNChipTypes;i++) {
TString brname = Form("%sDigits%s",GetName(),GetChipTypeName(i));
TBranch* br = treeD->GetBranch(brname.Data());
if (!br) continue;
TClonesArray* darr = (TClonesArray*)fDetDigits->At(i);
br->SetAddress(&darr);
}
}
if (fLoader->TreeH() && (fHits == 0x0)) fHits = new TClonesArray("AliITSUHit", 1560);
AliDetector::SetTreeAddress();
}
void AliITSU::AddHit(Int_t track, Int_t *vol, Float_t *hits)
{
TClonesArray &lhits = *fHits;
new(lhits[fNhits++]) AliITSUHit(fIshunt,track,vol,hits);
}
void AliITSU::FillChips(Int_t bgrev, Option_t *option, const char *filename)
{
static TTree *trH1=0;
static Bool_t first=kTRUE;
static TFile *file = 0;
const char *addBgr = strstr(option,"Add");
if (addBgr ) {
if(first) {
file = new TFile(filename);
first=kFALSE;
}
file->cd();
file->ls();
if (trH1) {delete trH1; trH1=0;}
char treeName[21];
snprintf(treeName,20,"TreeH%d",bgrev);
trH1 = (TTree*)gDirectory->Get(treeName);
if (!trH1) Error("FillChips","cannot find Hits Tree for event:%d",bgrev);
}
FillChips(fLoader->TreeH(),0);
if (addBgr ) {
FillChips(trH1,10000000);
TTree *fAli=fLoader->GetRunLoader()->TreeK();
TFile *fileAli=0;
if (fAli) {
fileAli = fAli->GetCurrentFile();
fileAli->cd();
}
}
}
void AliITSU::FillChips(TTree *treeH, Int_t )
{
if (treeH == 0x0) { AliError("Tree H is NULL"); return; }
Int_t lay,sta,ssta,mod,chip,index;
AliITSUHit *itsHit=0;
char branchname[21];
snprintf(branchname,20,"%s",GetName());
TBranch *branch = treeH->GetBranch(branchname);
if (!branch) {Error("FillChips","%s branch in TreeH not found",branchname); return;}
branch->SetAddress(&fHits);
Int_t nTracks =(Int_t) treeH->GetEntries();
Int_t iPrimTrack,h;
for (iPrimTrack=0; iPrimTrack<nTracks; iPrimTrack++) {
ResetHits();
Int_t nBytes = treeH->GetEvent(iPrimTrack);
if (nBytes <= 0) continue;
Int_t nHits = fHits->GetEntriesFast();
for (h=0; h<nHits; h++){
itsHit = (AliITSUHit *)fHits->UncheckedAt(h);
itsHit->GetChipID(lay,sta,ssta,mod,chip);
index = fGeomTGeo->GetChipIndex(lay,sta,ssta,mod,chip);
itsHit = new( (*fDetHits)[fDetHits->GetEntriesFast()] ) AliITSUHit(*itsHit);
itsHit->SetUniqueID(h);
GetChip(index)->AddHit(itsHit);
}
}
}
void AliITSU::ClearChips()
{
if (!fChipHits || !fDetHits) AliFatal("Hits accumulation arrays are not defined");
for (int i=fGeomTGeo->GetNChips();i--;) GetChip(i)->Clear();
fDetHits->Clear();
}
void AliITSU::Hits2SDigits()
{
if (!IsSimInitDone()) InitSimulation();
fLoader->LoadHits("read");
fLoader->LoadSDigits("recreate");
AliRunLoader* rl = fLoader->GetRunLoader();
for (Int_t iEvent = 0; iEvent < rl->GetNumberOfEvents(); iEvent++) {
rl->GetEvent(iEvent);
if (!fLoader->TreeS()) fLoader->MakeTree("S");
MakeBranch("S");
SetTreeAddress();
Hits2SDigits(iEvent,0," "," ");
}
fLoader->UnloadHits();
fLoader->UnloadSDigits();
}
void AliITSU::Hits2SDigits(Int_t evNumber,Int_t bgrev,Option_t *option,const char *filename)
{
if (!IsSimInitDone()) InitSimulation();
FillChips(bgrev,option,filename);
Int_t nchips = fGeomTGeo->GetNChips();
int prevLr = -1;
float roPhase=0;
Bool_t randomyzeChips = kFALSE;
for(int chip=0;chip<nchips;chip++) {
int lr = fGeomTGeo->GetLayer(chip);
AliITSUSimulation* sim = GetSimulationModel(lr);
sim->InitSimulationChip(GetChip(chip),evNumber,GetSegmentation(lr),GetResponseParam(lr));
if (prevLr!=lr) {
roPhase = fSimuParam->GetLrROCycleShift(lr);
if (Abs(roPhase)<1.) roPhase = roPhase*sim->GetReadOutCycleLength();
else randomyzeChips = kTRUE;
}
if (randomyzeChips) sim->GenerateReadOutCycleOffset();
else sim->SetReadOutCycleOffset(roPhase);
sim->SDigitiseChip();
fLoader->TreeS()->Fill();
ResetSDigits();
prevLr = lr;
}
ClearChips();
fLoader->TreeS()->GetEntries();
fLoader->TreeS()->AutoSave();
fLoader->WriteSDigits("OVERWRITE");
fLoader->TreeS()->Reset();
}
void AliITSU::Hits2Digits()
{
if (!IsSimInitDone()) InitSimulation();
fLoader->LoadHits("read");
fLoader->LoadDigits("recreate");
AliRunLoader* rl = fLoader->GetRunLoader();
for (Int_t iEvent = 0; iEvent < rl->GetNumberOfEvents(); iEvent++) {
rl->GetEvent(iEvent);
if (!fLoader->TreeD()) fLoader->MakeTree("D");
MakeBranch("D");
SetTreeAddress();
Hits2Digits(iEvent,0," "," ");
}
fLoader->UnloadHits();
fLoader->UnloadSDigits();
}
void AliITSU::Hits2Digits(Int_t evNumber,Int_t bgrev,Option_t *option,const char *filename)
{
if (!IsSimInitDone()) InitSimulation();
FillChips(bgrev,option,filename);
Int_t nchips = fGeomTGeo->GetNChips();
int prevLr = -1;
float roPhase=0;
Bool_t randomyzeChips = kFALSE;
for (Int_t chip=0;chip<nchips;chip++) {
int lr = fGeomTGeo->GetLayer(chip);
AliITSUSimulation* sim = GetSimulationModel(lr);
sim->InitSimulationChip(GetChip(chip),evNumber,GetSegmentation(lr),GetResponseParam(lr));
if (prevLr!=lr) {
roPhase = fSimuParam->GetLrROCycleShift(lr);
if (Abs(roPhase)<1.) roPhase = roPhase*sim->GenerateReadOutCycleOffset();
else randomyzeChips = kTRUE;
}
if (randomyzeChips) sim->GenerateReadOutCycleOffset();
else sim->SetReadOutCycleOffset(roPhase);
sim->DigitiseChip();
fLoader->TreeD()->Fill();
ResetDigits();
prevLr = lr;
}
ClearChips();
fLoader->TreeD()->GetEntries();
fLoader->TreeD()->AutoSave();
fLoader->TreeD()->Reset();
}
void AliITSU::Hits2FastRecPoints(Int_t bgrev,Option_t *opt,const char *flnm)
{
if (!IsSimInitDone()) InitSimulation();
AliITSULoader *pITSloader = (AliITSULoader*)fLoader;
Int_t nchips = fGeomTGeo->GetNChips();
FillChips(bgrev,opt,flnm);
TTree *lTR = pITSloader->TreeR();
if(!lTR) {
pITSloader->MakeTree("R");
lTR = pITSloader->TreeR();
}
TClonesArray* ptarray = new TClonesArray("AliITSRecPoint",1000);
TBranch* branch = (TBranch*)lTR->Branch("ITSRecPointsF",&ptarray);
branch->SetAddress(&ptarray);
for (int chip=0;chip<nchips;chip++){
int id = fGeomTGeo->GetChipChipTypeID(chip);
AliITSUSimulation* sim = GetSimulationModel(id);
if (!sim) AliFatal(Form("The sim.class for chip %d of ChipTypeID %d is missing",chip,id));
sim->CreateFastRecPoints( GetChip(chip) ,chip,gRandom,ptarray);
lTR->Fill();
ptarray->Clear();
}
ClearChips();
fLoader->WriteRecPoints("OVERWRITE");
delete ptarray;
}
Int_t AliITSU::Hits2Clusters(TTree *, TTree *)
{
return 0;
}
void AliITSU::CheckLabels(Int_t lab[3]) const
{
if(lab[0]<0 && lab[1]<0 && lab[2]<0) return;
Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
for (Int_t i=0;i<3;i++){
Int_t label = lab[i];
if (label>=0 && label<ntracks) {
TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
if (part->P() < 0.005) {
Int_t m=part->GetFirstMother();
if (m<0) continue;
if (part->GetStatusCode()>0) continue;
lab[i]=m;
}
}
}
}
void AliITSU::ResetDigits()
{
if (fDetDigits) for (int i=kNChipTypes;i--;) ResetDigits(i);
}
void AliITSU::ResetDigits(Int_t branch)
{
if (fDetDigits) ((TClonesArray*)fDetDigits->At(branch))->Clear();
}
void AliITSU::AddSumDigit(AliITSUSDigit &sdig)
{
new( (*fSDigits)[fSDigits->GetEntriesFast()]) AliITSUSDigit(sdig);
}
void AliITSU::AddSimDigit(Int_t branch, AliITSdigit *d)
{
TClonesArray &ldigits = *((TClonesArray*)fDetDigits->At(branch));
int nd = ldigits.GetEntriesFast();
switch(branch){
case AliITSUGeomTGeo::kChipTypePix:
new(ldigits[nd]) AliITSUDigitPix(*((AliITSUDigitPix*)d));
break;
default:
AliFatal(Form("Unknown digits branch %d",branch));
}
}
void AliITSU::AddSimDigit(Int_t branch,Float_t ,Int_t *digits,Int_t *tracks,
Int_t *hits,Float_t *, Int_t )
{
TClonesArray &ldigits = *((TClonesArray*)fDetDigits->At(branch));
int nd = ldigits.GetEntriesFast();
switch(branch){
case AliITSUGeomTGeo::kChipTypePix:
new(ldigits[nd]) AliITSUDigitPix(digits,tracks,hits);
break;
default:
AliFatal(Form("Unknown digits branch %d",branch));
}
}
void AliITSU::Digits2Raw()
{
AliError("Not ready");
}
AliLoader* AliITSU::MakeLoader(const char* topfoldername)
{
AliDebug(1,Form("Creating AliITSULoader. Top folder is %s.",topfoldername));
fLoader = new AliITSULoader(GetName(),topfoldername);
return fLoader;
}
Bool_t AliITSU::Raw2SDigits(AliRawReader* )
{
AliError("Not ready");
return kFALSE;
}
void AliITSU::WriteFOSignals()
{
AliError("Not ready");
}
void AliITSU::SDigits2Digits()
{
if (!IsSimInitDone()) InitSimulation();
TTree* trees = fLoader->TreeS();
if( !(trees && fSDigits) ) AliFatal("Error: No trees or SDigits.");
TBranch* brchSDigits = trees->GetBranch(GetName());
int nchips = fGeomTGeo->GetNChips();
int prevLr = -1;
float roPhase=0;
Bool_t randomyzeChips = kFALSE;
for (int chip=0;chip<nchips;chip++) {
int lr = fGeomTGeo->GetLayer(chip);
AliITSUSimulation* sim = GetSimulationModel(lr);
sim->InitSimulationChip(GetChip(chip),gAlice->GetEvNumber(),GetSegmentation(lr),GetResponseParam(lr));
if (prevLr!=lr) {
roPhase = fSimuParam->GetLrROCycleShift(lr);
if (Abs(roPhase)<1.) roPhase = roPhase*sim->GenerateReadOutCycleOffset();
else randomyzeChips = kTRUE;
}
if (randomyzeChips) sim->GenerateReadOutCycleOffset();
else sim->SetReadOutCycleOffset(roPhase);
fSDigits->Clear();
brchSDigits->GetEvent(chip);
sim->AddSDigitsToChip(fSDigits,0);
sim->FinishSDigitiseChip();
fLoader->TreeD()->Fill();
ResetDigits();
prevLr = lr;
}
fLoader->TreeD()->GetEntries();
fLoader->TreeD()->AutoSave();
fLoader->TreeD()->Reset();
}
void AliITSU::InitSimulation()
{
if (fSimInitDone) {AliInfo("Already done"); return;}
AliCDBEntry* cdbEnt = AliCDBManager::Instance()->Get("ITS/Calib/SimuParam");
if (!cdbEnt) {AliFatal("Failed to find ITS/Calib/SimuParam on CDB"); exit(1);}
fSimuParam = (AliITSUSimuParam*)cdbEnt->GetObject();
fSensMap = new AliITSUSensMap("AliITSUSDigit",0,0);
fSimModelLr = new AliITSUSimulation*[fNLayers];
fSegModelLr = new AliITSsegmentation*[fNLayers];
fResponseLr = new AliITSUParamList*[fNLayers];
TObjArray arrSeg;
AliITSUSegmentationPix::LoadSegmentations(&arrSeg, AliITSUGeomTGeo::GetITSsegmentationFileName());
for (int i=fNLayers;i--;) {
fSimModelLr[i] = 0;
fSegModelLr[i] = 0;
fResponseLr[i] = 0;
int dType = fGeomTGeo->GetLayerChipTypeID(i);
int sType = dType/AliITSUGeomTGeo::kMaxSegmPerChipType;
AliITSUSimulation* simUpg = 0;
for (int j=fNLayers-1;j>i;j--) {
simUpg = GetSimulationModel(j);
if (simUpg && int(simUpg->GetUniqueID())==sType) break;
else simUpg = 0;
}
if (!simUpg) {
switch (sType)
{
case AliITSUGeomTGeo::kChipTypePix :
simUpg = new AliITSUSimulationPix(fSimuParam,fSensMap);
break;
default: AliFatal(Form("No %d detector type is defined",sType));
}
}
fSimModelLr[i] = simUpg;
if (!(fSegModelLr[i]=(AliITSsegmentation*)arrSeg[dType])) {AliFatal(Form("Segmentation for ChipType#%d is not found",dType)); exit(1);}
if ( !(fResponseLr[i]=(AliITSUParamList*)fSimuParam->FindRespFunParams(dType)) ) {AliFatal(Form("Response for ChipType#%d is not found in SimuParams",dType)); exit(1);}
}
for (int i=fNLayers;i--;) arrSeg.Remove(fSegModelLr[i]);
arrSeg.Delete();
InitArrays();
fSimInitDone = kTRUE;
}