#include "TGeoManager.h"
#include "TROOT.h"
#include "TInterpreter.h"
+#include "TFile.h"
+//#include "string.h"
// --- AliRoot Analysis Steering
#include "AliAnalysisTask.h"
#include "AliCDBEntry.h"
#include "AliLog.h"
#include "AliVEventHandler.h"
+#include "AliAODInputHandler.h"
// --- EMCAL
#include "AliEMCALRecParam.h"
#include "AliEMCALGeometry.h"
#include "AliEMCALClusterizerNxN.h"
#include "AliEMCALClusterizerv1.h"
+#include "AliEMCALClusterizerv2.h"
#include "AliEMCALRecPoint.h"
#include "AliEMCALDigit.h"
#include "AliCaloCalibPedestal.h"
ClassImp(AliAnalysisTaskEMCALClusterize)
-//________________________________________________________________________
+//______________________________________________________________________________
AliAnalysisTaskEMCALClusterize::AliAnalysisTaskEMCALClusterize(const char *name)
- : AliAnalysisTaskSE(name)
- , fGeom(0), fGeomName("EMCAL_FIRSTYEARV1"), fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
- , fCalibData(0), fPedestalData(0), fOCDBpath("raw://")
- , fDigitsArr(0), fClusterArr(0), fCaloClusterArr(0)
- , fRecParam(0), fClusterizer(0), fUnfolder(0), fJustUnfold(kFALSE)
- , fOutputAODBranch(0), fOutputAODBranchName("newEMCALClusters"), fFillAODFile(kTRUE)
- , fRun(-1), fRecoUtils(0), fConfigName("")
-
- {
+: AliAnalysisTaskSE(name)
+, fEvent(0)
+, fGeom(0), fGeomName("EMCAL_COMPLETEV1")
+, fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
+, fCalibData(0), fPedestalData(0)
+, fOCDBpath("raw://"), fAccessOCDB(kFALSE)
+, fDigitsArr(0), fClusterArr(0), fCaloClusterArr(0)
+, fRecParam(0), fClusterizer(0)
+, fUnfolder(0), fJustUnfold(kFALSE)
+, fOutputAODBranch(0), fOutputAODBranchName("newEMCALClusters")
+, fFillAODFile(kTRUE), fFillAODHeader(0)
+, fFillAODCaloCells(0), fRun(-1)
+, fRecoUtils(0), fConfigName("")
+, fCellLabels(), fCellSecondLabels(), fCellTime()
+, fMaxEvent(1000000000), fDoTrackMatching(kFALSE)
+, fSelectCell(kFALSE), fSelectCellMinE(0.005), fSelectCellMinFrac(0.001)
+, fRemoveLEDEvents(kFALSE), fRemoveExoticEvents(kFALSE), fRemoveExoticCells(kFALSE)
+, fExoticCellFraction(0.9), fExoticCellDiffTime(1e6), fExoticCellMinAmplitude(0.5)
+
+{
//ctor
- for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = 0 ;
+ for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = 0;
+ for(Int_t j = 0; j < 24*48*11; j++) {
+ fCellLabels[j] = -1;
+ fCellSecondLabels[j] = -1;
+ fCellTime[j] = 0.;
+ }
+
fDigitsArr = new TClonesArray("AliEMCALDigit",200);
fClusterArr = new TObjArray(100);
- fCaloClusterArr = new TObjArray(100);
+ fCaloClusterArr = new TObjArray(1000);
fRecParam = new AliEMCALRecParam;
fBranchNames = "ESD:AliESDHeader.,EMCALCells.";
fRecoUtils = new AliEMCALRecoUtils();
+
}
-//________________________________________________________________________
+//______________________________________________________________
AliAnalysisTaskEMCALClusterize::AliAnalysisTaskEMCALClusterize()
- : AliAnalysisTaskSE("DefaultAnalysis_AliAnalysisTaskEMCALClusterize")
- , fGeom(0), fGeomName("EMCAL_FIRSTYEARV1"), fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
- , fCalibData(0), fPedestalData(0), fOCDBpath("raw://")
- , fDigitsArr(0), fClusterArr(0), fCaloClusterArr(0)
- , fRecParam(0), fClusterizer(0), fUnfolder(0), fJustUnfold(kFALSE)
- , fOutputAODBranch(0), fOutputAODBranchName("newEMCALClusters"), fFillAODFile(kFALSE)
- , fRun(-1), fRecoUtils(0), fConfigName("")
+: AliAnalysisTaskSE("DefaultAnalysis_AliAnalysisTaskEMCALClusterize")
+, fEvent(0)
+, fGeom(0), fGeomName("EMCAL_COMPLETEV1")
+, fGeomMatrixSet(kFALSE), fLoadGeomMatrices(kFALSE)
+, fCalibData(0), fPedestalData(0)
+, fOCDBpath("raw://"), fAccessOCDB(kFALSE)
+, fDigitsArr(0), fClusterArr(0), fCaloClusterArr(0)
+, fRecParam(0), fClusterizer(0)
+, fUnfolder(0), fJustUnfold(kFALSE)
+, fOutputAODBranch(0), fOutputAODBranchName("newEMCALClusters")
+, fFillAODFile(kTRUE), fFillAODHeader(0)
+, fFillAODCaloCells(0), fRun(-1)
+, fRecoUtils(0), fConfigName("")
+, fCellLabels(), fCellSecondLabels(), fCellTime()
+, fMaxEvent(1000000000), fDoTrackMatching(kFALSE)
+, fSelectCell(kFALSE), fSelectCellMinE(0.005), fSelectCellMinFrac(0.001)
+, fRemoveLEDEvents(kFALSE), fRemoveExoticEvents(kFALSE), fRemoveExoticCells(kFALSE)
+, fExoticCellFraction(0.9), fExoticCellDiffTime(1e6), fExoticCellMinAmplitude(0.5)
{
// Constructor
- for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = 0 ;
+ for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = 0;
+ for(Int_t j = 0; j < 24*48*11; j++) {
+ fCellLabels[j] = -1;
+ fCellSecondLabels[j] = -1;
+ fCellTime[j] = 0.;
+ }
fDigitsArr = new TClonesArray("AliEMCALDigit",200);
fClusterArr = new TObjArray(100);
fCaloClusterArr = new TObjArray(100);
}
-//________________________________________________________________________
+//_______________________________________________________________
AliAnalysisTaskEMCALClusterize::~AliAnalysisTaskEMCALClusterize()
{
//dtor
fCaloClusterArr->Delete();
delete fCaloClusterArr;
}
-
+
if(fClusterizer) delete fClusterizer;
if(fUnfolder) delete fUnfolder;
if(fRecoUtils) delete fRecoUtils;
-
-}
-
-//-------------------------------------------------------------------
-void AliAnalysisTaskEMCALClusterize::Init()
-{
- //Init analysis with configuration macro if available
- if(gROOT->LoadMacro(fConfigName) >=0){
- printf("Configure analysis with %s\n",fConfigName.Data());
- AliAnalysisTaskEMCALClusterize *clus = (AliAnalysisTaskEMCALClusterize*)gInterpreter->ProcessLine("ConfigEMCALClusterize()");
- fGeomName = clus->fGeomName;
- fLoadGeomMatrices = clus->fLoadGeomMatrices;
- fOCDBpath = clus->fOCDBpath;
- fRecParam = clus->fRecParam;
- fJustUnfold = clus->fJustUnfold;
- fFillAODFile = clus->fFillAODFile;
- fRecoUtils = clus->fRecoUtils;
- fConfigName = clus->fConfigName;
- fOutputAODBranchName = clus->fOutputAODBranchName;
- for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = clus->fGeomMatrix[i] ;
-
- }
-
-}
-
-//-------------------------------------------------------------------
-void AliAnalysisTaskEMCALClusterize::UserCreateOutputObjects()
-{
- // Init geometry, create list of output clusters
-
- fGeom = AliEMCALGeometry::GetInstance(fGeomName) ;
-
- fOutputAODBranch = new TClonesArray("AliAODCaloCluster", 0);
- fOutputAODBranch->SetName(fOutputAODBranchName);
- AddAODBranch("TClonesArray", &fOutputAODBranch);
-
}
-//________________________________________________________________________
-void AliAnalysisTaskEMCALClusterize::UserExec(Option_t *)
+//_________________________________________________________________________________
+Bool_t AliAnalysisTaskEMCALClusterize::AcceptCalibrateCell(const Int_t absID,
+ Float_t & amp,
+ Double_t & time,
+ AliVCaloCells* cells)
{
- // Main loop
- // Called for each event
-
- //printf("--- Event %d -- \n",(Int_t)Entry());
- //Remove the contents of output list set in the previous event
- fOutputAODBranch->Clear("C");
+ // Reject cell if criteria not passed and calibrate it
- AliVEvent * event = InputEvent();
- AliESDEvent * esdevent = dynamic_cast<AliESDEvent*>(InputEvent());
-
- if (!event) {
- Error("UserExec","Event not available");
- return;
- }
+ if(absID < 0 || absID >= 24*48*fGeom->GetNumberOfSuperModules()) return kFALSE;
- //Magic line to write events to AOD file
- AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(fFillAODFile);
- LoadBranches();
+ Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
+ fGeom->GetCellIndex(absID,imod,iTower,iIphi,iIeta);
+ fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
- AccessOCDB();
-
- //-------------------------------------------------------------------------------------
- //Set the geometry matrix, for the first event, skip the rest
- //-------------------------------------------------------------------------------------
- if(!fGeomMatrixSet){
- if(fLoadGeomMatrices){
- for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
- if(fGeomMatrix[mod]){
- if(DebugLevel() > 1)
- fGeomMatrix[mod]->Print();
- fGeom->SetMisalMatrix(fGeomMatrix[mod],mod) ;
- }
- fGeomMatrixSet=kTRUE;
- }//SM loop
- }//Load matrices
- else if(!gGeoManager){
- Info("UserExec","Get geo matrices from data");
- //Still not implemented in AOD, just a workaround to be able to work at least with ESDs
- if(!strcmp(event->GetName(),"AliAODEvent")) {
- if(DebugLevel() > 1)
- Warning("UserExec","Use ideal geometry, values geometry matrix not kept in AODs.");
- }//AOD
- else {
- if(DebugLevel() > 1)
- Info("UserExec","AliAnalysisTaskEMCALClusterize Load Misaligned matrices.");
- AliESDEvent* esd = dynamic_cast<AliESDEvent*>(event) ;
- if(!esd) {
- Error("UserExec","This event does not contain ESDs?");
- return;
- }
- for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
- if(DebugLevel() > 1)
- esd->GetEMCALMatrix(mod)->Print();
- if(esd->GetEMCALMatrix(mod)) fGeom->SetMisalMatrix(esd->GetEMCALMatrix(mod),mod) ;
- }
- fGeomMatrixSet=kTRUE;
- }//ESD
- }//Load matrices from Data
-
- //Recover time dependent corrections, put then in recalibration histograms. Do it once
- fRecoUtils->SetTimeDependentCorrections(InputEvent()->GetRunNumber());
-
- }//first event
-
- //Get the list of cells needed for unfolding and reclustering
- AliVCaloCells *cells= event->GetEMCALCells();
- Int_t nClustersOrg = 0;
- //-------------------------------------------
- //---------Unfolding clusters----------------
- //-------------------------------------------
- if (fJustUnfold) {
-
- //Fill the array with the EMCAL clusters, copy them
- for (Int_t i = 0; i < event->GetNumberOfCaloClusters(); i++)
- {
- AliVCluster *clus = event->GetCaloCluster(i);
- if(clus->IsEMCAL()){
- //printf("Org Cluster %d, E %f\n",i, clus->E());
-
- //recalibrate/remove bad channels/etc if requested
- if(fRecoUtils->ClusterContainsBadChannel(fGeom,clus->GetCellsAbsId(), clus->GetNCells())){
- //printf("Remove cluster\n");
- continue;
- }
-
- if(fRecoUtils->IsRecalibrationOn()){
- //printf("Energy before %f ",clus->E());
- fRecoUtils->RecalibrateClusterEnergy(fGeom, clus, cells);
- //printf("; after %f\n",clus->E());
- }
- //Cast to ESD or AOD, needed to create the cluster array
- AliESDCaloCluster * esdCluster = dynamic_cast<AliESDCaloCluster*> (clus);
- AliAODCaloCluster * aodCluster = dynamic_cast<AliAODCaloCluster*> (clus);
- if (esdCluster){
- fCaloClusterArr->Add( new AliESDCaloCluster(*esdCluster) );
- }//ESD
- else if(aodCluster){
- fCaloClusterArr->Add( new AliAODCaloCluster(*aodCluster) );
- }//AOD
- else
- Warning("UserExec()"," - Wrong CaloCluster type?");
- nClustersOrg++;
- }
- }
-
- //Do the unfolding
- fUnfolder->UnfoldClusters(fCaloClusterArr, cells);
-
- //CLEAN-UP
- fUnfolder->Clear();
-
-
- //printf("nClustersOrg %d\n",nClustersOrg);
+ // Do not include bad channels found in analysis,
+ if( fRecoUtils->IsBadChannelsRemovalSwitchedOn() &&
+ fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)) {
+ return kFALSE;
+ }
+ //Recalibrate energy
+ amp = cells->GetCellAmplitude(absID);
+ if(fRecoUtils->IsRecalibrationOn()){
+ amp *=fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
}
- //-------------------------------------------
- //---------- Recluster cells ----------------
- //-------------------------------------------
- else{
- //-------------------------------------------------------------------------------------
- //Transform CaloCells into Digits
- //-------------------------------------------------------------------------------------
- Int_t idigit = 0;
- Int_t id = -1;
- Float_t amp = -1;
- Float_t time = -1;
-
- Double_t cellAmplitude = 0;
- Double_t cellTime = 0;
- Short_t cellNumber = 0;
-
- TTree *digitsTree = new TTree("digitstree","digitstree");
- digitsTree->Branch("EMCAL","TClonesArray", &fDigitsArr, 32000);
-
- for (Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++)
- {
- if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
- break;
-
- time = cellTime;
- amp = cellAmplitude;
- id = cellNumber;
-
- Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
- fGeom->GetCellIndex(id,imod,iTower,iIphi,iIeta);
- fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
-
- //Do not include bad channels found in analysis?
- if( fRecoUtils->IsBadChannelsRemovalSwitchedOn() &&
- fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)){
- //printf("Remove channel %d\n",id);
- continue;
- }
-
- //Recalibrate?
- if(fRecoUtils->IsRecalibrationOn()){
- //printf("CalibFactor %f times %f for id %d\n",fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi),amp,id);
- amp *=fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
- }
-
- AliEMCALDigit *digit = (AliEMCALDigit*) fDigitsArr->New(idigit);
- digit->SetId(id);
- digit->SetAmplitude(amp);
- digit->SetTime(time);
- digit->SetTimeR(time);
- digit->SetIndexInList(idigit);
- digit->SetType(AliEMCALDigit::kHG);
-
- //printf("Digit: Id %d, amp %f, time %e, index %d\n",id, amp,time,idigit);
- idigit++;
- }
-
- //Fill the tree with digits
- digitsTree->Fill();
-
- //-------------------------------------------------------------------------------------
- //Do the clusterization
- //-------------------------------------------------------------------------------------
- TTree *clustersTree = new TTree("clustertree","clustertree");
-
- fClusterizer->SetInput(digitsTree);
- fClusterizer->SetOutput(clustersTree);
- fClusterizer->Digits2Clusters("");
-
- //-------------------------------------------------------------------------------------
- //Transform the recpoints into AliVClusters
- //-------------------------------------------------------------------------------------
-
- clustersTree->SetBranchStatus("*",0); //disable all branches
- clustersTree->SetBranchStatus("EMCALECARP",1); //Enable only the branch we need
-
- TBranch *branch = clustersTree->GetBranch("EMCALECARP");
- branch->SetAddress(&fClusterArr);
- branch->GetEntry(0);
-
- RecPoints2Clusters(fDigitsArr, fClusterArr, fCaloClusterArr);
-
- //---CLEAN UP-----
- fClusterizer->Clear();
- fDigitsArr ->Clear("C");
- fClusterArr ->Delete(); // Do not Clear(), it leaks, why?
-
- clustersTree->Delete("all");
- digitsTree ->Delete("all");
+ // Do not include cells with too low energy, nor exotic cell
+ if(amp < fRecParam->GetMinECut() ) {
+ amp = 0.;
+ return kFALSE;
}
- //Recalculate track-matching for the new clusters, only with ESDs
- if(esdevent)fRecoUtils->FindMatches(esdevent,fCaloClusterArr);
-
+ // Recalibrate time
+ time = cells->GetCellTime(absID);
+ Int_t bc = InputEvent()->GetBunchCrossNumber();
- //-------------------------------------------------------------------------------------
- //Put the new clusters in the AOD list
- //-------------------------------------------------------------------------------------
+ // In case of AOD analysis cell time is 0, approximate replacing by time of the cluster the digit belongs.
+ if (time*1e9 < 1.) time = fCellTime[absID];
- Int_t kNumberOfCaloClusters = fCaloClusterArr->GetEntries();
- //Info("UserExec","New clusters %d",kNumberOfCaloClusters);
- //if(nClustersOrg!=kNumberOfCaloClusters) Info("UserExec","Different number: Org %d, New %d\n",nClustersOrg,kNumberOfCaloClusters);
- for(Int_t i = 0; i < kNumberOfCaloClusters; i++){
- AliAODCaloCluster *newCluster = (AliAODCaloCluster *) fCaloClusterArr->At(i);
- //if(Entry()==0) Info("UserExec","newCluster E %f\n", newCluster->E());
+ fRecoUtils->RecalibrateCellTime(absID,bc,time);
- //Add matched track, if any, only with ESDs
- if(esdevent){
- Int_t trackIndex = fRecoUtils->GetMatchedTrackIndex(i);
- if(trackIndex >= 0){
- newCluster->AddTrackMatched(event->GetTrack(trackIndex));
- if(DebugLevel() > 1)
- Info("UserExec","Matched Track index %d to new cluster %d \n",trackIndex,i);
- }
- }
-
- //In case of new bad channels, recalculate distance to bad channels
- if(fRecoUtils->IsBadChannelsRemovalSwitchedOn()){
- //printf("DistToBad before %f ",newCluster->GetDistanceToBadChannel());
- fRecoUtils->RecalculateClusterDistanceToBadChannel(fGeom, event->GetEMCALCells(), newCluster);
- //printf("; after %f \n",newCluster->GetDistanceToBadChannel());
- }
-
- newCluster->SetID(i);
- //printf("Cluster %d, energy %f\n",newCluster->GetID(),newCluster->E());
- new((*fOutputAODBranch)[i]) AliAODCaloCluster(*newCluster);
- }
+ //printf("AliAnalysisTaskEMCALClusterize::AcceptCalibrateCell() - Accepted Cell id %d, amp %f, t %f\n",absID,amp,time*1.e9);
- //---CLEAN UP-----
- fCaloClusterArr->Delete(); // Do not Clear(), it leaks, why?
-}
+ return kTRUE;
+}
-//_____________________________________________________________________
+
+//_________________________________________________
Bool_t AliAnalysisTaskEMCALClusterize::AccessOCDB()
{
//Access to OCDB stuff
-
- AliVEvent * event = InputEvent();
- if (!event)
+
+ fEvent = InputEvent();
+ if (!fEvent)
{
Warning("AccessOCDB","Event not available!!!");
return kFALSE;
}
-
- if (event->GetRunNumber()==fRun)
+
+ if (fEvent->GetRunNumber()==fRun)
return kTRUE;
- fRun = event->GetRunNumber();
-
+ fRun = fEvent->GetRunNumber();
+
if(DebugLevel() > 1 )
- Info("AccessODCD()"," Begin");
-
- fGeom = AliEMCALGeometry::GetInstance(fGeomName);
+ printf("AliAnalysisTaksEMCALClusterize::AccessODCD() - Begin");
+ //fGeom = AliEMCALGeometry::GetInstance(fGeomName);
AliCDBManager *cdb = AliCDBManager::Instance();
-
-
+
+
if (fOCDBpath.Length()){
cdb->SetDefaultStorage(fOCDBpath.Data());
- Info("AccessOCDB","Default storage %s",fOCDBpath.Data());
+ printf("AliAnalysisTaksEMCALClusterize::AccessOCDB() - Default storage %s",fOCDBpath.Data());
}
- cdb->SetRun(event->GetRunNumber());
-
+ cdb->SetRun(fEvent->GetRunNumber());
+
//
// EMCAL from RAW OCDB
if (fOCDBpath.Contains("alien:"))
cdb->SetSpecificStorage("EMCAL/Calib/Data","alien://Folder=/alice/data/2010/OCDB");
cdb->SetSpecificStorage("EMCAL/Calib/Pedestals","alien://Folder=/alice/data/2010/OCDB");
}
-
+
TString path = cdb->GetDefaultStorage()->GetBaseFolder();
// init parameters:
if(!fCalibData)
{
AliCDBEntry *entry = (AliCDBEntry*)
- AliCDBManager::Instance()->Get("EMCAL/Calib/Data");
+ AliCDBManager::Instance()->Get("EMCAL/Calib/Data");
if (entry) fCalibData = (AliEMCALCalibData*) entry->GetObject();
}
if(!fCalibData)
AliFatal("Calibration parameters not found in CDB!");
-
+
//Get calibration parameters
if(!fPedestalData)
{
AliCDBEntry *entry = (AliCDBEntry*)
- AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals");
+ AliCDBManager::Instance()->Get("EMCAL/Calib/Pedestals");
if (entry) fPedestalData = (AliCaloCalibPedestal*) entry->GetObject();
}
-
+
if(!fPedestalData)
AliFatal("Dead map not found in CDB!");
-
- InitClusterization();
return kTRUE;
}
-//________________________________________________________________________________________
+//_______________________________________________________________________
+void AliAnalysisTaskEMCALClusterize::CheckAndGetEvent()
+{
+ // Get the input event, it can depend in embedded events what you want to get
+ // Also check if the quality of the event is good if not reject it
+
+ fEvent = 0x0;
+
+ AliAODInputHandler* aodIH = dynamic_cast<AliAODInputHandler*>((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
+ Int_t eventN = Entry();
+ if(aodIH) eventN = aodIH->GetReadEntry();
+
+ if (eventN > fMaxEvent)
+ return ;
+
+ //printf("Clusterizer --- Event %d-- \n",eventN);
+
+ //Check if input event are embedded events
+ //If so, take output event
+ if (aodIH && aodIH->GetMergeEvents()) {
+ fEvent = AODEvent();
+
+ if(!aodIH->GetMergeEMCALCells())
+ AliFatal("Events merged but not EMCAL cells, check analysis settings!");
+
+ if(DebugLevel() > 1){
+ printf("AliAnalysisTaksEMCALClusterize::UserExec() - Use embedded events\n");
+ printf("\t InputEvent N Clusters %d, N Cells %d\n",InputEvent()->GetNumberOfCaloClusters(),
+ InputEvent()->GetEMCALCells()->GetNumberOfCells());
+ printf("\t MergedEvent N Clusters %d, N Cells %d\n",aodIH->GetEventToMerge()->GetNumberOfCaloClusters(),
+ aodIH->GetEventToMerge()->GetEMCALCells()->GetNumberOfCells());
+ for (Int_t icl=0; icl < aodIH->GetEventToMerge()->GetNumberOfCaloClusters(); icl++) {
+ AliAODCaloCluster *sigCluster = aodIH->GetEventToMerge()->GetCaloCluster(icl);
+ if(sigCluster->IsEMCAL()) printf("\t \t Signal cluster: i %d, E %f\n",icl,sigCluster->E());
+ }
+ printf("\t OutputEvent N Clusters %d, N Cells %d\n", AODEvent()->GetNumberOfCaloClusters(),
+ AODEvent()->GetEMCALCells()->GetNumberOfCells());
+ }
+ }
+ else {
+ fEvent = InputEvent();
+ if(fFillAODCaloCells) FillAODCaloCells();
+ if(fFillAODHeader) FillAODHeader();
+ }
+
+ if (!fEvent) {
+ Error("UserExec","Event not available");
+ return ;
+ }
+
+ //-------------------------------------------------------------------------------------
+ // Reject events if LED was firing, use only for LHC11a data
+ // Reject event if triggered by exotic cell and remove exotic cells if not triggered
+ //-------------------------------------------------------------------------------------
+
+ if(IsLEDEvent ()) { fEvent = 0x0 ; return ; }
+
+ if(IsExoticEvent()) { fEvent = 0x0 ; return ; }
+
+ //Magic line to write events to AOD filem put after event rejection
+ AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(fFillAODFile);
+
+}
+
+//____________________________________________________
+void AliAnalysisTaskEMCALClusterize::ClusterizeCells()
+{
+ // Recluster calocells, transform them into digits,
+ // feed the clusterizer with them and get new list of clusters
+
+ //In case of MC, first loop on the clusters and fill MC label to array
+ Int_t nClusters = fEvent->GetNumberOfCaloClusters();
+ Int_t nClustersOrg = 0;
+
+ AliAODInputHandler* aodIH = dynamic_cast<AliAODInputHandler*>((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
+ if(aodIH && aodIH->GetEventToMerge()) //Embedding
+ nClusters = aodIH->GetEventToMerge()->GetNumberOfCaloClusters(); //Get clusters directly from embedded signal
+
+ for (Int_t i = 0; i < nClusters; i++)
+ {
+ AliVCluster *clus = 0;
+ if(aodIH && aodIH->GetEventToMerge()) //Embedding
+ clus = aodIH->GetEventToMerge()->GetCaloCluster(i); //Get clusters directly from embedded signal
+ else
+ clus = fEvent->GetCaloCluster(i);
+
+ if(!clus) return;
+
+ if(clus->IsEMCAL()){
+ Int_t label = clus->GetLabel();
+ Int_t label2 = -1 ;
+ if (clus->GetNLabels()>=2) label2 = clus->GetLabelAt(1) ;
+ UShort_t * index = clus->GetCellsAbsId() ;
+ for(Int_t icell=0; icell < clus->GetNCells(); icell++ ){
+ fCellLabels[index[icell]] = label;
+ fCellSecondLabels[index[icell]] = label2;
+ fCellTime[icell] = clus->GetTOF();
+ }
+ nClustersOrg++;
+ }
+ }
+
+ // Transform CaloCells into Digits
+
+ Int_t idigit = 0;
+ Int_t id = -1;
+ Float_t amp = -1;
+ Double_t time = -1;
+
+ AliVCaloCells *cells = fEvent->GetEMCALCells();
+
+ TTree *digitsTree = new TTree("digitstree","digitstree");
+ digitsTree->Branch("EMCAL","TClonesArray", &fDigitsArr, 32000);
+
+ for (Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++)
+ {
+
+ // Get cell values, recalibrate and not include bad channels found in analysis, nor cells with too low energy, nor exotic cell
+ id = cells->GetCellNumber(icell);
+ Bool_t accept = AcceptCalibrateCell(id,amp,time,cells);
+ if( accept && IsExoticCell(id,amp,time,cells)) accept = kFALSE;
+ if( !accept ){
+ fCellLabels[id] =-1; //reset the entry in the array for next event
+ fCellSecondLabels[id]=-1; //reset the entry in the array for next event
+ fCellTime[id] = 0.;
+ if( DebugLevel() > 2 ) printf("AliAnalysisTaksEMCALClusterize::ClusterizeCells() - Remove channel absId %d, index %d of %d, amp %f, time %f\n",
+ id,icell, cells->GetNumberOfCells(), amp, time*1.e9);
+ continue;
+ }
+
+ //Create the digit, put a fake primary deposited energy to trick the clusterizer when checking the most likely primary
+ new((*fDigitsArr)[idigit]) AliEMCALDigit( fCellLabels[id], fCellLabels[id],id, amp, time,AliEMCALDigit::kHG,idigit, 0, 0, 1);
+
+ fCellLabels[id] =-1; //reset the entry in the array for next event
+
+ idigit++;
+ }
+
+ //Fill the tree with digits
+ digitsTree->Fill();
+
+ //-------------------------------------------------------------------------------------
+ //Do the clusterization
+ //-------------------------------------------------------------------------------------
+ TTree *clustersTree = new TTree("clustertree","clustertree");
+
+ fClusterizer->SetInput(digitsTree);
+ fClusterizer->SetOutput(clustersTree);
+ fClusterizer->Digits2Clusters("");
+
+ //-------------------------------------------------------------------------------------
+ //Transform the recpoints into AliVClusters
+ //-------------------------------------------------------------------------------------
+
+ clustersTree->SetBranchStatus("*",0); //disable all branches
+ clustersTree->SetBranchStatus("EMCALECARP",1); //Enable only the branch we need
+
+ TBranch *branch = clustersTree->GetBranch("EMCALECARP");
+ branch->SetAddress(&fClusterArr);
+ branch->GetEntry(0);
+
+ RecPoints2Clusters(fDigitsArr, fClusterArr, fCaloClusterArr);
+
+ if(!fCaloClusterArr){
+ printf("AliAnalysisTaksEMCALClusterize::UserExec() - No array with CaloClusters, input RecPoints entries %d\n",fClusterArr->GetEntriesFast());
+ return;
+ }
+
+ if( DebugLevel() > 0 ){
+
+ printf("AliAnalysisTaksEMCALClusterize::ClusterizeCells() - N clusters: before recluster %d, after recluster %d\n",nClustersOrg, fCaloClusterArr->GetEntriesFast());
+
+ if(fCaloClusterArr->GetEntriesFast() != fClusterArr->GetEntriesFast()){
+ printf("\t Some RecRoints not transformed into CaloClusters (clusterizer %d, unfold %d): Input entries %d - Output entries %d - %d (not fast)\n",
+ fRecParam->GetClusterizerFlag(),fRecParam->GetUnfold(),
+ fClusterArr->GetEntriesFast(), fCaloClusterArr->GetEntriesFast(), fCaloClusterArr->GetEntries());
+ }
+ }
+
+ //Reset the array with second labels for this event
+ memset(fCellSecondLabels, -1, sizeof(fCellSecondLabels));
+
+ //---CLEAN UP-----
+ fClusterizer->Clear();
+ fDigitsArr ->Clear("C");
+ fClusterArr ->Delete(); // Do not Clear(), it leaks, why?
+
+ clustersTree->Delete("all");
+ digitsTree ->Delete("all");
+
+}
+
+//_____________________________________________________________________
+void AliAnalysisTaskEMCALClusterize::ClusterUnfolding()
+{
+ // Take the event clusters and unfold them
+
+ AliVCaloCells *cells = fEvent->GetEMCALCells();
+ Double_t cellAmplitude = 0;
+ Double_t cellTime = 0;
+ Short_t cellNumber = 0;
+ Int_t nClustersOrg = 0;
+
+ // Fill the array with the EMCAL clusters, copy them
+ for (Int_t i = 0; i < fEvent->GetNumberOfCaloClusters(); i++)
+ {
+ AliVCluster *clus = fEvent->GetCaloCluster(i);
+ if(clus->IsEMCAL()){
+
+ //recalibrate/remove bad channels/etc if requested
+ if(fRecoUtils->ClusterContainsBadChannel(fGeom,clus->GetCellsAbsId(), clus->GetNCells())){
+ continue;
+ }
+
+ if(fRecoUtils->IsRecalibrationOn()){
+
+ //Calibrate cluster
+ fRecoUtils->RecalibrateClusterEnergy(fGeom, clus, cells);
+
+ //CalibrateCells
+ for (Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++)
+ {
+ if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
+ break;
+
+ Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
+ fGeom->GetCellIndex(cellNumber,imod,iTower,iIphi,iIeta);
+ fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
+
+ //Do not include bad channels found in analysis?
+ if( fRecoUtils->IsBadChannelsRemovalSwitchedOn() &&
+ fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)){
+ fCellLabels[cellNumber] =-1; //reset the entry in the array for next event
+ fCellSecondLabels[cellNumber]=-1; //reset the entry in the array for next event
+ fCellTime[cellNumber] = 0.;
+ continue;
+ }
+
+ cells->SetCell(icell, cellNumber, cellAmplitude*fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi),cellTime);
+
+ }// cells loop
+ }// recalibrate
+
+ //Cast to ESD or AOD, needed to create the cluster array
+ AliESDCaloCluster * esdCluster = dynamic_cast<AliESDCaloCluster*> (clus);
+ AliAODCaloCluster * aodCluster = dynamic_cast<AliAODCaloCluster*> (clus);
+ if (esdCluster){
+ fCaloClusterArr->Add( new AliESDCaloCluster(*esdCluster) );
+ }//ESD
+ else if(aodCluster){
+ fCaloClusterArr->Add( new AliAODCaloCluster(*aodCluster) );
+ }//AOD
+ else
+ Warning("UserExec()"," - Wrong CaloCluster type?");
+ nClustersOrg++;
+ }
+ }
+
+ //Do the unfolding
+ fUnfolder->UnfoldClusters(fCaloClusterArr, cells);
+
+ //CLEAN-UP
+ fUnfolder->Clear();
+
+}
+
+//_____________________________________________________
+void AliAnalysisTaskEMCALClusterize::FillAODCaloCells()
+{
+ // Put calo cells in standard branch
+ AliVCaloCells &eventEMcells = *(fEvent->GetEMCALCells());
+ Int_t nEMcell = eventEMcells.GetNumberOfCells() ;
+
+ AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
+ aodEMcells.CreateContainer(nEMcell);
+ aodEMcells.SetType(AliVCaloCells::kEMCALCell);
+ Double_t calibFactor = 1.;
+ for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
+ Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
+ fGeom->GetCellIndex(eventEMcells.GetCellNumber(iCell),imod,iTower,iIphi,iIeta);
+ fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
+
+ if(fRecoUtils->IsRecalibrationOn()){
+ calibFactor = fRecoUtils->GetEMCALChannelRecalibrationFactor(imod,ieta,iphi);
+ }
+
+ if(!fRecoUtils->GetEMCALChannelStatus(imod, ieta, iphi)){ //Channel is not declared as bad
+ aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),eventEMcells.GetAmplitude(iCell)*calibFactor);
+ }
+ else {
+ aodEMcells.SetCell(iCell,eventEMcells.GetCellNumber(iCell),0);
+ }
+ }
+ aodEMcells.Sort();
+
+}
+
+//__________________________________________________
+void AliAnalysisTaskEMCALClusterize::FillAODHeader()
+{
+ //Put event header information in standard AOD branch
+
+ AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (fEvent);
+ AliAODEvent* aodevent = dynamic_cast<AliAODEvent*> (fEvent);
+
+ Double_t pos[3] ;
+ Double_t covVtx[6];
+ for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
+
+ AliAODHeader* header = AODEvent()->GetHeader();
+ header->SetRunNumber(fEvent->GetRunNumber());
+
+ if(esdevent){
+ TTree* tree = fInputHandler->GetTree();
+ if (tree) {
+ TFile* file = tree->GetCurrentFile();
+ if (file) header->SetESDFileName(file->GetName());
+ }
+ }
+ else if (aodevent) header->SetESDFileName(aodevent->GetHeader()->GetESDFileName());
+
+ header->SetBunchCrossNumber(fEvent->GetBunchCrossNumber());
+ header->SetOrbitNumber(fEvent->GetOrbitNumber());
+ header->SetPeriodNumber(fEvent->GetPeriodNumber());
+ header->SetEventType(fEvent->GetEventType());
+
+ //Centrality
+ if(fEvent->GetCentrality()){
+ header->SetCentrality(new AliCentrality(*(fEvent->GetCentrality())));
+ }
+ else{
+ header->SetCentrality(0);
+ }
+
+ //Trigger
+ header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
+ if (esdevent) header->SetFiredTriggerClasses(esdevent->GetFiredTriggerClasses());
+ else if (aodevent) header->SetFiredTriggerClasses(aodevent->GetFiredTriggerClasses());
+ header->SetTriggerMask(fEvent->GetTriggerMask());
+ header->SetTriggerCluster(fEvent->GetTriggerCluster());
+ if(esdevent){
+ header->SetL0TriggerInputs(esdevent->GetHeader()->GetL0TriggerInputs());
+ header->SetL1TriggerInputs(esdevent->GetHeader()->GetL1TriggerInputs());
+ header->SetL2TriggerInputs(esdevent->GetHeader()->GetL2TriggerInputs());
+ }
+ else if (aodevent){
+ header->SetL0TriggerInputs(aodevent->GetHeader()->GetL0TriggerInputs());
+ header->SetL1TriggerInputs(aodevent->GetHeader()->GetL1TriggerInputs());
+ header->SetL2TriggerInputs(aodevent->GetHeader()->GetL2TriggerInputs());
+ }
+
+ header->SetMagneticField(fEvent->GetMagneticField());
+ //header->SetMuonMagFieldScale(esdevent->GetCurrentDip()/6000.);
+
+ header->SetZDCN1Energy(fEvent->GetZDCN1Energy());
+ header->SetZDCP1Energy(fEvent->GetZDCP1Energy());
+ header->SetZDCN2Energy(fEvent->GetZDCN2Energy());
+ header->SetZDCP2Energy(fEvent->GetZDCP2Energy());
+ header->SetZDCEMEnergy(fEvent->GetZDCEMEnergy(0),fEvent->GetZDCEMEnergy(1));
+
+ Float_t diamxy[2]={fEvent->GetDiamondX(),fEvent->GetDiamondY()};
+ Float_t diamcov[3];
+ fEvent->GetDiamondCovXY(diamcov);
+ header->SetDiamond(diamxy,diamcov);
+ if (esdevent) header->SetDiamondZ(esdevent->GetDiamondZ(),esdevent->GetSigma2DiamondZ());
+ else if (aodevent) header->SetDiamondZ(aodevent->GetDiamondZ(),aodevent->GetSigma2DiamondZ());
+
+ //
+ //
+ Int_t nVertices = 1 ;/* = prim. vtx*/;
+ Int_t nCaloClus = fEvent->GetNumberOfCaloClusters();
+
+ AODEvent()->ResetStd(0, nVertices, 0, 0, 0, nCaloClus, 0, 0);
+
+ // Access to the AOD container of vertices
+ TClonesArray &vertices = *(AODEvent()->GetVertices());
+ Int_t jVertices=0;
+
+ // Add primary vertex. The primary tracks will be defined
+ // after the loops on the composite objects (V0, cascades, kinks)
+ fEvent->GetPrimaryVertex()->GetXYZ(pos);
+ Float_t chi = 0;
+ if (esdevent){
+ esdevent->GetPrimaryVertex()->GetCovMatrix(covVtx);
+ chi = esdevent->GetPrimaryVertex()->GetChi2toNDF();
+ }
+ else if (aodevent){
+ aodevent->GetPrimaryVertex()->GetCovMatrix(covVtx);
+ chi = aodevent->GetPrimaryVertex()->GetChi2perNDF();//Different from ESD?
+ }
+
+ AliAODVertex * primary = new(vertices[jVertices++])
+ AliAODVertex(pos, covVtx, chi, NULL, -1, AliAODVertex::kPrimary);
+ primary->SetName(fEvent->GetPrimaryVertex()->GetName());
+ primary->SetTitle(fEvent->GetPrimaryVertex()->GetTitle());
+
+}
+
+//_________________________________________
+void AliAnalysisTaskEMCALClusterize::Init()
+{
+ //Init analysis with configuration macro if available
+
+ if(gROOT->LoadMacro(fConfigName) >=0){
+ printf("AliAnalysisTaksEMCALClusterize::Init() - Configure analysis with %s\n",fConfigName.Data());
+ AliAnalysisTaskEMCALClusterize *clus = (AliAnalysisTaskEMCALClusterize*)gInterpreter->ProcessLine("ConfigEMCALClusterize()");
+ fGeomName = clus->fGeomName;
+ fLoadGeomMatrices = clus->fLoadGeomMatrices;
+ fOCDBpath = clus->fOCDBpath;
+ fAccessOCDB = clus->fAccessOCDB;
+ fRecParam = clus->fRecParam;
+ fJustUnfold = clus->fJustUnfold;
+ fFillAODFile = clus->fFillAODFile;
+ fRecoUtils = clus->fRecoUtils;
+ fConfigName = clus->fConfigName;
+ fMaxEvent = clus->fMaxEvent;
+ fDoTrackMatching = clus->fDoTrackMatching;
+ fOutputAODBranchName = clus->fOutputAODBranchName;
+ for(Int_t i = 0; i < 10; i++) fGeomMatrix[i] = clus->fGeomMatrix[i] ;
+
+ }
+
+}
+
+//_______________________________________________________
void AliAnalysisTaskEMCALClusterize::InitClusterization()
{
//Select clusterization/unfolding algorithm and set all the needed parameters
if (fJustUnfold){
// init the unfolding afterburner
delete fUnfolder;
- fUnfolder = new AliEMCALAfterBurnerUF(fRecParam->GetW0(),fRecParam->GetLocMaxCut());
+ fUnfolder = new AliEMCALAfterBurnerUF(fRecParam->GetW0(),fRecParam->GetLocMaxCut(),fRecParam->GetMinECut());
return;
- }
-
+ }
+
//First init the clusterizer
delete fClusterizer;
if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
fClusterizer = new AliEMCALClusterizerv1 (fGeom, fCalibData, fPedestalData);
- else if(fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN)
+ else if(fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
+ fClusterizer = new AliEMCALClusterizerv2(fGeom, fCalibData, fPedestalData);
+ else if(fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN){
fClusterizer = new AliEMCALClusterizerNxN(fGeom, fCalibData, fPedestalData);
- else if(fRecParam->GetClusterizerFlag() > AliEMCALRecParam::kClusterizerNxN) {
- AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fGeom, fCalibData, fPedestalData);
- clusterizer->SetNRowDiff(2);
- clusterizer->SetNColDiff(2);
- fClusterizer = clusterizer;
- } else{
+ fClusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
+ fClusterizer->SetNColDiff(fRecParam->GetNColDiff());
+ } else {
AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
}
-
+
//Now set the parameters
fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
fClusterizer->SetECALogWeight ( fRecParam->GetW0() );
}//end of loop over parameters
fClusterizer->InitClusterUnfolding();
+
}// to unfold
}
-//________________________________________________________________________________________
-void AliAnalysisTaskEMCALClusterize::RecPoints2Clusters(TClonesArray *digitsArr, TObjArray *recPoints, TObjArray *clusArray)
+//_________________________________________________
+void AliAnalysisTaskEMCALClusterize::InitGeometry()
+{
+ // Set the geometry matrix, for the first event, skip the rest
+ // Also set once the run dependent calibrations
+
+ if(!fGeomMatrixSet){
+ if(fLoadGeomMatrices){
+ for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
+ if(fGeomMatrix[mod]){
+ if(DebugLevel() > 1)
+ fGeomMatrix[mod]->Print();
+ fGeom->SetMisalMatrix(fGeomMatrix[mod],mod) ;
+ }
+ fGeomMatrixSet=kTRUE;
+ }//SM loop
+ }//Load matrices
+ else if(!gGeoManager){
+ printf("AliAnalysisTaksEMCALClusterize::InitGeometry() - Get geo matrices from data");
+ //Still not implemented in AOD, just a workaround to be able to work at least with ESDs
+ if(!strcmp(fEvent->GetName(),"AliAODEvent")) {
+ if(DebugLevel() > 1)
+ Warning("UserExec","Use ideal geometry, values geometry matrix not kept in AODs.");
+ }//AOD
+ else {
+ if(DebugLevel() > 1)
+ printf("AliAnalysisTaksEMCALClusterize::InitGeometry() - AliAnalysisTaskEMCALClusterize Load Misaligned matrices.");
+ AliESDEvent* esd = dynamic_cast<AliESDEvent*>(fEvent) ;
+ if(!esd) {
+ Error("InitGeometry"," - This event does not contain ESDs?");
+ AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kFALSE);
+ return;
+ }
+ for(Int_t mod=0; mod < (fGeom->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
+ if(DebugLevel() > 1)
+ esd->GetEMCALMatrix(mod)->Print();
+ if(esd->GetEMCALMatrix(mod)) fGeom->SetMisalMatrix(esd->GetEMCALMatrix(mod),mod) ;
+ }
+ fGeomMatrixSet=kTRUE;
+ }//ESD
+ }//Load matrices from Data
+
+ //Recover time dependent corrections, put then in recalibration histograms. Do it once
+ fRecoUtils->SetRunDependentCorrections(InputEvent()->GetRunNumber());
+
+ }//first event
+
+}
+
+//___________________________________________________________________
+Bool_t AliAnalysisTaskEMCALClusterize::IsExoticCell(const Int_t absID,
+ const Float_t ecell,
+ const Float_t tcell,
+ AliVCaloCells* cells)
+{
+ //Look to cell neighbourhood and reject if it seems exotic
+
+ if(!fRemoveExoticCells) return kFALSE;
+
+ if(ecell < fExoticCellMinAmplitude) return kFALSE;
+
+ Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
+ fGeom->GetCellIndex(absID,imod,iTower,iIphi,iIeta);
+ fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,iphi,ieta);
+
+ //Get close cells index, energy and time, not in corners
+ Int_t absID1 = fGeom-> GetAbsCellIdFromCellIndexes(imod, iphi+1, ieta);
+ Int_t absID2 = fGeom-> GetAbsCellIdFromCellIndexes(imod, iphi-1, ieta);
+ Int_t absID3 = fGeom-> GetAbsCellIdFromCellIndexes(imod, iphi, ieta+1);
+ Int_t absID4 = fGeom-> GetAbsCellIdFromCellIndexes(imod, iphi, ieta-1);
+
+ Float_t ecell1 = 0, ecell2 = 0, ecell3 = 0, ecell4 = 0;
+ Double_t tcell1 = 0, tcell2 = 0, tcell3 = 0, tcell4 = 0;
+ Bool_t accept1 = 0, accept2 = 0, accept3 = 0, accept4 = 0;
+
+ accept1 = AcceptCalibrateCell(absID1,ecell1,tcell1,cells);
+ accept2 = AcceptCalibrateCell(absID2,ecell2,tcell2,cells);
+ accept3 = AcceptCalibrateCell(absID3,ecell3,tcell3,cells);
+ accept4 = AcceptCalibrateCell(absID4,ecell4,tcell4,cells);
+
+ if(DebugLevel() > 2 ){
+ printf("AliAnalysisTaksEMCALClusterize::IsExoticCell() - Cell absID %d \n",absID);
+ printf("\t accept1 %d, accept2 %d, accept3 %d, accept4 %d\n",
+ accept1,accept2,accept3,accept4);
+ printf("\t id %d: id1 %d, id2 %d, id3 %d, id4 %d\n",
+ absID,absID1,absID2,absID3,absID4);
+ printf("\t e %f: e1 %f, e2 %f, e3 %f, e4 %f\n",
+ ecell,ecell1,ecell2,ecell3,ecell4);
+ printf("\t t %f: t1 %f, t2 %f, t3 %f, t4 %f;\n dt1 %f, dt2 %f, dt3 %f, dt4 %f\n",
+ tcell*1.e9,tcell1*1.e9,tcell2*1.e9,tcell3*1.e9,tcell4*1.e9,
+ TMath::Abs(tcell-tcell1)*1.e9, TMath::Abs(tcell-tcell2)*1.e9, TMath::Abs(tcell-tcell3)*1.e9, TMath::Abs(tcell-tcell4)*1.e9);
+ }
+
+ if(TMath::Abs(tcell-tcell1)*1.e9 > fExoticCellDiffTime) ecell1 = 0 ;
+ if(TMath::Abs(tcell-tcell2)*1.e9 > fExoticCellDiffTime) ecell2 = 0 ;
+ if(TMath::Abs(tcell-tcell3)*1.e9 > fExoticCellDiffTime) ecell3 = 0 ;
+ if(TMath::Abs(tcell-tcell4)*1.e9 > fExoticCellDiffTime) ecell4 = 0 ;
+
+
+ Float_t eCross = ecell1+ecell2+ecell3+ecell4;
+ if(DebugLevel() > 2 ){
+ printf("\t eCell %f, eCross %f, 1-eCross/eCell %f\n",ecell,eCross,1-eCross/ecell);
+ }
+
+ if(1-eCross/ecell > fExoticCellFraction) {
+ //cells->SetCell(icell,absID,0,1e6);
+ if(DebugLevel() > 2 ) printf("AliAnalysisTaskEMCALClusterize::IsExoticCell() - EXOTIC CELL REMOVED id %d, eCell %f, eCross %f, 1-eCross/eCell %f\n",absID,ecell,eCross,1-eCross/ecell);
+ return kTRUE;
+ }
+
+ return kFALSE;
+
+}
+
+//____________________________________________________
+Bool_t AliAnalysisTaskEMCALClusterize::IsExoticEvent()
+{
+
+ // Check if event is exotic, get an exotic cell and compare with triggered patch
+ // If there is a match remove event ... to be completed, filled with something provisional
+
+ if(!fRemoveExoticEvents) return kFALSE;
+
+ // Loop on cells
+ AliVCaloCells * cells = fEvent->GetEMCALCells();
+ Float_t totCellE = 0;
+ for(Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++){
+
+ Float_t ecell = 0 ;
+ Double_t tcell = 0 ;
+
+ Int_t absID = cells->GetCellNumber(icell);
+ Bool_t accept = AcceptCalibrateCell(absID,ecell,tcell,cells);
+ if(accept && !IsExoticCell(absID, ecell,tcell,cells)) totCellE += ecell;
+ }
+
+ // TString triggerclasses = "";
+ // if(esdevent) triggerclasses = esdevent ->GetFiredTriggerClasses();
+ // else triggerclasses = ((AliAODEvent*)event)->GetFiredTriggerClasses();
+ // //
+ // printf("AliAnalysisTaskEMCALClusterize - reject event %d with cluster - reject event with ncells in SM3 %d and SM4 %d\n",(Int_t)Entry(),ncellsSM3, ncellsSM4);
+ // AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kFALSE);
+ // return;
+ //
+
+ //printf("TotE cell %f\n",totCellE);
+ if(totCellE < 1) return kTRUE;
+
+ return kFALSE;
+
+}
+
+//_________________________________________________
+Bool_t AliAnalysisTaskEMCALClusterize::IsLEDEvent()
+{
+ //Check if event is LED
+
+ if(!fRemoveLEDEvents) return kFALSE;
+
+ // Count number of cells with energy larger than 0.1 in SM3, cut on this number
+ Int_t ncellsSM3 = 0;
+ Int_t ncellsSM4 = 0;
+ AliVCaloCells * cells = fEvent->GetEMCALCells();
+ for(Int_t icell = 0; icell < cells->GetNumberOfCells(); icell++){
+ if(cells->GetAmplitude(icell) > 0.1 && cells->GetCellNumber(icell)/(24*48)==3) ncellsSM3++;
+ if(cells->GetAmplitude(icell) > 0.1 && cells->GetCellNumber(icell)/(24*48)==4) ncellsSM4++;
+ }
+
+ TString triggerclasses = "";
+
+ AliESDEvent *esdevent = dynamic_cast<AliESDEvent*>(fEvent);
+ if(esdevent) triggerclasses = esdevent ->GetFiredTriggerClasses();
+ else triggerclasses = ((AliAODEvent*)fEvent)->GetFiredTriggerClasses();
+
+ Int_t ncellcut = 21;
+ if(triggerclasses.Contains("EMC")) ncellcut = 35;
+
+ if( ncellsSM3 >= ncellcut || ncellsSM4 >= 100 ){
+ printf("AliAnalysisTaksEMCALClusterize::IsLEDEvent() - reject event %d with ncells in SM3 %d and SM4 %d\n",(Int_t)Entry(),ncellsSM3, ncellsSM4);
+ AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kFALSE);
+ return kTRUE;
+ }
+
+ return kFALSE;
+
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskEMCALClusterize::RecPoints2Clusters(TClonesArray *digitsArr,
+ TObjArray *recPoints,
+ TObjArray *clusArray)
{
// Restore clusters from recPoints
// Cluster energy, global position, cells and their amplitude fractions are restored
-
+ Int_t j = 0;
for(Int_t i = 0; i < recPoints->GetEntriesFast(); i++)
{
AliEMCALRecPoint *recPoint = (AliEMCALRecPoint*) recPoints->At(i);
const Int_t ncells = recPoint->GetMultiplicity();
- Int_t ncells_true = 0;
+ Int_t ncellsTrue = 0;
+
+ if(recPoint->GetEnergy() < fRecParam->GetClusteringThreshold()) continue;
// cells and their amplitude fractions
UShort_t absIds[ncells];
Double32_t ratios[ncells];
+ //For later check embedding
+ AliAODInputHandler* aodIH = dynamic_cast<AliAODInputHandler*>((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
+
+ Float_t clusterE = 0;
for (Int_t c = 0; c < ncells; c++) {
AliEMCALDigit *digit = (AliEMCALDigit*) digitsArr->At(recPoint->GetDigitsList()[c]);
- absIds[ncells_true] = digit->GetId();
- ratios[ncells_true] = recPoint->GetEnergiesList()[c]/digit->GetAmplitude();
+ absIds[ncellsTrue] = digit->GetId();
+ ratios[ncellsTrue] = recPoint->GetEnergiesList()[c]/digit->GetAmplitude();
+
+ // In case of unfolding, remove digits with unfolded energy too low
+ if(fSelectCell){
+ if (recPoint->GetEnergiesList()[c] < fSelectCellMinE || ratios[ncellsTrue] < fSelectCellMinFrac) {
+
+ if(DebugLevel() > 1) {
+ printf("AliAnalysisTaksEMCALClusterize::RecPoints2Clusters() - Too small energy in cell of cluster: cluster cell %f, digit %f\n",
+ recPoint->GetEnergiesList()[c],digit->GetAmplitude());
+ }
+
+ continue;
+
+ } // if cuts
+ }// Select cells
+
+ //Recalculate cluster energy and number of cluster cells in case any of the cells was rejected
+ ncellsTrue++;
+ clusterE +=recPoint->GetEnergiesList()[c];
- if (ratios[ncells_true] > 0.001) ncells_true++;
+ // In case of embedding, fill ratio with amount of signal,
+ if (aodIH && aodIH->GetMergeEvents()) {
+
+ //AliVCaloCells* inEMCALCells = InputEvent()->GetEMCALCells();
+ AliVCaloCells* meEMCALCells = aodIH->GetEventToMerge()->GetEMCALCells();
+ AliVCaloCells* ouEMCALCells = AODEvent()->GetEMCALCells();
+
+ Float_t sigAmplitude = meEMCALCells->GetCellAmplitude(absIds[ncellsTrue]);
+ //Float_t bkgAmplitude = inEMCALCells->GetCellAmplitude(absIds[ncellsTrue]);
+ Float_t sumAmplitude = ouEMCALCells->GetCellAmplitude(absIds[ncellsTrue]);
+ //printf("\t AbsID %d, amplitude : bkg %f, sigAmplitude %f, summed %f - %f\n",absIds[ncellsTrue], bkgAmplitude, sigAmplitude, sumAmplitude, digit->GetAmplitude());
+
+ if(sumAmplitude > 0) ratios[ncellsTrue] = sigAmplitude/sumAmplitude;
+ //printf("\t \t ratio %f\n",ratios[ncellsTrue]);
+
+ }//Embedding
+
+ }// cluster cell loop
+
+ if (ncellsTrue < 1) {
+ if (DebugLevel() > 1)
+ printf("AliAnalysisTaskEMCALClusterize::RecPoints2Clusters() - Skipping cluster with no cells avobe threshold E = %f, ncells %d\n",
+ recPoint->GetEnergy(), ncells);
+ continue;
}
- if (ncells_true < 1) {
- Warning("AliAnalysisTaskEMCALClusterize::RecPoints2Clusters", "skipping cluster with no cells");
+ //if(ncellsTrue != ncells) printf("Old E %f, ncells %d; New E %f, ncells %d\n",recPoint->GetEnergy(),ncells,clusterE,ncellsTrue);
+
+ if(clusterE < fRecParam->GetClusteringThreshold()) {
+ if (DebugLevel()>1)
+ printf("AliAnalysisTaskEMCALClusterize::RecPoints2Clusters() - Remove cluster with energy below seed threshold %f\n",clusterE);
continue;
}
gpos.GetXYZ(g);
// create a new cluster
- AliAODCaloCluster *clus = new AliAODCaloCluster();
+ (*clusArray)[j] = new AliAODCaloCluster() ;
+ AliAODCaloCluster *clus = dynamic_cast<AliAODCaloCluster *>( clusArray->At(j) ) ;
+ j++;
clus->SetType(AliVCluster::kEMCALClusterv1);
- clus->SetE(recPoint->GetEnergy());
+ clus->SetE(clusterE);
clus->SetPosition(g);
- clus->SetNCells(ncells_true);
+ clus->SetNCells(ncellsTrue);
clus->SetCellsAbsId(absIds);
clus->SetCellsAmplitudeFraction(ratios);
- clus->SetDispersion(recPoint->GetDispersion());
clus->SetChi2(-1); //not yet implemented
clus->SetTOF(recPoint->GetTime()) ; //time-of-flight
clus->SetNExMax(recPoint->GetNExMax()); //number of local maxima
- Float_t elipAxis[2];
- recPoint->GetElipsAxis(elipAxis);
- clus->SetM02(elipAxis[0]*elipAxis[0]) ;
- clus->SetM20(elipAxis[1]*elipAxis[1]) ;
clus->SetDistanceToBadChannel(recPoint->GetDistanceToBadTower());
- clusArray->Add(clus);
+
+ if(ncells == ncellsTrue){
+ Float_t elipAxis[2];
+ recPoint->GetElipsAxis(elipAxis);
+ clus->SetM02(elipAxis[0]*elipAxis[0]) ;
+ clus->SetM20(elipAxis[1]*elipAxis[1]) ;
+ clus->SetDispersion(recPoint->GetDispersion());
+ }
+ else if(fSelectCell){
+ // In case some cells rejected, in unfolding case, recalculate
+ // shower shape parameters and position
+ AliVCaloCells* cells = 0x0;
+ if (aodIH && aodIH->GetMergeEvents()) cells = AODEvent() ->GetEMCALCells();
+ else cells = InputEvent()->GetEMCALCells();
+ fRecoUtils->RecalculateClusterShowerShapeParameters(fGeom,cells,clus);
+ fRecoUtils->RecalculateClusterPID(clus);
+ fRecoUtils->RecalculateClusterPosition(fGeom,cells,clus);
+
+ }
+
+ //MC
+ Int_t parentMult = 0;
+ Int_t *parentList = recPoint->GetParents(parentMult);
+ clus->SetLabel(parentList, parentMult);
+
+ //Write the second major contributor to each MC cluster.
+ Int_t iNewLabel ;
+ for ( Int_t iLoopCell = 0 ; iLoopCell < clus->GetNCells() ; iLoopCell++ ){
+
+ Int_t idCell = clus->GetCellAbsId(iLoopCell) ;
+ if(idCell>=0){
+ iNewLabel = 1 ; //iNewLabel makes sure we don't write twice the same label.
+ for ( UInt_t iLoopLabels = 0 ; iLoopLabels < clus->GetNLabels() ; iLoopLabels++ )
+ {
+ if ( fCellSecondLabels[idCell] == -1 ) iNewLabel = 0; // -1 is never a good second label.
+ if ( fCellSecondLabels[idCell] == clus->GetLabelAt(iLoopLabels) ) iNewLabel = 0;
+ }
+ if (iNewLabel == 1)
+ {
+ Int_t * newLabelArray = new Int_t[clus->GetNLabels()+1] ;
+ for ( UInt_t iLoopNewLabels = 0 ; iLoopNewLabels < clus->GetNLabels() ; iLoopNewLabels++ ){
+ newLabelArray[iLoopNewLabels] = clus->GetLabelAt(iLoopNewLabels) ;
+ }
+
+ newLabelArray[clus->GetNLabels()] = fCellSecondLabels[idCell] ;
+ clus->SetLabel(newLabelArray,clus->GetNLabels()+1) ;
+ delete [] newLabelArray;
+ }
+ }//positive cell number
+ }
+
} // recPoints loop
+
+}
+
+//____________________________________________________________
+void AliAnalysisTaskEMCALClusterize::UserCreateOutputObjects()
+{
+ // Init geometry, create list of output clusters
+
+ fGeom = AliEMCALGeometry::GetInstance(fGeomName) ;
+ if(fOutputAODBranchName.Length()!=0){
+ fOutputAODBranch = new TClonesArray("AliAODCaloCluster", 0);
+ fOutputAODBranch->SetName(fOutputAODBranchName);
+ AddAODBranch("TClonesArray", &fOutputAODBranch);
+ }
+ else {
+ AliFatal("fOutputAODBranchName not set\n");
+ }
}
+
+//_______________________________________________________
+void AliAnalysisTaskEMCALClusterize::UserExec(Option_t *)
+{
+ // Main loop
+ // Called for each event
+
+ //Remove the contents of output list set in the previous event
+ fOutputAODBranch->Clear("C");
+
+ LoadBranches();
+
+ //Get the event, do some checks and settings
+ CheckAndGetEvent() ;
+
+ if (!fEvent) {
+ if(DebugLevel() > 0 ) printf("AliAnalysisTaksEMCALClusterize::UserExec() - Skip Event %d", (Int_t) Entry());
+ return ;
+ }
+
+ //Init pointers, clusterizer, ocdb
+ if(fAccessOCDB) AccessOCDB();
+
+ InitClusterization();
+
+ InitGeometry(); // only once
+
+ // Make clusters
+ if (fJustUnfold) ClusterUnfolding();
+ else ClusterizeCells() ;
+
+ //Recalculate track-matching for the new clusters
+ if(fDoTrackMatching) fRecoUtils->FindMatches(fEvent,fCaloClusterArr,fGeom);
+
+ //Put the new clusters in the AOD list
+
+ Int_t kNumberOfCaloClusters = fCaloClusterArr->GetEntriesFast();
+ for(Int_t i = 0; i < kNumberOfCaloClusters; i++){
+ AliAODCaloCluster *newCluster = (AliAODCaloCluster *) fCaloClusterArr->At(i);
+ newCluster->SetID(i);
+ new((*fOutputAODBranch)[i]) AliAODCaloCluster(*newCluster);
+
+ //Add matched track
+ if(fDoTrackMatching){
+ Int_t trackIndex = fRecoUtils->GetMatchedTrackIndex(i);
+ if(trackIndex >= 0){
+ newCluster->AddTrackMatched(fEvent->GetTrack(trackIndex));
+ if(DebugLevel() > 1)
+ printf("AliAnalysisTaksEMCALClusterize::UserExec() - Matched Track index %d to new cluster %d \n",trackIndex,i);
+ }
+ }
+
+ //In case of new bad channels, recalculate distance to bad channels
+ if(fRecoUtils->IsBadChannelsRemovalSwitchedOn())
+ fRecoUtils->RecalculateClusterDistanceToBadChannel(fGeom, fEvent->GetEMCALCells(), newCluster);
+
+ if(DebugLevel() > 1 )
+ printf("AliAnalysisTaksEMCALClusterize::UserExec() - New cluster %d of %d, energy %f\n",newCluster->GetID(), kNumberOfCaloClusters, newCluster->E());
+
+ } // cluster loop
+
+ fOutputAODBranch->Expand(kNumberOfCaloClusters); // resize TObjArray to 'remove' slots
+
+ // Clean up
+ fCaloClusterArr->Delete(); // Do not Clear(), it leaks, why?
+}
+