#include "AliEMCALRawUtils.h"
#include "AliEMCALDigit.h"
#include "AliEMCALClusterizerv1.h"
+#include "AliEMCALClusterizerv2.h"
#include "AliEMCALClusterizerNxN.h"
#include "AliEMCALRecPoint.h"
#include "AliEMCALPID.h"
-#include "AliEMCALTrigger.h"
+#include "AliEMCALRecoUtils.h"
#include "AliRawReader.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "AliEMCALTriggerTypes.h"
ClassImp(AliEMCALReconstructor)
-
+
const AliEMCALRecParam* AliEMCALReconstructor::fgkRecParam = 0; // EMCAL rec. parameters
AliEMCALRawUtils* AliEMCALReconstructor::fgRawUtils = 0; // EMCAL raw utilities class
AliEMCALClusterizer* AliEMCALReconstructor::fgClusterizer = 0; // EMCAL clusterizer class
AliEMCALTriggerElectronics* AliEMCALReconstructor::fgTriggerProcessor = 0x0;
//____________________________________________________________________________
AliEMCALReconstructor::AliEMCALReconstructor()
- : fGeom(0),fCalibData(0),fPedestalData(0),fTriggerData(0x0)
+ : fGeom(0),fCalibData(0),fPedestalData(0),fTriggerData(0x0), fMatches(0x0)
{
// ctor
+ // AliDebug(2, "Mark.");
+
fgRawUtils = new AliEMCALRawUtils;
//To make sure we match with the geometry in a simulation file,
if(!fCalibData)
{
AliCDBEntry *entry = (AliCDBEntry*)
- AliCDBManager::Instance()->Get("EMCAL/Calib/Data");
+ AliCDBManager::Instance()->Get("EMCAL/Calib/Data");
if (entry) fCalibData = (AliEMCALCalibData*) entry->GetObject();
}
if(!fPedestalData)
{
AliCDBEntry *entry = (AliCDBEntry*)
- AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals");
+ AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals");
if (entry) fPedestalData = (AliCaloCalibPedestal*) entry->GetObject();
}
//Init temporary list of digits
fgDigitsArr = new TClonesArray("AliEMCALDigit",1000);
fgClustersArr = new TObjArray(1000);
- fgTriggerDigits = new TClonesArray("AliEMCALTriggerRawDigit",1000);
+
+ const int kNTRU = fGeom->GetNTotalTRU();
+ fgTriggerDigits = new TClonesArray("AliEMCALTriggerRawDigit", kNTRU * 96);
+
+ //Track matching
+ fMatches = new TList();
+ fMatches->SetOwner(kTRUE);
}
//____________________________________________________________________________
AliEMCALReconstructor::~AliEMCALReconstructor()
{
// dtor
-
+
+ //AliDebug(2, "Mark.");
+
if(fGeom) delete fGeom;
//No need to delete, recovered from OCDB
if(fgClusterizer) delete fgClusterizer;
if(fgTriggerProcessor) delete fgTriggerProcessor;
+ if(fMatches) { fMatches->Delete(); delete fMatches; fMatches = 0;}
+
AliCodeTimer::Instance()->Print();
}
//printf("ReCreate clusterizer? Clusterizer set <%d>, Clusterizer in use <%s>\n",
// clusterizerType, fgClusterizer->Version());
- if (clusterizerType == AliEMCALRecParam::kClusterizerv1 && !strcmp(fgClusterizer->Version(),"clu-v1")) return;
+ if (clusterizerType == AliEMCALRecParam::kClusterizerv1 && !strcmp(fgClusterizer->Version(),"clu-v1")) return;
else if(clusterizerType == AliEMCALRecParam::kClusterizerNxN && !strcmp(fgClusterizer->Version(),"clu-NxN")) return;
+ else if(clusterizerType == AliEMCALRecParam::kClusterizerv2 && !strcmp(fgClusterizer->Version(),"clu-v2")) return;
+
//Need to create new clusterizer, the one set previously is not the correct one
delete fgClusterizer;
}
else return;
}
- if (clusterizerType == AliEMCALRecParam::kClusterizerv1)
+ if (clusterizerType == AliEMCALRecParam::kClusterizerv1)
{
- fgClusterizer = new AliEMCALClusterizerv1(fGeom, fCalibData,fPedestalData);
+ fgClusterizer = new AliEMCALClusterizerv1 (fGeom, fCalibData,fPedestalData);
}
- else
+ else if (clusterizerType == AliEMCALRecParam::kClusterizerNxN)
{
fgClusterizer = new AliEMCALClusterizerNxN(fGeom, fCalibData,fPedestalData);
}
+ else if (clusterizerType == AliEMCALRecParam::kClusterizerv2)
+ {
+ fgClusterizer = new AliEMCALClusterizerv2 (fGeom, fCalibData,fPedestalData);
+ }
+ else
+ {
+ AliFatal(Form("Unknown clusterizer %d ", clusterizerType));
+ }
}
//____________________________________________________________________________
}//not a LED event
clustersTree->Fill();
+
+ // Deleting the recpoints at the end of the reconstruction call
+ fgClusterizer->DeleteRecPoints();
}
//____________________________________________________________________________
if(fgDigitsArr) fgDigitsArr->Clear("C");
- TClonesArray *digitsTrg = new TClonesArray("AliEMCALTriggerRawDigit", 32 * 96);
+ const int kNTRU = fGeom->GetNTotalTRU();
+ TClonesArray *digitsTrg = new TClonesArray("AliEMCALTriggerRawDigit", kNTRU * 96);
Int_t bufsize = 32000;
digitsTree->Branch("EMCAL", &fgDigitsArr, bufsize);
fgRawUtils->SetOption(GetOption());
// fgRawUtils->SetRawFormatHighLowGainFactor(GetRecParam()->GetHighLowGainFactor());
-
+
// fgRawUtils->SetRawFormatOrder(GetRecParam()->GetOrderParameter());
// fgRawUtils->SetRawFormatTau(GetRecParam()->GetTau());
fgRawUtils->SetNoiseThreshold(GetRecParam()->GetNoiseThreshold());
fgRawUtils->SetNPedSamples(GetRecParam()->GetNPedSamples());
fgRawUtils->SetRemoveBadChannels(GetRecParam()->GetRemoveBadChannels());
- fgRawUtils->SetFittingAlgorithm(GetRecParam()->GetFittingAlgorithm());
+ if (!fgRawUtils->GetFittingAlgorithm()) fgRawUtils->SetFittingAlgorithm(GetRecParam()->GetFittingAlgorithm());
fgRawUtils->SetFALTROUsage(GetRecParam()->UseFALTRO());
-
+ // fgRawUtils->SetFALTROUsage(0);
+
//fgRawUtils->SetTimeMin(GetRecParam()->GetTimeMin());
//fgRawUtils->SetTimeMax(GetRecParam()->GetTimeMax());
//########################################
static int saveOnce = 0;
-
+
Int_t v0M[2] = {0, 0};
AliESDVZERO* esdV0 = esd->GetVZEROData();
if (esdV0)
{
- for (Int_t i = 0; i < 32; i++)
- {
- v0M[0] += (Int_t)esdV0->GetAdcV0C(i);
- v0M[1] += (Int_t)esdV0->GetAdcV0A(i);
- }
+ v0M[0] = esdV0->GetTriggerChargeC();
+ v0M[1] = esdV0->GetTriggerChargeA();
}
else
{
- AliWarning("Cannot retrieve V0 ESD! Run w/ null V0 charges");
+ AliWarning("No V0 ESD! Run trigger processor w/ null V0 charges");
}
- if (fgTriggerDigits) fgTriggerDigits->Clear();
+ if (fgTriggerDigits && fgTriggerDigits->GetEntriesFast()) fgTriggerDigits->Delete();
TBranch *branchtrg = digitsTree->GetBranch("EMTRG");
for (Int_t i = 0; i < fgTriggerDigits->GetEntriesFast(); i++)
{
AliEMCALTriggerRawDigit* rdig = (AliEMCALTriggerRawDigit*)fgTriggerDigits->At(i);
-
+ if (AliDebugLevel() > 999) rdig->Print("");
+
Int_t px, py;
if (fGeom->GetPositionInEMCALFromAbsFastORIndex(rdig->GetId(), px, py))
{
rdig->GetMaximum(a, t);
rdig->GetL0Times(times);
-
+
trgESD->Add(px, py, a, t, times, rdig->GetNL0Times(), rdig->GetL1TimeSum(), rdig->GetTriggerBits());
}
}
- trgESD->SetL1Threshold(0, fTriggerData->GetL1GammaThreshold());
+ for (int i = 0; i < 2; i++) {
+ trgESD->SetL1Threshold(2 * i , fTriggerData->GetL1JetThreshold( i));
+ trgESD->SetL1Threshold(2 * i + 1, fTriggerData->GetL1GammaThreshold(i));
+ }
- trgESD->SetL1Threshold(1, fTriggerData->GetL1JetThreshold() );
-
- Int_t v0[2];
- fTriggerData->GetL1V0(v0);
-
- trgESD->SetL1V0(v0);
- trgESD->SetL1FrameMask(fTriggerData->GetL1FrameMask());
-
- if (!saveOnce)
- {
- int type[8] = {0};
- fTriggerData->GetL1TriggerType(type);
-
- esd->SetCaloTriggerType(type);
-
- saveOnce = 1;
- }
+ Int_t v0[2];
+ fTriggerData->GetL1V0(v0);
+
+ trgESD->SetL1V0(v0);
+ trgESD->SetL1FrameMask(fTriggerData->GetL1FrameMask());
+
+ if (!saveOnce && fTriggerData->GetL1DataDecoded())
+ {
+ int type[15] = {0};
+ fTriggerData->GetL1TriggerType(type);
+
+ esd->SetCaloTriggerType(type);
+
+ saveOnce = 1;
+ }
}
// Resetting
AliESDCaloCells &emcCells = *(esd->GetEMCALCells());
emcCells.CreateContainer(nDigits);
emcCells.SetType(AliVCaloCells::kEMCALCell);
+
Float_t energy = 0;
- for (Int_t idig = 0 ; idig < nDigits ; idig++) {
+ Float_t time = 0;
+ for (Int_t idig = 0 ; idig < nDigits ; idig++)
+ {
const AliEMCALDigit * dig = (const AliEMCALDigit*)fgDigitsArr->At(idig);
- if(dig->GetAmplitude() > 0 ){
- energy = fgClusterizer->Calibrate(dig->GetAmplitude(),dig->GetTime(),dig->GetId()); //TimeR or Time?
- if(energy > 0){ //Digits tagged as bad (dead, hot, not alive) are set to 0 in calibrate, remove them
- emcCells.SetCell(idignew,dig->GetId(),energy, dig->GetTime());
- idignew++;
+ time = dig->GetTime(); // Time already calibrated in clusterizer
+ energy = dig->GetAmplitude(); // energy calibrated in clusterizer
+
+ if(energy > 0 )
+ {
+ fgClusterizer->Calibrate(energy,time,dig->GetId()); //Digits already calibrated in clusterizers
+
+ if(energy > 0) //Digits tagged as bad (dead, hot, not alive) are set to 0 in calibrate, remove them
+ {
+ // Only for MC
+ // Get the label of the primary particle that generated the cell
+ // Assign the particle that deposited more energy
+ Int_t nprimaries = dig->GetNprimary() ;
+ Int_t digLabel =-1 ;
+ Float_t edep =-1.;
+ if ( nprimaries > 0 )
+ {
+ Int_t jndex ;
+ for ( jndex = 0 ; jndex < nprimaries ; jndex++ ) { // all primaries in digit
+
+ if(edep < dig->GetDEParent(jndex+1))
+ {
+ digLabel = dig->GetIparent (jndex+1);
+ edep = dig->GetDEParent(jndex+1);
+ }
+
+ } // all primaries in digit
+ } // select primary label
+
+ Bool_t highGain = kFALSE;
+ if( dig->GetType() == AliEMCALDigit::kHG ) highGain = kTRUE;
+
+ emcCells.SetCell(idignew,dig->GetId(),energy, time,digLabel,0.,highGain);
+ idignew++;
}
}
}
+
emcCells.SetNumberOfCells(idignew);
emcCells.Sort();
Int_t nClusters = fgClustersArr->GetEntries(), nClustersNew=0;
AliDebug(1,Form("%d clusters",nClusters));
-
- //######################################################
- //#######################TRACK MATCHING###############
- //######################################################
- //Fill list of integers, each one is index of track to which the cluster belongs.
-
- // step 1 - initialize array of matched track indexes
- Int_t *matchedTrack = new Int_t[nClusters];
- for (Int_t iclus = 0; iclus < nClusters; iclus++)
- matchedTrack[iclus] = -1; // neg. index --> no matched track
-
- // step 2, change the flag for all matched clusters found in tracks
- Int_t iemcalMatch = -1;
- Int_t endtpc = esd->GetNumberOfTracks();
- for (Int_t itrack = 0; itrack < endtpc; itrack++) {
- AliESDtrack * track = esd->GetTrack(itrack) ; // retrieve track
- iemcalMatch = track->GetEMCALcluster();
- if(iemcalMatch >= 0) matchedTrack[iemcalMatch] = itrack;
- }
+
//########################################
//##############Fill CaloClusters#############
//########################################
for (Int_t iClust = 0 ; iClust < nClusters ; iClust++) {
const AliEMCALRecPoint * clust = (const AliEMCALRecPoint*)fgClustersArr->At(iClust);
+ if(!clust) continue;
//if(clust->GetClusterType()== AliVCluster::kEMCALClusterv1) nRP++; else nPC++;
// clust->Print(); //For debugging
// Get information from EMCAL reconstruction points
Int_t newCellMult = 0;
for (Int_t iCell=0; iCell<cellMult; iCell++) {
if (amplFloat[iCell] > 0) {
- absIdList[newCellMult] = (UShort_t)(digitInts[iCell]);
- //Calculate Fraction
- if(emcCells.GetCellAmplitude(digitInts[iCell])>0 && GetRecParam()->GetUnfold()){
- fracList[newCellMult] = amplFloat[iCell]/(emcCells.GetCellAmplitude(digitInts[iCell]));//get cell calibration value
-
- }
- else{
- fracList[newCellMult] = 0;
- }
- newCellMult++;
+ absIdList[newCellMult] = (UShort_t)(digitInts[iCell]);
+ //Calculate Fraction
+ if(emcCells.GetCellAmplitude(digitInts[iCell])>0 && GetRecParam()->GetUnfold()){
+ fracList[newCellMult] = amplFloat[iCell]/(emcCells.GetCellAmplitude(digitInts[iCell]));//get cell calibration value
+
+ }
+ else{
+ fracList[newCellMult] = 0;
+ }
+ newCellMult++;
}
}
ec->SetM20(elipAxis[1]*elipAxis[1]) ;
ec->SetTOF(clust->GetTime()) ; //time-of-fligh
ec->SetNExMax(clust->GetNExMax()); //number of local maxima
- TArrayI arrayTrackMatched(1);// Only one track, temporal solution.
- arrayTrackMatched[0]= matchedTrack[iClust];
- ec->AddTracksMatched(arrayTrackMatched);
+
TArrayI arrayParents(parentMult,parentList);
ec->AddLabels(arrayParents);
-
- // add the cluster to the esd object
+ //
+ //Track matching
+ //
+ fMatches->Clear();
+ Int_t nTracks = esd->GetNumberOfTracks();
+ for (Int_t itrack = 0; itrack < nTracks; itrack++)
+ {
+ AliESDtrack * track = esd->GetTrack(itrack) ; // retrieve track
+ if(track->GetEMCALcluster()==iClust)
+ {
+ Float_t dEta=-999, dPhi=-999;
+ Bool_t isMatch = CalculateResidual(track, ec, dEta, dPhi);
+ if(!isMatch)
+ {
+ // AliDebug(10, "Not good");
+ continue;
+ }
+ AliEMCALMatch *match = new AliEMCALMatch();
+ match->SetIndexT(itrack);
+ match->SetDistance(TMath::Sqrt(dEta*dEta+dPhi*dPhi));
+ match->SetdEta(dEta);
+ match->SetdPhi(dPhi);
+ fMatches->Add(match);
+ }
+ }
+ fMatches->Sort(kSortAscending); //Sort matched tracks from closest to furthest
+ Int_t nMatch = fMatches->GetEntries();
+ TArrayI arrayTrackMatched(nMatch);
+ for(Int_t imatch=0; imatch<nMatch; imatch++)
+ {
+ AliEMCALMatch *match = (AliEMCALMatch*)fMatches->At(imatch);
+ arrayTrackMatched[imatch] = match->GetIndexT();
+ if(imatch==0)
+ {
+ ec->SetTrackDistance(match->GetdPhi(), match->GetdEta());
+ }
+ }
+ ec->AddTracksMatched(arrayTrackMatched);
+
+ //add the cluster to the esd object
esd->AddCaloCluster(ec);
+
delete ec;
delete [] newAbsIdList ;
delete [] newFracList ;
}
} // cycle on clusters
+
+ //
+ //Reset the index of matched cluster for tracks
+ //to the one in CaloCluster array
+ Int_t ncls = esd->GetNumberOfCaloClusters();
+ for(Int_t icl=0; icl<ncls; icl++)
+ {
+ AliESDCaloCluster *cluster = esd->GetCaloCluster(icl);
+ if(!cluster || !cluster->IsEMCAL()) continue;
+ TArrayI *trackIndex = cluster->GetTracksMatched();
+ for(Int_t itr=0; itr<trackIndex->GetSize(); itr++)
+ {
+ AliESDtrack *track = esd->GetTrack(trackIndex->At(itr));
+ track->SetEMCALcluster(cluster->GetID());
+ }
+ }
- delete [] matchedTrack;
//Fill ESDCaloCluster with PID weights
AliEMCALPID *pid = new AliEMCALPID;
const Int_t bufsize = 255;
char path[bufsize] ;
TGeoHMatrix * m = 0x0;
+ Int_t tmpType = -1;
+ Int_t SMOrder = 0;
+ TString SMName;
for(Int_t sm = 0; sm < fGeom->GetNumberOfSuperModules(); sm++){
- snprintf(path,bufsize,"/ALIC_1/XEN1_1/SMOD_%d",sm+1) ; //In Geometry modules numbered 1,2,.,5
- if(sm >= 10) snprintf(path,bufsize,"/ALIC_1/XEN1_1/SM10_%d",sm-10+1) ;
-
+ if(fGeom->GetSMType(sm) == AliEMCALGeometry::kEMCAL_Standard ) SMName = "SMOD";
+ else if(fGeom->GetSMType(sm) == AliEMCALGeometry::kEMCAL_Half ) SMName = "SM10";
+ else if(fGeom->GetSMType(sm) == AliEMCALGeometry::kEMCAL_3rd ) SMName = "SM3rd";
+ else if( fGeom->GetSMType(sm) == AliEMCALGeometry::kDCAL_Standard ) SMName = "DCSM";
+ else if( fGeom->GetSMType(sm) == AliEMCALGeometry::kDCAL_Ext ) SMName = "DCEXT";
+ else AliError("Unkown SM Type!!");
+
+ if(fGeom->GetSMType(sm) == tmpType) {
+ SMOrder++;
+ } else {
+ tmpType = fGeom->GetSMType(sm);
+ SMOrder = 1;
+ }
+ snprintf(path,bufsize,"/ALIC_1/XEN1_1/%s_%d", SMName.Data(), SMOrder) ;
+
if (gGeoManager->CheckPath(path)){
gGeoManager->cd(path);
m = gGeoManager->GetCurrentMatrix() ;
branch->GetEntry(0);
}
+//==================================================================================
+Bool_t AliEMCALReconstructor::CalculateResidual(AliESDtrack *track, AliESDCaloCluster *cluster, Float_t &dEta, Float_t &dPhi)const
+{
+ //
+ // calculate the residual between track and cluster
+ //
+
+ // If the esdFriend is available, use the TPCOuter point as the starting point of extrapolation
+ // Otherwise use the TPCInner point
+
+ dEta = -999, dPhi = -999;
+ Bool_t ITSTrackSA = 0;
+
+ AliExternalTrackParam *trkParam = 0;
+
+ const AliESDfriendTrack* friendTrack = track->GetFriendTrack();
+ if(friendTrack && friendTrack->GetTPCOut())
+ trkParam = const_cast<AliExternalTrackParam*>(friendTrack->GetTPCOut());
+ else if(track->GetInnerParam())
+ trkParam = const_cast<AliExternalTrackParam*>(track->GetInnerParam());
+ else{
+ trkParam = new AliExternalTrackParam(*track); //If there is ITSSa track
+ ITSTrackSA = 1;
+ }
+ if(!trkParam) return kFALSE;
+
+ AliExternalTrackParam trkParamTmp (*trkParam);
+ if(!AliEMCALRecoUtils::ExtrapolateTrackToCluster(&trkParamTmp, cluster, track->GetMass(kTRUE), GetRecParam()->GetExtrapolateStep(), dEta, dPhi)){
+ if(ITSTrackSA) delete trkParam;
+ return kFALSE;
+ }
+
+ if(ITSTrackSA) delete trkParam;
+ return kTRUE;
+}
+
+//
+//==================================================================================
+//
+AliEMCALReconstructor::AliEMCALMatch::AliEMCALMatch()
+ : TObject(),
+ fIndexT(-1),
+ fDistance(-999.),
+ fdEta(-999.),
+ fdPhi(-999.)
+{
+ //default constructor
+}
+
+//
+//==================================================================================
+//
+AliEMCALReconstructor::AliEMCALMatch::AliEMCALMatch(const AliEMCALMatch& copy)
+ : TObject(),
+ fIndexT(copy.fIndexT),
+ fDistance(copy.fDistance),
+ fdEta(copy.fdEta),
+ fdPhi(copy.fdPhi)
+{
+ //copy ctor
+}
+//_____________________________________________________________________
+AliEMCALReconstructor::AliEMCALMatch& AliEMCALReconstructor::AliEMCALMatch::AliEMCALMatch::operator = (const AliEMCALMatch &source)
+{ // assignment operator; use copy ctor
+ if (&source == this) return *this;
+
+ new (this) AliEMCALMatch(source);
+ return *this;
+}
+//
+//==================================================================================
+//
+Int_t AliEMCALReconstructor::AliEMCALMatch::Compare(const TObject *obj) const
+{
+ //
+ // Compare wrt the residual
+ //
+
+ AliEMCALReconstructor::AliEMCALMatch *that = (AliEMCALReconstructor::AliEMCALMatch*)obj;
+
+ Double_t thisDist = fDistance;//fDistance;
+ Double_t thatDist = that->fDistance;//that->GetDistance();
+
+ if (thisDist > thatDist) return 1;
+ else if (thisDist < thatDist) return -1;
+ return 0;
+}