1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
18 // EMCAL tender, apply corrections to EMCAL clusters and do track matching. //
20 // Author: Deepa Thomas (Utrecht University) //
21 // Later mods/rewrite: Jiri Kral (University of Jyvaskyla) //
22 // S. Aiola, C. Loizides : Make it work for AODs //
24 ///////////////////////////////////////////////////////////////////////////////
29 #include <TInterpreter.h>
30 #include <TObjArray.h>
31 #include <TClonesArray.h>
32 #include <TGeoGlobalMagField.h>
33 #include "AliEMCALAfterBurnerUF.h"
34 #include "AliEMCALClusterizer.h"
35 #include "AliEMCALClusterizerNxN.h"
36 #include "AliEMCALClusterizerv1.h"
37 #include "AliEMCALClusterizerv2.h"
38 #include "AliEMCALDigit.h"
39 #include "AliEMCALGeometry.h"
40 #include "AliEMCALRecParam.h"
41 #include "AliEMCALRecParam.h"
42 #include "AliEMCALRecPoint.h"
43 #include "AliEMCALRecoUtils.h"
44 #include "AliEMCALTenderSupply.h"
45 #include "AliESDCaloCluster.h"
47 #include "AliOADBContainer.h"
48 #include "AliAODEvent.h"
49 #include "AliAnalysisManager.h"
50 #include "AliESDEvent.h"
52 #include "AliTender.h"
53 #include "AliAODMCParticle.h"
55 ClassImp(AliEMCALTenderSupply)
57 AliEMCALTenderSupply::AliEMCALTenderSupply() :
67 ,fNonLinearThreshold(-1)
68 ,fReCalibCluster(kFALSE)
70 ,fCalibrateEnergy(kFALSE)
71 ,fCalibrateTime(kFALSE)
72 ,fCalibrateTimeParamAvailable(kFALSE)
73 ,fDoNonLinearity(kFALSE)
74 ,fBadCellRemove(kFALSE)
75 ,fRejectExoticCells(kFALSE)
76 ,fRejectExoticClusters(kFALSE)
77 ,fClusterBadChannelCheck(kFALSE)
78 ,fRecalClusPos(kFALSE)
80 ,fNCellsFromEMCALBorder(-1)
81 ,fRecalDistToBadChannels(kFALSE)
82 ,fRecalShowerShape(kFALSE)
85 ,fGetPassFromFileName(kTRUE)
90 ,fCutEtaPhiSeparate(kFALSE)
95 ,fReClusterize(kFALSE)
97 ,fGeomMatrixSet(kFALSE)
98 ,fLoadGeomMatrices(kFALSE)
100 ,fDoTrackMatch(kFALSE)
101 ,fDoUpdateOnly(kFALSE)
105 ,fMisalignSurvey(kdefault)
106 ,fExoticCellFraction(-1)
107 ,fExoticCellDiffTime(-1)
108 ,fExoticCellMinAmplitude(-1)
109 ,fSetCellMCLabelFromCluster(0)
111 ,fRemapMCLabelForAODs(0)
114 // Default constructor.
116 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
117 for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
120 //_____________________________________________________
121 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
122 AliTenderSupply(name,tender)
131 ,fNonLinearThreshold(-1)
132 ,fReCalibCluster(kFALSE)
134 ,fCalibrateEnergy(kFALSE)
135 ,fCalibrateTime(kFALSE)
136 ,fCalibrateTimeParamAvailable(kFALSE)
137 ,fDoNonLinearity(kFALSE)
138 ,fBadCellRemove(kFALSE)
139 ,fRejectExoticCells(kFALSE)
140 ,fRejectExoticClusters(kFALSE)
141 ,fClusterBadChannelCheck(kFALSE)
142 ,fRecalClusPos(kFALSE)
144 ,fNCellsFromEMCALBorder(-1)
145 ,fRecalDistToBadChannels(kFALSE)
146 ,fRecalShowerShape(kFALSE)
149 ,fGetPassFromFileName(kTRUE)
153 ,fCutEtaPhiSum(kTRUE)
154 ,fCutEtaPhiSeparate(kFALSE)
159 ,fReClusterize(kFALSE)
161 ,fGeomMatrixSet(kFALSE)
162 ,fLoadGeomMatrices(kFALSE)
164 ,fDoTrackMatch(kFALSE)
165 ,fDoUpdateOnly(kFALSE)
169 ,fMisalignSurvey(kdefault)
170 ,fExoticCellFraction(-1)
171 ,fExoticCellDiffTime(-1)
172 ,fExoticCellMinAmplitude(-1)
173 ,fSetCellMCLabelFromCluster(0)
175 ,fRemapMCLabelForAODs(0)
180 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
181 for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
184 //_____________________________________________________
185 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, AliAnalysisTaskSE *task) :
186 AliTenderSupply(name)
195 ,fNonLinearThreshold(-1)
196 ,fReCalibCluster(kFALSE)
198 ,fCalibrateEnergy(kFALSE)
199 ,fCalibrateTime(kFALSE)
200 ,fCalibrateTimeParamAvailable(kFALSE)
201 ,fDoNonLinearity(kFALSE)
202 ,fBadCellRemove(kFALSE)
203 ,fRejectExoticCells(kFALSE)
204 ,fRejectExoticClusters(kFALSE)
205 ,fClusterBadChannelCheck(kFALSE)
206 ,fRecalClusPos(kFALSE)
208 ,fNCellsFromEMCALBorder(-1)
209 ,fRecalDistToBadChannels(kFALSE)
210 ,fRecalShowerShape(kFALSE)
213 ,fGetPassFromFileName(kTRUE)
217 ,fCutEtaPhiSum(kTRUE)
218 ,fCutEtaPhiSeparate(kFALSE)
223 ,fReClusterize(kFALSE)
225 ,fGeomMatrixSet(kFALSE)
226 ,fLoadGeomMatrices(kFALSE)
228 ,fDoTrackMatch(kFALSE)
229 ,fDoUpdateOnly(kFALSE)
233 ,fMisalignSurvey(kdefault)
234 ,fExoticCellFraction(-1)
235 ,fExoticCellDiffTime(-1)
236 ,fExoticCellMinAmplitude(-1)
237 ,fSetCellMCLabelFromCluster(0)
239 ,fRemapMCLabelForAODs(0)
241 // Named constructor.
243 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
244 for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
247 //_____________________________________________________
248 AliEMCALTenderSupply::~AliEMCALTenderSupply()
252 if (!AliAnalysisManager::GetAnalysisManager()) return;
254 if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode())
256 delete fEMCALRecoUtils;
264 fDigitsArr->Clear("C");
276 //_____________________________________________________
277 void AliEMCALTenderSupply::SetDefaults()
279 // Set default settings.
281 SwitchOnBadCellRemove();
282 SwitchOnExoticCellRemove();
283 SwitchOnCalibrateEnergy();
284 SwitchOnCalibrateTime();
285 SwitchOnUpdateCell();
286 SwitchOnReclustering();
287 SwitchOnClusterBadChannelCheck();
288 SwitchOnClusterExoticChannelCheck();
289 SwitchOnTrackMatch();
292 //_____________________________________________________
293 Bool_t AliEMCALTenderSupply::RunChanged() const
297 return (fTender && fTender->RunChanged()) || (fTask && fRun != fTask->InputEvent()->GetRunNumber());
300 //_____________________________________________________
301 void AliEMCALTenderSupply::Init()
303 // Initialise EMCAL tender.
306 AliWarning("Init EMCAL Tender supply");
308 if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) {
309 AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
310 AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
311 fDebugLevel = tender->fDebugLevel;
312 fEMCALGeoName = tender->fEMCALGeoName;
313 fEMCALRecoUtils = tender->fEMCALRecoUtils;
314 fConfigName = tender->fConfigName;
315 fNonLinearFunc = tender->fNonLinearFunc;
316 fNonLinearThreshold = tender->fNonLinearThreshold;
317 fReCalibCluster = tender->fReCalibCluster;
318 fUpdateCell = tender->fUpdateCell;
319 fRecalClusPos = tender->fRecalClusPos;
320 fCalibrateEnergy = tender->fCalibrateEnergy;
321 fCalibrateTime = tender->fCalibrateTime;
322 fCalibrateTimeParamAvailable = tender->fCalibrateTimeParamAvailable;
323 fFiducial = tender->fFiducial;
324 fNCellsFromEMCALBorder = tender->fNCellsFromEMCALBorder;
325 fRecalDistToBadChannels = tender->fRecalDistToBadChannels;
326 fRecalShowerShape = tender->fRecalShowerShape;
327 fClusterBadChannelCheck = tender->fClusterBadChannelCheck;
328 fBadCellRemove = tender->fBadCellRemove;
329 fRejectExoticCells = tender->fRejectExoticCells;
330 fRejectExoticClusters = tender->fRejectExoticClusters;
331 fMass = tender->fMass;
332 fStep = tender->fStep;
333 fCutEtaPhiSum = tender->fCutEtaPhiSum;
334 fCutEtaPhiSeparate = tender->fCutEtaPhiSeparate;
335 fRcut = tender->fRcut;
336 fEtacut = tender->fEtacut;
337 fPhicut = tender->fPhicut;
338 fReClusterize = tender->fReClusterize;
339 fLoadGeomMatrices = tender->fLoadGeomMatrices;
340 fRecParam = tender->fRecParam;
341 fDoNonLinearity = tender->fDoNonLinearity;
342 fDoTrackMatch = tender->fDoTrackMatch;
343 fDoUpdateOnly = tender->fDoUpdateOnly;
344 fMisalignSurvey = tender->fMisalignSurvey;
345 fExoticCellFraction = tender->fExoticCellFraction;
346 fExoticCellDiffTime = tender->fExoticCellDiffTime;
347 fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude;
349 for(Int_t i = 0; i < 12; i++)
350 fEMCALMatrix[i] = tender->fEMCALMatrix[i] ;
354 AliInfo( "Emcal Tender settings: ======================================" );
355 AliInfo( "------------ Switches --------------------------" );
356 AliInfo( Form( "BadCellRemove : %d", fBadCellRemove ));
357 AliInfo( Form( "ExoticCellRemove : %d", fRejectExoticCells ));
358 AliInfo( Form( "CalibrateEnergy : %d", fCalibrateEnergy ));
359 AliInfo( Form( "CalibrateTime : %d", fCalibrateTime ));
360 AliInfo( Form( "UpdateCell : %d", fUpdateCell ));
361 AliInfo( Form( "DoUpdateOnly : %d", fDoUpdateOnly ));
362 AliInfo( Form( "Reclustering : %d", fReClusterize ));
363 AliInfo( Form( "ClusterBadChannelCheck : %d", fClusterBadChannelCheck ));
364 AliInfo( Form( "ClusterExoticChannelCheck : %d", fRejectExoticClusters ));
365 AliInfo( Form( "CellFiducialRegion : %d", fFiducial ));
366 AliInfo( Form( "ReCalibrateCluster : %d", fReCalibCluster ));
367 AliInfo( Form( "RecalculateClusPos : %d", fRecalClusPos ));
368 AliInfo( Form( "RecalShowerShape : %d", fRecalShowerShape ));
369 AliInfo( Form( "NonLinearityCorrection : %d", fDoNonLinearity ));
370 AliInfo( Form( "RecalDistBadChannel : %d", fRecalDistToBadChannels ));
371 AliInfo( Form( "TrackMatch : %d", fDoTrackMatch ));
372 AliInfo( "------------ Variables -------------------------" );
373 AliInfo( Form( "DebugLevel : %d", fDebugLevel ));
374 AliInfo( Form( "BasePath : %s", fBasePath.Data() ));
375 AliInfo( Form( "ConfigFileName : %s", fConfigName.Data() ));
376 AliInfo( Form( "EMCALGeometryName : %s", fEMCALGeoName.Data() ));
377 AliInfo( Form( "NonLinearityFunction : %d", fNonLinearFunc ));
378 AliInfo( Form( "NonLinearityThreshold : %d", fNonLinearThreshold ));
379 AliInfo( Form( "MisalignmentMatrixSurvey : %d", fMisalignSurvey ));
380 AliInfo( Form( "NumberOfCellsFromEMCALBorder : %d", fNCellsFromEMCALBorder ));
381 AliInfo( Form( "RCut : %f", fRcut ));
382 AliInfo( Form( "Mass : %f", fMass ));
383 AliInfo( Form( "Step : %f", fStep ));
384 AliInfo( Form( "EtaCut : %f", fEtacut ));
385 AliInfo( Form( "PhiCut : %f", fPhicut ));
386 AliInfo( Form( "ExoticCellFraction : %f", fExoticCellFraction ));
387 AliInfo( Form( "ExoticCellDiffTime : %f", fExoticCellDiffTime ));
388 AliInfo( Form( "ExoticCellMinAmplitude : %f", fExoticCellMinAmplitude ));
389 AliInfo( "=============================================================" );
395 fEMCALRecoUtils = new AliEMCALRecoUtils;
397 // init geometry if requested
398 if (fEMCALGeoName.Length()>0)
399 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
402 fDigitsArr = new TClonesArray("AliEMCALDigit",1000);
404 // initialising non-linearity parameters
405 if( fNonLinearThreshold != -1 )
406 fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
407 if( fNonLinearFunc != -1 )
408 fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
410 // missalignment function
411 fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
414 // do not do the eta0 fiducial cut
415 if( fNCellsFromEMCALBorder != -1 )
416 fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
417 fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
419 // exotic cell rejection
420 if( fExoticCellFraction != -1 )
421 fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
422 if( fExoticCellDiffTime != -1 )
423 fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
424 if( fExoticCellMinAmplitude != -1 )
425 fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
427 // setting track matching parameters ... mass, step size and residual cut
429 fEMCALRecoUtils->SetMass(fMass);
431 fEMCALRecoUtils->SetStep(fStep);
433 // spatial cut based on separate eta/phi or common processing
435 fEMCALRecoUtils->SwitchOnCutEtaPhiSum();
437 fEMCALRecoUtils->SetCutR(fRcut);
438 } else if (fCutEtaPhiSeparate) {
439 fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
441 fEMCALRecoUtils->SetCutEta(fEtacut);
443 fEMCALRecoUtils->SetCutPhi(fPhicut);
447 //_____________________________________________________
448 AliVEvent* AliEMCALTenderSupply::GetEvent()
450 // Return the event pointer.
453 return fTender->GetEvent();
456 return fTask->InputEvent();
462 //_____________________________________________________
463 void AliEMCALTenderSupply::ProcessEvent()
467 AliVEvent *event = GetEvent();
470 AliError("Event ptr = 0, returning");
474 // Initialising parameters once per run number
477 AliWarning( "Run changed, initializing parameters" );
478 fRun = event->GetRunNumber();
480 // init geometry if not already done
481 if (fEMCALGeoName.Length()==0) {
482 fEMCALGeoName = "EMCAL_FIRSTYEARV1";
484 fEMCALGeoName = "EMCAL_COMPLETEV1";
487 fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
489 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
491 AliFatal(Form("Can not create geometry: %s", fEMCALGeoName.Data()));
497 if (fGetPassFromFileName)
500 // define what recalib parameters are needed for various switches
501 // this is based on implementation in AliEMCALRecoUtils
502 Bool_t needRecoParam = fReClusterize;
503 Bool_t needBadChannels = fBadCellRemove | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
504 Bool_t needRecalib = fCalibrateEnergy | fReClusterize;
505 Bool_t needTimecalib = fCalibrateTime | fReClusterize;
506 Bool_t needMisalign = fRecalClusPos | fReClusterize;
507 Bool_t needClusterizer = fReClusterize;
510 if( needBadChannels ){
511 Int_t fInitBC = InitBadChannels();
513 AliError("InitBadChannels returned false, returning");
515 AliWarning("InitBadChannels OK");
517 AliWarning(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
520 // init recalibration factors
523 Int_t fInitRecalib = InitRecalib();
525 AliError("InitRecalib returned false, returning");
527 AliWarning("InitRecalib OK");
529 AliWarning(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
531 Int_t fInitRunDepRecalib = InitRunDepRecalib();
532 if (fInitRunDepRecalib==0)
533 AliError("InitrunDepRecalib returned false, returning");
534 if (fInitRunDepRecalib==1)
535 AliWarning("InitRecalib OK");
536 if (fInitRunDepRecalib>1)
537 AliWarning(Form("No Temperature recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
541 // init time calibration
542 if( needTimecalib ) {
543 Int_t initTC = InitTimeCalibration();
545 AliError("InitTimeCalibration returned false, returning");
547 fCalibrateTimeParamAvailable = kTRUE;
548 AliWarning("InitTimeCalib OK");
551 AliWarning(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
554 // init misalignment matrix
556 if (!InitMisalignMatrix())
557 AliError("InitMisalignmentMatrix returned false, returning");
559 AliWarning("InitMisalignMatrix OK");
562 // initiate reco params with some defaults
563 // will not overwrite, if those have been provided by user
564 if( needRecoParam ) {
565 Int_t initRC = InitRecParam();
568 AliInfo("Defaults reco params loaded.");
570 AliWarning("User defined reco params.");
574 if( needClusterizer ) {
575 if (!InitClusterization())
576 AliError("InitClusterization returned false, returning");
578 AliWarning("InitClusterization OK");
582 fEMCALRecoUtils->Print("");
585 // disable implied switches -------------------------------------------------
586 // AliEMCALRecoUtils or clusterizer functions alredy include some
587 // recalibration so based on those implied callibration te switches
588 // here are disabled to avoid duplication
590 // clusterizer does cluster energy recalibration, position recomputation
593 fReCalibCluster = kFALSE;
594 fRecalClusPos = kFALSE;
595 fRecalShowerShape = kFALSE;
598 // CONFIGURE THE RECO UTILS -------------------------------------------------
599 // configure the reco utils
600 // this option does energy recalibration
601 if( fCalibrateEnergy )
602 fEMCALRecoUtils->SwitchOnRecalibration();
604 fEMCALRecoUtils->SwitchOffRecalibration();
606 // allows time calibration
608 fEMCALRecoUtils->SwitchOnTimeRecalibration();
610 fEMCALRecoUtils->SwitchOffTimeRecalibration();
612 // allows to zero bad cells
614 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
616 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
618 // distance to bad channel recalibration
619 if( fRecalDistToBadChannels )
620 fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
622 fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
624 // exclude exotic cells
625 if( fRejectExoticCells )
626 fEMCALRecoUtils->SwitchOnRejectExoticCell();
628 fEMCALRecoUtils->SwitchOffRejectExoticCell();
630 // exclude clusters with exotic cells
631 if( fRejectExoticClusters )
632 fEMCALRecoUtils->SwitchOnRejectExoticCluster();
634 fEMCALRecoUtils->SwitchOffRejectExoticCluster();
636 // TODO: not implemented switches
637 // SwitchOnClusterEnergySmearing
638 // SwitchOnRunDepCorrection
640 // START PROCESSING ---------------------------------------------------------
641 // Test if cells present
642 AliVCaloCells *cells= event->GetEMCALCells();
643 if (cells->GetNumberOfCells()<=0)
646 AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
651 AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
653 // mark the cells not recalibrated in case of selected
654 // time, energy recalibration or bad channel removal
655 if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
656 fEMCALRecoUtils->ResetCellsCalibrated();
658 // CELL RECALIBRATION -------------------------------------------------------
659 // cell objects will be updated
660 // the cell calibrations are also processed locally any time those are needed
661 // in case that the cell objects are not to be updated here for later use
665 // includes exotic cell check in the UpdateCells function - is not provided
669 // switch off recalibrations so those are not done multiple times
670 // this is just for safety, the recalibrated flag of cell object
671 // should not allow for farther processing anyways
672 fEMCALRecoUtils->SwitchOffRecalibration();
673 fEMCALRecoUtils->SwitchOffTimeRecalibration();
679 // RECLUSTERIZATION ---------------------------------------------------------
687 // Store good clusters
688 TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
690 clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
692 AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
696 // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
697 // now go through clusters one by one and process separate correction
698 // as those were defined or not
699 Int_t nclusters = clusArr->GetEntriesFast();
700 for (Int_t icluster=0; icluster < nclusters; ++icluster)
702 AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
705 if (!clust->IsEMCAL())
708 // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
709 if( fClusterBadChannelCheck )
711 // careful, the the ClusterContainsBadChannel is dependent on
712 // SwitchOnBadChannelsRemoval, switching it ON automatically
713 // and returning to original value after processing
714 Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
715 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
717 Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
719 // switch the bad channels removal back
721 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
725 delete clusArr->RemoveAt(icluster);
726 continue; //TODO is it really needed to remove it? Or should we flag it?
730 // REMOVE EXOTIC CLUSTERS -------------------------------------
731 // does process local cell recalibration energy and time without replacing
732 // the global cell values, in case of no cell recalib done yet
733 if( fRejectExoticClusters )
735 // careful, the IsExoticCluster is dependent on
736 // SwitchOnRejectExoticCell, switching it ON automatically
737 // and returning to original value after processing
738 Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
739 fEMCALRecoUtils->SwitchOnRejectExoticCell();
741 // get bunch crossing
742 Int_t bunchCrossNo = event->GetBunchCrossNumber();
744 Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
746 // switch the exotic channels removal back
748 fEMCALRecoUtils->SwitchOffRejectExoticCell();
752 delete clusArr->RemoveAt(icluster);
753 continue; //TODO is it really needed to remove it? Or should we flag it?
757 // FIDUCIAL CUT -----------------------------------------------
760 // depends on SetNumberOfCellsFromEMCALBorder
761 // SwitchOnNoFiducialBorderInEMCALEta0
762 if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
763 delete clusArr->RemoveAt(icluster);
764 continue; //TODO it would be nice to store the distance
768 // CLUSTER ENERGY ---------------------------------------------
769 // does process local cell recalibration energy and time without replacing
770 // the global cell values, in case of no cell recalib done yet
771 if( fReCalibCluster ) {
772 fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
773 if (clust->E() < 1e-9) {
774 delete clusArr->RemoveAt(icluster);
779 // CLUSTER POSITION -------------------------------------------
780 // does process local cell energy recalibration, if enabled and cells
781 // not calibrated yet
783 fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
785 // SHOWER SHAPE -----------------------------------------------
786 if( fRecalShowerShape )
787 fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);
789 // NONLINEARITY -----------------------------------------------
790 if( fDoNonLinearity )
792 Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
793 clust->SetE(correctedEnergy);
796 // DISTANCE TO BAD CHANNELS -----------------------------------
797 if( fRecalDistToBadChannels )
798 fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);
806 // TRACK MATCHING -----------------------------------------------------------
807 if (!TGeoGlobalMagField::Instance()->GetField()) {
808 AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
810 esd->InitMagneticField();
812 AliAODEvent *aod = dynamic_cast<AliAODEvent*>(event);
813 Double_t curSol = 30000*aod->GetMagneticField()/5.00668;
814 Double_t curDip = 6000 *aod->GetMuonMagFieldScale();
815 AliMagF *field = AliMagF::CreateFieldMap(curSol,curDip);
816 TGeoGlobalMagField::Instance()->SetField(field);
820 fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
821 fEMCALRecoUtils->SetClusterMatchedToTrack(event);
822 fEMCALRecoUtils->SetTracksMatchedToCluster(event);
825 //_____________________________________________________
826 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
828 // Initialising misalignment matrices
830 AliVEvent *event = GetEvent();
837 AliInfo("Misalignment matrix already set");
842 AliInfo("Initialising misalignment matrix");
844 if (fLoadGeomMatrices) {
845 for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
847 if (fEMCALMatrix[mod]){
849 fEMCALMatrix[mod]->Print();
850 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
853 fGeomMatrixSet = kTRUE;
857 Int_t runGM = event->GetRunNumber();
860 if(fMisalignSurvey == kdefault)
861 { //take default alignment corresponding to run no
862 AliOADBContainer emcalgeoCont(Form("emcal"));
863 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
864 mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
867 if(fMisalignSurvey == kSurveybyS)
868 { //take alignment at sector level
869 if (runGM <= 140000) { //2010 data
870 AliOADBContainer emcalgeoCont(Form("emcal2010"));
871 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
872 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
874 else if (runGM>140000)
875 { // 2011 LHC11a pass1 data
876 AliOADBContainer emcalgeoCont(Form("emcal2011"));
877 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
878 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");
882 if(fMisalignSurvey == kSurveybyM)
883 { //take alignment at module level
884 if (runGM <= 140000) { //2010 data
885 AliOADBContainer emcalgeoCont(Form("emcal2010"));
886 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
887 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
889 else if (runGM>140000)
890 { // 2011 LHC11a pass1 data
891 AliOADBContainer emcalgeoCont(Form("emcal2011"));
892 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
893 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");
899 AliFatal("Geometry matrix array not found");
903 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
905 fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
906 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
907 fEMCALMatrix[mod]->Print();
913 //_____________________________________________________
914 Int_t AliEMCALTenderSupply::InitBadChannels()
916 // Initialising bad channel maps
918 AliVEvent *event = GetEvent();
924 AliInfo("Initialising Bad channel map");
926 // init default maps first
927 if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
928 fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
930 Int_t runBC = event->GetRunNumber();
932 AliOADBContainer *contBC = new AliOADBContainer("");
934 { //if fBasePath specified in the ->SetBasePath()
935 if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
937 TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
938 if (!fbad || fbad->IsZombie())
940 AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
944 if (fbad) delete fbad;
946 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");
949 { // Else choose the one in the $ALICE_ROOT directory
950 if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
952 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
953 if (!fbad || fbad->IsZombie())
955 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
959 if (fbad) delete fbad;
961 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels");
964 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
967 AliError(Form("No external hot channel set for run number: %d", runBC));
971 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
972 for (Int_t i=0; i<sms; ++i)
974 TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
977 h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
981 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
985 fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
990 //_____________________________________________________
991 Int_t AliEMCALTenderSupply::InitRecalib()
993 // Initialising recalibration factors.
995 AliVEvent *event = GetEvent();
1001 AliInfo("Initialising recalibration factors");
1003 // init default maps first
1004 if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
1005 fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
1007 Int_t runRC = event->GetRunNumber();
1009 AliOADBContainer *contRF=new AliOADBContainer("");
1011 { //if fBasePath specified in the ->SetBasePath()
1012 if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
1014 TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
1015 if (!fRecalib || fRecalib->IsZombie())
1017 AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
1021 if (fRecalib) delete fRecalib;
1023 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
1026 { // Else choose the one in the $ALICE_ROOT directory
1027 if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
1029 TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
1030 if (!fRecalib || fRecalib->IsZombie())
1032 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
1036 if (fRecalib) delete fRecalib;
1038 contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");
1041 TObjArray *recal=(TObjArray*)contRF->GetObject(runRC);
1044 AliError(Form("No Objects for run: %d",runRC));
1048 TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
1051 AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
1055 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
1058 AliError(Form("No Recalib histos found for %d - %s",runRC,fFilepass.Data()));
1062 if (fDebugLevel>0) recalib->Print();
1064 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
1065 for (Int_t i=0; i<sms; ++i)
1067 TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
1070 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
1073 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
1077 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
1082 //_____________________________________________________
1083 Int_t AliEMCALTenderSupply::InitRunDepRecalib()
1085 // Initialising recalibration factors.
1087 AliVEvent *event = GetEvent();
1093 AliInfo("Initialising recalibration factors");
1095 // init default maps first
1096 if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
1097 fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
1099 Int_t runRC = event->GetRunNumber();
1101 AliOADBContainer *contRF=new AliOADBContainer("");
1103 { //if fBasePath specified in the ->SetBasePath()
1104 if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
1106 TFile *fRunDepRecalib= new TFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"read");
1107 if (!fRunDepRecalib || fRunDepRecalib->IsZombie())
1109 AliFatal(Form("EMCALTemperatureCorrCalib.root not found in %s",fBasePath.Data()));
1113 if (fRunDepRecalib) delete fRunDepRecalib;
1115 contRF->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"AliEMCALRunDepTempCalibCorrections");
1118 { // Else choose the one in the $ALICE_ROOT directory
1119 if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
1121 TFile *fRunDepRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","read");
1122 if (!fRunDepRecalib || fRunDepRecalib->IsZombie())
1124 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root was not found");
1128 if (fRunDepRecalib) delete fRunDepRecalib;
1130 contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","AliEMCALRunDepTempCalibCorrections");
1133 TH1S *rundeprecal=(TH1S*)contRF->GetObject(runRC);
1136 AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runRC));
1137 // let's get the closest runnumber instead then..
1140 Int_t maxEntry = contRF->GetNumberOfEntries();
1142 while ( (ic < maxEntry) && (contRF->UpperLimit(ic) < runRC) ) {
1147 Int_t closest = lower;
1148 if ( (ic<maxEntry) &&
1149 (contRF->LowerLimit(ic)-runRC) < (runRC - contRF->UpperLimit(lower)) ) {
1153 AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRF->LowerLimit(closest)));
1154 rundeprecal = (TH1S*) contRF->GetObjectByIndex(closest);
1157 if (fDebugLevel>0) rundeprecal->Print();
1159 Int_t nSM = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
1161 for (Int_t ism=0; ism<nSM; ++ism)
1163 for (Int_t icol=0; icol<48; ++icol)
1165 for (Int_t irow=0; irow<24; ++irow)
1167 Float_t factor = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactor(ism,icol,irow);
1169 Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
1170 factor *= rundeprecal->GetBinContent(absID) / 10000. ; // correction dependent on T
1172 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
1181 //_____________________________________________________
1182 Int_t AliEMCALTenderSupply::InitTimeCalibration()
1184 // Initialising bad channel maps
1185 AliVEvent *event = GetEvent();
1191 AliInfo("Initialising time calibration map");
1193 // init default maps first
1194 if ( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
1195 fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
1197 Int_t runBC = event->GetRunNumber();
1199 AliOADBContainer *contBC = new AliOADBContainer("");
1201 { //if fBasePath specified in the ->SetBasePath()
1202 if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
1204 TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
1205 if (!fbad || fbad->IsZombie())
1207 AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
1211 if (fbad) delete fbad;
1213 contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
1216 { // Else choose the one in the $ALICE_ROOT directory
1217 if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
1219 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
1220 if (!fbad || fbad->IsZombie())
1222 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
1226 if (fbad) delete fbad;
1228 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
1231 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
1234 AliError(Form("No external time calibration set for run number: %d", runBC));
1238 // Here, it looks for a specific pass
1239 TString pass = fFilepass;
1240 if(fFilepass=="calo_spc") pass ="pass1";
1241 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
1244 AliError(Form("No external time calibration set for: %d -%s", runBC,pass.Data()));
1248 if (fDebugLevel>0) arrayBCpass->Print();
1250 for( Int_t i = 0; i < 4; i++ )
1252 TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
1256 h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
1260 AliError(Form("Can not get hAllTimeAvBC%d",i));
1264 fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
1269 //_____________________________________________________
1270 void AliEMCALTenderSupply::UpdateCells()
1272 //Remove bad cells from the cell list
1273 //Recalibrate energy and time cells
1274 //This is required for later reclusterization
1276 AliVEvent *event = GetEvent();
1280 AliVCaloCells *cells = event->GetEMCALCells();
1281 Int_t bunchCrossNo = event->GetBunchCrossNumber();
1283 fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo);
1285 // remove exotic cells - loop through cells and zero the exotic ones
1286 // just like with bad cell rejection in reco utils (inside RecalibrateCells)
1287 if( fRejectExoticCells )
1294 Bool_t isExot = kFALSE;
1296 // loop through cells
1297 Int_t nEMcell = cells->GetNumberOfCells() ;
1298 for (Int_t iCell = 0; iCell < nEMcell; iCell++)
1300 cells->GetCell( iCell, absId, ecell, tcell, mclabel, efrac );
1302 isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo );
1305 cells->SetCell( iCell, absId, 0.0, -1.0, mclabel, efrac );
1307 } // reject exotic cells
1312 //_____________________________________________________
1313 TString AliEMCALTenderSupply::GetBeamType()
1315 // Get beam type : pp-AA-pA
1316 // ESDs have it directly, AODs get it from hardcoded run number ranges
1318 AliVEvent *event = GetEvent();
1321 AliError("Couldn't retrieve event!");
1327 AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
1329 const AliESDRun *run = esd->GetESDRun();
1330 beamType = run->GetBeamType();
1334 Int_t runNumber = event->GetRunNumber();
1335 if ((runNumber >= 136851 && runNumber <= 139517) // LHC10h
1336 || (runNumber >= 166529 && runNumber <= 170593)) // LHC11h
1349 //_____________________________________________________
1350 Int_t AliEMCALTenderSupply::InitRecParam()
1352 // Init reco params if not yet exist (probably shipped by the user already)
1354 if( fRecParam != 0 )
1357 TString beamType = GetBeamType();
1359 // set some default reco params
1360 fRecParam = new AliEMCALRecParam();
1361 fRecParam->SetClusteringThreshold(0.100);
1362 fRecParam->SetMinECut(0.050);
1364 if(!fCalibrateTimeParamAvailable){
1365 fRecParam->SetTimeCut(250*1.e-9);
1366 fRecParam->SetTimeMin(425*1.e-9);
1367 fRecParam->SetTimeMax(825*1.e-9);
1370 fRecParam->SetTimeCut(100*1.e-9);
1371 fRecParam->SetTimeMin(-50*1.e-9);
1372 fRecParam->SetTimeMax( 50*1.e-9);
1375 if ( beamType == "A-A") {
1376 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1379 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1385 //_____________________________________________________
1386 Bool_t AliEMCALTenderSupply::InitClusterization()
1388 // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1390 AliVEvent *event = GetEvent();
1396 AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1398 //---setup clusterizer
1400 // avoid deleting fDigitsArr
1401 fClusterizer->SetDigitsArr(0);
1402 delete fClusterizer;
1405 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1406 fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1407 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
1408 fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1409 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN)
1411 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1412 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1413 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1414 fClusterizer = clusterizer;
1418 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1422 // Set the clustering parameters
1423 fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1424 fClusterizer->SetECALogWeight ( fRecParam->GetW0() );
1425 fClusterizer->SetMinECut ( fRecParam->GetMinECut() );
1426 fClusterizer->SetUnfolding ( fRecParam->GetUnfold() );
1427 fClusterizer->SetECALocalMaxCut ( fRecParam->GetLocMaxCut() );
1428 fClusterizer->SetTimeCut ( fRecParam->GetTimeCut() );
1429 fClusterizer->SetTimeMin ( fRecParam->GetTimeMin() );
1430 fClusterizer->SetTimeMax ( fRecParam->GetTimeMax() );
1431 fClusterizer->SetInputCalibrated ( kTRUE );
1432 fClusterizer->SetJustClusters ( kTRUE );
1434 // In case of unfolding after clusterization is requested, set the corresponding parameters
1435 if (fRecParam->GetUnfold())
1437 for (Int_t i = 0; i < 8; ++i)
1439 fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1441 for (Int_t i = 0; i < 3; ++i)
1443 fClusterizer->SetPar5 (i, fRecParam->GetPar5(i));
1444 fClusterizer->SetPar6 (i, fRecParam->GetPar6(i));
1446 fClusterizer->InitClusterUnfolding();
1449 fClusterizer->SetDigitsArr(fDigitsArr);
1450 fClusterizer->SetOutput(0);
1451 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1455 //_____________________________________________________
1456 void AliEMCALTenderSupply::FillDigitsArray()
1458 // Fill digits from cells to a TClonesArray.
1460 AliVEvent *event = GetEvent();
1465 // In case of MC productions done before aliroot tag v5-02-Rev09
1466 // assing the cluster label to all the cells belonging to this cluster
1468 Int_t cellLabels[12672];
1469 if(fSetCellMCLabelFromCluster)
1471 for (Int_t i = 0; i < 12672; i++)
1473 cellLabels [i] = 0 ;
1474 fOrgClusterCellId[i] =-1 ;
1477 Int_t nClusters = event->GetNumberOfCaloClusters();
1478 for (Int_t i = 0; i < nClusters; i++)
1480 AliVCluster *clus = event->GetCaloCluster(i);
1484 if(!clus->IsEMCAL()) continue ;
1486 Int_t label = clus->GetLabel();
1487 UShort_t * index = clus->GetCellsAbsId() ;
1489 for(Int_t icell=0; icell < clus->GetNCells(); icell++ )
1491 cellLabels [index[icell]] = label;
1492 fOrgClusterCellId[index[icell]] = i ; // index of the original cluster
1497 fDigitsArr->Clear("C");
1498 AliVCaloCells *cells = event->GetEMCALCells();
1499 Int_t ncells = cells->GetNumberOfCells();
1500 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell)
1502 Double_t cellAmplitude=0, cellTime=0, efrac = 0;
1503 Short_t cellNumber=0;
1506 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime, mcLabel, efrac) != kTRUE)
1509 // Do not add if energy already too low (some cells set to 0 if bad channels)
1510 if (cellAmplitude < fRecParam->GetMinECut())
1513 // If requested, do not include exotic cells
1514 if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber()))
1517 if ( fSetCellMCLabelFromCluster ) mcLabel = cellLabels[cellNumber];
1518 else if( fRemapMCLabelForAODs ) RemapMCLabelForAODs(mcLabel);
1520 if (mcLabel > 0 && efrac < 1e-6) efrac = 1;
1522 new((*fDigitsArr)[idigit]) AliEMCALDigit(mcLabel, mcLabel, cellNumber,
1523 (Float_t)cellAmplitude, (Float_t)cellTime,
1524 AliEMCALDigit::kHG,idigit, 0, 0, efrac*cellAmplitude);
1529 //_____________________________________________________
1530 void AliEMCALTenderSupply::Clusterize()
1534 fClusterizer->Digits2Clusters("");
1537 //_____________________________________________________
1538 void AliEMCALTenderSupply::UpdateClusters()
1540 // Update ESD cluster list.
1542 AliVEvent *event = GetEvent();
1547 TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1549 clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1552 AliError(" Null pointer to calo clusters array, returning");
1556 // Before destroying the orignal list, assign to the rec points the MC labels
1557 // of the original clusters, if requested
1558 if( fSetCellMCLabelFromCluster == 2 ) SetClustersMCLabelFromOriginalClusters() ;
1560 Int_t nents = clus->GetEntriesFast();
1561 for (Int_t i=0; i < nents; ++i)
1563 AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
1568 delete clus->RemoveAt(i);
1574 RecPoints2Clusters(clus);
1577 //_____________________________________________________
1578 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1580 // Convert AliEMCALRecoPoints to AliESDCaloClusters/AliAODCaloClusters.
1581 // Cluster energy, global position, cells and their amplitude fractions are restored.
1583 AliVEvent *event = GetEvent();
1588 Int_t ncls = fClusterArr->GetEntriesFast();
1589 for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i)
1591 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1593 Int_t ncellsTrue = 0;
1594 const Int_t ncells = recpoint->GetMultiplicity();
1595 UShort_t absIds[ncells];
1596 Double32_t ratios[ncells];
1597 Int_t *dlist = recpoint->GetDigitsList();
1598 Float_t *elist = recpoint->GetEnergiesList();
1599 for (Int_t c = 0; c < ncells; ++c)
1601 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1602 absIds[ncellsTrue] = digit->GetId();
1603 ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1604 if (ratios[ncellsTrue] < 0.001)
1611 AliWarning("Skipping cluster with no cells");
1615 // calculate new cluster position
1617 recpoint->GetGlobalPosition(gpos);
1621 AliVCluster *c = static_cast<AliVCluster*>(clus->New(nout++));
1623 c->SetType(AliVCluster::kEMCALClusterv1);
1624 c->SetE(recpoint->GetEnergy());
1626 c->SetNCells(ncellsTrue);
1627 c->SetDispersion(recpoint->GetDispersion());
1628 c->SetEmcCpvDistance(-1); //not yet implemented
1629 c->SetChi2(-1); //not yet implemented
1630 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
1631 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1632 Float_t elipAxis[2];
1633 recpoint->GetElipsAxis(elipAxis);
1634 c->SetM02(elipAxis[0]*elipAxis[0]) ;
1635 c->SetM20(elipAxis[1]*elipAxis[1]) ;
1636 c->SetCellsAbsId(absIds);
1637 c->SetCellsAmplitudeFraction(ratios);
1640 Int_t parentMult = 0;
1641 Int_t *parentList = recpoint->GetParents(parentMult);
1642 if (parentMult > 0) c->SetLabel(parentList, parentMult);
1647 //___________________________________________________________
1648 void AliEMCALTenderSupply::RemapMCLabelForAODs(Int_t & label)
1650 // MC label for Cells not remapped after ESD filtering, do it here.
1652 if(label < 0) return ;
1654 AliAODEvent * evt = dynamic_cast<AliAODEvent*> (GetEvent()) ;
1657 TClonesArray * arr = dynamic_cast<TClonesArray*>(evt->FindListObject("mcparticles")) ;
1660 if(label < arr->GetEntriesFast())
1662 AliAODMCParticle * particle = dynamic_cast<AliAODMCParticle *>(arr->At(label));
1663 if(!particle) return ;
1665 if(label == particle->Label()) return ; // label already OK
1668 // loop on the particles list and check if there is one with the same label
1669 for(Int_t ind = 0; ind < arr->GetEntriesFast(); ind++ )
1671 AliAODMCParticle * particle = dynamic_cast<AliAODMCParticle *>(arr->At(ind));
1672 if(!particle) continue ;
1674 if(label == particle->Label())
1685 //_____________________________________________________________________________________________
1686 void AliEMCALTenderSupply::SetClustersMCLabelFromOriginalClusters()
1688 // Get the original clusters that contribute to the new rec point cluster,
1689 // assign the labels of such clusters to the new rec point cluster.
1690 // Only approximatedly valid when output are V1 clusters, or input/output clusterizer
1691 // are the same handle with care
1692 // Copy from same method in AliAnalysisTaskEMCALClusterize, but here modify the recpoint and
1693 // not the output calocluster
1695 Int_t ncls = fClusterArr->GetEntriesFast();
1696 for(Int_t irp=0; irp < ncls; ++irp)
1698 TArrayI clArray(300) ; //Weird if more than a few clusters are in the origin ...
1701 Int_t nLabTotOrg = 0;
1705 AliEMCALRecPoint *clus = static_cast<AliEMCALRecPoint*>(fClusterArr->At(irp));
1707 //Find the clusters that originally had the cells
1708 const Int_t ncells = clus->GetMultiplicity();
1709 Int_t *digList = clus->GetDigitsList();
1711 for ( Int_t iLoopCell = 0 ; iLoopCell < ncells ; iLoopCell++ )
1713 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(digList[iLoopCell]));
1714 Int_t idCell = digit->GetId();
1718 Int_t idCluster = fOrgClusterCellId[idCell];
1720 for(Int_t icl =0; icl < nClu; icl++)
1722 if(((Int_t)clArray.GetAt(icl))==-1 ) continue;
1723 if( idCluster == ((Int_t)clArray.GetAt(icl)) ) set = kFALSE;
1725 if( set && idCluster >= 0)
1727 clArray.SetAt(idCluster,nClu++);
1728 nLabTotOrg+=(GetEvent()->GetCaloCluster(idCluster))->GetNLabels();
1730 //Search highest E cluster
1731 AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster);
1732 if(emax < clOrg->E())
1741 // Put the first in the list the cluster with highest energy
1742 if(idMax != ((Int_t)clArray.GetAt(0))) // Max not at first position
1744 Int_t maxIndex = -1;
1745 Int_t firstCluster = ((Int_t)clArray.GetAt(0));
1746 for ( Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++ )
1748 if(idMax == ((Int_t)clArray.GetAt(iLoopCluster))) maxIndex = iLoopCluster;
1751 if(firstCluster >=0 && idMax >=0)
1753 clArray.SetAt(idMax,0);
1754 clArray.SetAt(firstCluster,maxIndex);
1758 // Get the labels list in the original clusters, assign all to the new cluster
1759 TArrayI clMCArray(nLabTotOrg) ;
1763 for ( Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++ )
1765 Int_t idCluster = (Int_t) clArray.GetAt(iLoopCluster);
1766 AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster);
1767 Int_t nLab = clOrg->GetNLabels();
1769 for ( Int_t iLab = 0 ; iLab < nLab ; iLab++ )
1771 Int_t lab = clOrg->GetLabelAt(iLab) ;
1775 for(Int_t iLabTot =0; iLabTot < nLabTot; iLabTot++)
1777 if( lab == ((Int_t)clMCArray.GetAt(iLabTot)) ) set = kFALSE;
1779 if( set ) clMCArray.SetAt(lab,nLabTot++);
1784 // Set the final list of labels to rec point
1786 Int_t *labels = new Int_t[nLabTot];
1787 for(Int_t il = 0; il < nLabTot; il++) labels[il] = clMCArray.GetArray()[il];
1788 clus->SetParents(nLabTot,labels);
1790 } // rec point array
1794 //_____________________________________________________
1795 void AliEMCALTenderSupply::GetPass()
1797 // Get passx from filename
1799 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1800 fInputTree = mgr->GetTree();
1804 AliError("Pointer to tree = 0, returning");
1808 fInputFile = fInputTree->GetCurrentFile();
1810 AliError("Null pointer input file, returning");
1814 TString fname(fInputFile->GetName());
1815 if (fname.Contains("pass1")) fFilepass = TString("pass1");
1816 else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1817 else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1818 else if (fname.Contains("pass4")) fFilepass = TString("pass4");
1819 else if (fname.Contains("pass5")) fFilepass = TString("pass5");
1820 else if (fname.Contains("LHC11c") &&
1821 fname.Contains("spc_calo")) fFilepass = TString("spc_calo");
1822 else if (fname.Contains("calo") || fname.Contains("high_lumi"))
1825 //printf("AliEMCALTenderSupply::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1826 fFilepass = TString("pass1");
1830 AliError(Form("Pass number string not found: %s", fname.Data()));