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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // EMCAL tender, apply corrections to EMCAL clusters and do track matching. //
21 // Author: Deepa Thomas (Utrecht University) //
22 // Later mods/rewrite: Jiri Kral (University of Jyvaskyla) //
23 // S. Aiola, C. Loizides : Make it work for AODs //
25 ///////////////////////////////////////////////////////////////////////////////
30 #include <TInterpreter.h>
31 #include <TObjArray.h>
32 #include <TClonesArray.h>
33 #include <TGeoGlobalMagField.h>
34 #include "AliEMCALAfterBurnerUF.h"
35 #include "AliEMCALClusterizer.h"
36 #include "AliEMCALClusterizerNxN.h"
37 #include "AliEMCALClusterizerv1.h"
38 #include "AliEMCALClusterizerv2.h"
39 #include "AliEMCALDigit.h"
40 #include "AliEMCALGeometry.h"
41 #include "AliEMCALRecParam.h"
42 #include "AliEMCALRecParam.h"
43 #include "AliEMCALRecPoint.h"
44 #include "AliEMCALRecoUtils.h"
45 #include "AliEMCALTenderSupply.h"
46 #include "AliESDCaloCluster.h"
48 #include "AliOADBContainer.h"
49 #include "AliAODEvent.h"
50 #include "AliAnalysisManager.h"
51 #include "AliESDEvent.h"
53 #include "AliTender.h"
55 ClassImp(AliEMCALTenderSupply)
57 AliEMCALTenderSupply::AliEMCALTenderSupply() :
62 ,fEMCALGeoName("EMCAL_COMPLETEV1")
67 ,fNonLinearThreshold(-1)
68 ,fReCalibCluster(kFALSE)
70 ,fCalibrateEnergy(kFALSE)
71 ,fCalibrateTime(kFALSE)
72 ,fDoNonLinearity(kFALSE)
73 ,fBadCellRemove(kFALSE)
74 ,fRejectExoticCells(kFALSE)
75 ,fRejectExoticClusters(kFALSE)
76 ,fClusterBadChannelCheck(kFALSE)
77 ,fRecalClusPos(kFALSE)
79 ,fNCellsFromEMCALBorder(-1)
80 ,fRecalDistToBadChannels(kFALSE)
81 ,fRecalShowerShape(kFALSE)
88 ,fCutEtaPhiSeparate(kFALSE)
93 ,fReClusterize(kFALSE)
95 ,fGeomMatrixSet(kFALSE)
96 ,fLoadGeomMatrices(kFALSE)
98 ,fDoTrackMatch(kFALSE)
99 ,fDoUpdateOnly(kFALSE)
103 ,fMisalignSurvey(kdefault)
104 ,fExoticCellFraction(-1)
105 ,fExoticCellDiffTime(-1)
106 ,fExoticCellMinAmplitude(-1)
108 // Default constructor.
109 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
110 fEMCALRecoUtils = new AliEMCALRecoUtils;
113 //_____________________________________________________
114 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
115 AliTenderSupply(name,tender)
119 ,fEMCALGeoName("EMCAL_COMPLETEV1")
124 ,fNonLinearThreshold(-1)
125 ,fReCalibCluster(kFALSE)
127 ,fCalibrateEnergy(kFALSE)
128 ,fCalibrateTime(kFALSE)
129 ,fDoNonLinearity(kFALSE)
130 ,fBadCellRemove(kFALSE)
131 ,fRejectExoticCells(kFALSE)
132 ,fRejectExoticClusters(kFALSE)
133 ,fClusterBadChannelCheck(kFALSE)
134 ,fRecalClusPos(kFALSE)
136 ,fNCellsFromEMCALBorder(-1)
137 ,fRecalDistToBadChannels(kFALSE)
138 ,fRecalShowerShape(kFALSE)
144 ,fCutEtaPhiSum(kTRUE)
145 ,fCutEtaPhiSeparate(kFALSE)
150 ,fReClusterize(kFALSE)
152 ,fGeomMatrixSet(kFALSE)
153 ,fLoadGeomMatrices(kFALSE)
155 ,fDoTrackMatch(kFALSE)
156 ,fDoUpdateOnly(kFALSE)
160 ,fMisalignSurvey(kdefault)
161 ,fExoticCellFraction(-1)
162 ,fExoticCellDiffTime(-1)
163 ,fExoticCellMinAmplitude(-1)
167 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
168 fEMCALRecoUtils = new AliEMCALRecoUtils;
171 //_____________________________________________________
172 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, AliAnalysisTaskSE *task) :
173 AliTenderSupply(name)
177 ,fEMCALGeoName("EMCAL_COMPLETEV1")
182 ,fNonLinearThreshold(-1)
183 ,fReCalibCluster(kFALSE)
185 ,fCalibrateEnergy(kFALSE)
186 ,fCalibrateTime(kFALSE)
187 ,fDoNonLinearity(kFALSE)
188 ,fBadCellRemove(kFALSE)
189 ,fRejectExoticCells(kFALSE)
190 ,fRejectExoticClusters(kFALSE)
191 ,fClusterBadChannelCheck(kFALSE)
192 ,fRecalClusPos(kFALSE)
194 ,fNCellsFromEMCALBorder(-1)
195 ,fRecalDistToBadChannels(kFALSE)
196 ,fRecalShowerShape(kFALSE)
202 ,fCutEtaPhiSum(kTRUE)
203 ,fCutEtaPhiSeparate(kFALSE)
208 ,fReClusterize(kFALSE)
210 ,fGeomMatrixSet(kFALSE)
211 ,fLoadGeomMatrices(kFALSE)
213 ,fDoTrackMatch(kFALSE)
214 ,fDoUpdateOnly(kFALSE)
218 ,fMisalignSurvey(kdefault)
219 ,fExoticCellFraction(-1)
220 ,fExoticCellDiffTime(-1)
221 ,fExoticCellMinAmplitude(-1)
225 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
226 fEMCALRecoUtils = new AliEMCALRecoUtils;
229 //_____________________________________________________
230 AliEMCALTenderSupply::~AliEMCALTenderSupply()
234 delete fEMCALRecoUtils;
238 fDigitsArr->Clear("C");
246 //_____________________________________________________
247 Bool_t AliEMCALTenderSupply::RunChanged() const
250 return (fTender && fTender->RunChanged()) || (fTask && fRun != fTask->InputEvent()->GetRunNumber());
253 //_____________________________________________________
254 void AliEMCALTenderSupply::Init()
256 // Initialise EMCAL tender.
259 AliWarning("Init EMCAL Tender supply");
261 if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) {
262 AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
263 AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
264 fDebugLevel = tender->fDebugLevel;
265 fEMCALGeoName = tender->fEMCALGeoName;
266 fEMCALRecoUtils = tender->fEMCALRecoUtils;
267 fConfigName = tender->fConfigName;
268 fNonLinearFunc = tender->fNonLinearFunc;
269 fNonLinearThreshold = tender->fNonLinearThreshold;
270 fReCalibCluster = tender->fReCalibCluster;
271 fUpdateCell = tender->fUpdateCell;
272 fRecalClusPos = tender->fRecalClusPos;
273 fCalibrateEnergy = tender->fCalibrateEnergy;
274 fCalibrateTime = tender->fCalibrateTime;
275 fFiducial = tender->fFiducial;
276 fNCellsFromEMCALBorder = tender->fNCellsFromEMCALBorder;
277 fRecalDistToBadChannels = tender->fRecalDistToBadChannels;
278 fRecalShowerShape = tender->fRecalShowerShape;
279 fClusterBadChannelCheck = tender->fClusterBadChannelCheck;
280 fBadCellRemove = tender->fBadCellRemove;
281 fRejectExoticCells = tender->fRejectExoticCells;
282 fRejectExoticClusters = tender->fRejectExoticClusters;
283 fMass = tender->fMass;
284 fStep = tender->fStep;
285 fCutEtaPhiSum = tender->fCutEtaPhiSum;
286 fCutEtaPhiSeparate = tender->fCutEtaPhiSeparate;
287 fRcut = tender->fRcut;
288 fEtacut = tender->fEtacut;
289 fPhicut = tender->fPhicut;
290 fReClusterize = tender->fReClusterize;
291 fLoadGeomMatrices = tender->fLoadGeomMatrices;
292 fRecParam = tender->fRecParam;
293 fDoNonLinearity = tender->fDoNonLinearity;
294 fDoTrackMatch = tender->fDoTrackMatch;
295 fDoUpdateOnly = tender->fDoUpdateOnly;
296 fMisalignSurvey = tender->fMisalignSurvey;
297 fExoticCellFraction = tender->fExoticCellFraction;
298 fExoticCellDiffTime = tender->fExoticCellDiffTime;
299 fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude;
301 for(Int_t i = 0; i < 10; i++)
302 fEMCALMatrix[i] = tender->fEMCALMatrix[i] ;
306 AliInfo( "Emcal Tender settings: ======================================" );
307 AliInfo( "------------ Switches --------------------------" );
308 AliInfo( Form( "BadCellRemove : %d", fBadCellRemove ));
309 AliInfo( Form( "ExoticCellRemove : %d", fRejectExoticCells ));
310 AliInfo( Form( "CalibrateEnergy : %d", fCalibrateEnergy ));
311 AliInfo( Form( "CalibrateTime : %d", fCalibrateTime ));
312 AliInfo( Form( "UpdateCell : %d", fUpdateCell ));
313 AliInfo( Form( "DoUpdateOnly : %d", fDoUpdateOnly ));
314 AliInfo( Form( "Reclustering : %d", fReClusterize ));
315 AliInfo( Form( "ClusterBadChannelCheck : %d", fClusterBadChannelCheck ));
316 AliInfo( Form( "ClusterExoticChannelCheck : %d", fRejectExoticClusters ));
317 AliInfo( Form( "CellFiducialRegion : %d", fFiducial ));
318 AliInfo( Form( "ReCalibrateCluster : %d", fReCalibCluster ));
319 AliInfo( Form( "RecalculateClusPos : %d", fRecalClusPos ));
320 AliInfo( Form( "RecalShowerShape : %d", fRecalShowerShape ));
321 AliInfo( Form( "NonLinearityCorrection : %d", fDoNonLinearity ));
322 AliInfo( Form( "RecalDistBadChannel : %d", fRecalDistToBadChannels ));
323 AliInfo( Form( "TrackMatch : %d", fDoTrackMatch ));
324 AliInfo( "------------ Variables -------------------------" );
325 AliInfo( Form( "DebugLevel : %d", fDebugLevel ));
326 AliInfo( Form( "BasePath : %s", fBasePath.Data() ));
327 AliInfo( Form( "ConfigFileName : %s", fConfigName.Data() ));
328 AliInfo( Form( "EMCALGeometryName : %s", fEMCALGeoName.Data() ));
329 AliInfo( Form( "NonLinearityFunction : %d", fNonLinearFunc ));
330 AliInfo( Form( "NonLinearityThreshold : %d", fNonLinearThreshold ));
331 AliInfo( Form( "MisalignmentMatrixSurvey : %d", fMisalignSurvey ));
332 AliInfo( Form( "NumberOfCellsFromEMCALBorder : %d", fNCellsFromEMCALBorder ));
333 AliInfo( Form( "RCut : %f", fRcut ));
334 AliInfo( Form( "Mass : %f", fMass ));
335 AliInfo( Form( "Step : %f", fStep ));
336 AliInfo( Form( "EtaCut : %f", fEtacut ));
337 AliInfo( Form( "PhiCut : %f", fPhicut ));
338 AliInfo( Form( "ExoticCellFraction : %f", fExoticCellFraction ));
339 AliInfo( Form( "ExoticCellDiffTime : %f", fExoticCellDiffTime ));
340 AliInfo( Form( "ExoticCellMinAmplitude : %f", fExoticCellMinAmplitude ));
341 AliInfo( "=============================================================" );
345 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
348 fDigitsArr = new TClonesArray("AliEMCALDigit",1000);
350 // Initialising non-linearity parameters
351 if( fNonLinearThreshold != -1 )
352 fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
353 if( fNonLinearFunc != -1 )
354 fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
356 // missalignment function
357 fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
360 // do not do the eta0 fiducial cut
361 if( fNCellsFromEMCALBorder != -1 )
362 fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
363 fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
365 // exotic cell rejection
366 if( fExoticCellFraction != -1 )
367 fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
368 if( fExoticCellDiffTime != -1 )
369 fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
370 if( fExoticCellMinAmplitude != -1 )
371 fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
373 // Setting track matching parameters ... mass, step size and residual cut
375 fEMCALRecoUtils->SetMass(fMass);
377 fEMCALRecoUtils->SetStep(fStep);
379 // spatial cut based on separate eta/phi or common processing
381 fEMCALRecoUtils->SwitchOnCutEtaPhiSum();
383 fEMCALRecoUtils->SetCutR(fRcut);
384 } else if (fCutEtaPhiSeparate) {
385 fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
387 fEMCALRecoUtils->SetCutEta(fEtacut);
389 fEMCALRecoUtils->SetCutPhi(fPhicut);
393 //_____________________________________________________
394 AliVEvent* AliEMCALTenderSupply::GetEvent()
396 // return the event pointer
399 return fTender->GetEvent();
402 return fTask->InputEvent();
409 //_____________________________________________________
410 void AliEMCALTenderSupply::ProcessEvent()
414 AliVEvent *event = GetEvent();
417 AliError("Event ptr = 0, returning");
421 // Initialising parameters once per run number
424 fRun = event->GetRunNumber();
426 AliWarning( "Run changed, initializing parameters" );
431 // define what recalib parameters are needed for various switches
432 // this is based on implementation in AliEMCALRecoUtils
433 Bool_t needRecoParam = fReClusterize;
434 Bool_t needBadChannels = fBadCellRemove | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
435 Bool_t needRecalib = fCalibrateEnergy | fReClusterize;
436 Bool_t needTimecalib = fCalibrateTime | fReClusterize;
437 Bool_t needMisalign = fRecalClusPos | fReClusterize;
438 Bool_t needClusterizer = fReClusterize;
440 // initiate reco params with some defaults
441 // will not overwrite, if those have been provided by user
443 Int_t initRC = InitRecParam();
446 AliInfo("Defaults reco params loaded.");
448 AliWarning("User defined reco params.");
452 if( needBadChannels ){
453 Int_t fInitBC = InitBadChannels();
455 AliError("InitBadChannels returned false, returning");
457 AliWarning("InitBadChannels OK");
459 AliWarning(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
462 // init recalibration factors
464 Int_t fInitRecalib = InitRecalib();
466 AliError("InitRecalib returned false, returning");
468 AliWarning("InitRecalib OK");
470 AliWarning(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
471 fReCalibCluster = kFALSE;
474 // init time calibration
476 Int_t initTC = InitTimeCalibration();
478 AliError("InitTimeCalibration returned false, returning");
480 AliWarning("InitTimeCalib OK");
482 AliWarning(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
485 // init misalignment matrix
487 if (!InitMisalignMatrix())
488 AliError("InitMisalignmentMatrix returned false, returning");
490 AliWarning("InitMisalignMatrix OK");
494 if( needClusterizer ) {
495 if (!InitClusterization())
496 AliError("InitClusterization returned false, returning");
498 AliWarning("InitClusterization OK");
502 fEMCALRecoUtils->Print("");
505 // disable implied switches -------------------------------------------------
506 // AliEMCALRecoUtils or clusterizer functions alredy include some
507 // recalibration so based on those implied callibration te switches
508 // here are disabled to avoid duplication
510 // clusterizer does cluster energy recalibration, position recomputation
513 fReCalibCluster = kFALSE;
514 fRecalClusPos = kFALSE;
515 fRecalShowerShape = kFALSE;
518 // CONFIGURE THE RECO UTILS -------------------------------------------------
519 // configure the reco utils
520 // this option does energy recalibration
521 if( fCalibrateEnergy )
522 fEMCALRecoUtils->SwitchOnRecalibration();
524 fEMCALRecoUtils->SwitchOffRecalibration();
526 // allows time calibration
528 fEMCALRecoUtils->SwitchOnTimeRecalibration();
530 fEMCALRecoUtils->SwitchOffTimeRecalibration();
532 // allows to zero bad cells
534 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
536 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
538 // distance to bad channel recalibration
539 if( fRecalDistToBadChannels )
540 fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
542 fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
544 // exclude exotic cells
545 if( fRejectExoticCells )
546 fEMCALRecoUtils->SwitchOnRejectExoticCell();
548 fEMCALRecoUtils->SwitchOffRejectExoticCell();
550 // exclude clusters with exotic cells
551 if( fRejectExoticClusters )
552 fEMCALRecoUtils->SwitchOnRejectExoticCluster();
554 fEMCALRecoUtils->SwitchOffRejectExoticCluster();
556 // TODO: not implemented switches
557 // SwitchOnClusterEnergySmearing
558 // SwitchOnRunDepCorrection
560 // START PROCESSING ---------------------------------------------------------
561 // Test if cells present
562 AliVCaloCells *cells= event->GetEMCALCells();
563 if (cells->GetNumberOfCells()<=0)
566 AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
571 AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
573 // mark the cells not recalibrated in case of selected
574 // time, energy recalibration or bad channel removal
575 if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
576 fEMCALRecoUtils->ResetCellsCalibrated();
578 // CELL RECALIBRATION -------------------------------------------------------
579 // cell objects will be updated
580 // the cell calibrations are also processed locally any time those are needed
581 // in case that the cell objects are not to be updated here for later use
585 // includes exotic cell check in the UpdateCells function - is not provided
589 // switch off recalibrations so those are not done multiple times
590 // this is just for safety, the recalibrated flag of cell object
591 // should not allow for farther processing anyways
592 fEMCALRecoUtils->SwitchOffRecalibration();
593 fEMCALRecoUtils->SwitchOffTimeRecalibration();
599 // RECLUSTERIZATION ---------------------------------------------------------
607 // Store good clusters
608 TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
610 clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
612 AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
616 // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
617 // now go through clusters one by one and process separate correction
618 // as those were defined or not
619 Int_t nclusters = clusArr->GetEntriesFast();
620 for (Int_t icluster=0; icluster < nclusters; ++icluster)
622 AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
625 if (!clust->IsEMCAL())
628 // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
629 if( fClusterBadChannelCheck )
631 // careful, the the ClusterContainsBadChannel is dependent on
632 // SwitchOnBadChannelsRemoval, switching it ON automatically
633 // and returning to original value after processing
634 Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
635 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
637 Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
639 // switch the bad channels removal back
641 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
645 delete clusArr->RemoveAt(icluster);
646 continue; //TODO is it really needed to remove it? Or should we flag it?
650 // REMOVE EXOTIC CLUSTERS -------------------------------------
651 // does process local cell recalibration energy and time without replacing
652 // the global cell values, in case of no cell recalib done yet
653 if( fRejectExoticClusters )
655 // careful, the IsExoticCluster is dependent on
656 // SwitchOnRejectExoticCell, switching it ON automatically
657 // and returning to original value after processing
658 Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
659 fEMCALRecoUtils->SwitchOnRejectExoticCell();
661 // get bunch crossing
662 Int_t bunchCrossNo = event->GetBunchCrossNumber();
664 Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
666 // switch the exotic channels removal back
668 fEMCALRecoUtils->SwitchOffRejectExoticCell();
672 delete clusArr->RemoveAt(icluster);
673 continue; //TODO is it really needed to remove it? Or should we flag it?
677 // FIDUCIAL CUT -----------------------------------------------
680 // depends on SetNumberOfCellsFromEMCALBorder
681 // SwitchOnNoFiducialBorderInEMCALEta0
682 if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
683 delete clusArr->RemoveAt(icluster);
684 continue; //TODO it would be nice to store the distance
688 // CLUSTER ENERGY ---------------------------------------------
689 // does process local cell recalibration energy and time without replacing
690 // the global cell values, in case of no cell recalib done yet
691 if( fReCalibCluster )
692 fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
694 // CLUSTER POSITION -------------------------------------------
695 // does process local cell energy recalibration, if enabled and cells
696 // not calibratied yet
698 fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
700 // SHOWER SHAPE -----------------------------------------------
701 if( fRecalShowerShape )
702 fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);
704 // NONLINEARITY -----------------------------------------------
705 if( fDoNonLinearity )
707 Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
708 clust->SetE(correctedEnergy);
711 // DISTANCE TO BAD CHANNELS -----------------------------------
712 if( fRecalDistToBadChannels )
713 fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);
721 // TRACK MATCHING -----------------------------------------------------------
722 if (!TGeoGlobalMagField::Instance()->GetField()) {
723 AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
725 esd->InitMagneticField();
727 AliAODEvent *aod = dynamic_cast<AliAODEvent*>(event);
728 Double_t curSol = 30000*aod->GetMagneticField()/5.00668;
729 Double_t curDip = 6000 *aod->GetMuonMagFieldScale();
730 AliMagF *field = AliMagF::CreateFieldMap(curSol,curDip);
731 TGeoGlobalMagField::Instance()->SetField(field);
735 fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
736 fEMCALRecoUtils->SetClusterMatchedToTrack(event);
737 fEMCALRecoUtils->SetTracksMatchedToCluster(event);
740 //_____________________________________________________
741 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
743 // Initialising misalignment matrices
744 AliVEvent *event = GetEvent();
751 AliInfo("Misalignment matrix already set");
756 AliInfo("Initialising misalignment matrix");
758 if (fLoadGeomMatrices) {
759 for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
761 if (fEMCALMatrix[mod]){
763 fEMCALMatrix[mod]->Print();
764 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
767 fGeomMatrixSet = kTRUE;
771 Int_t runGM = event->GetRunNumber();
774 if(fMisalignSurvey == kdefault)
775 { //take default alignment corresponding to run no
776 AliOADBContainer emcalgeoCont(Form("emcal"));
777 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
778 mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
781 if(fMisalignSurvey == kSurveybyS)
782 { //take alignment at sector level
783 if (runGM <= 140000) { //2010 data
784 AliOADBContainer emcalgeoCont(Form("emcal2010"));
785 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
786 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
788 } else if (runGM>140000)
789 { // 2011 LHC11a pass1 data
790 AliOADBContainer emcalgeoCont(Form("emcal2011"));
791 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
792 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");
796 if(fMisalignSurvey == kSurveybyM)
797 { //take alignment at module level
798 if (runGM <= 140000) { //2010 data
799 AliOADBContainer emcalgeoCont(Form("emcal2010"));
800 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
801 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
803 } else if (runGM>140000)
804 { // 2011 LHC11a pass1 data
805 AliOADBContainer emcalgeoCont(Form("emcal2011"));
806 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
807 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");
813 AliFatal("Geometry matrix array not found");
817 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
819 fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
820 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
821 fEMCALMatrix[mod]->Print();
827 //_____________________________________________________
828 Int_t AliEMCALTenderSupply::InitBadChannels()
830 // Initialising bad channel maps
832 AliVEvent *event = GetEvent();
838 AliInfo("Initialising Bad channel map");
840 // init default maps first
841 if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
842 fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
844 Int_t runBC = event->GetRunNumber();
846 AliOADBContainer *contBC = new AliOADBContainer("");
848 { //if fBasePath specified in the ->SetBasePath()
849 if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
851 TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
852 if (!fbad || fbad->IsZombie())
854 AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
858 if (fbad) delete fbad;
860 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");
863 { // Else choose the one in the $ALICE_ROOT directory
864 if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
866 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
867 if (!fbad || fbad->IsZombie())
869 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
873 if (fbad) delete fbad;
875 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels");
878 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
881 AliError(Form("No external hot channel set for run number: %d", runBC));
885 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
886 for (Int_t i=0; i<sms; ++i)
888 TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
891 h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
895 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
899 fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
904 //_____________________________________________________
905 Int_t AliEMCALTenderSupply::InitRecalib()
907 // Initialising recalibration factors.
909 AliVEvent *event = GetEvent();
915 AliInfo("Initialising recalibration factors");
917 // init default maps first
918 if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
919 fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
921 Int_t runRC = event->GetRunNumber();
923 AliOADBContainer *contRF=new AliOADBContainer("");
925 { //if fBasePath specified in the ->SetBasePath()
926 if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
928 TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
929 if (!fRecalib || fRecalib->IsZombie())
931 AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
935 if (fRecalib) delete fRecalib;
937 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
940 { // Else choose the one in the $ALICE_ROOT directory
941 if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
943 TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
944 if (!fRecalib || fRecalib->IsZombie())
946 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
950 if (fRecalib) delete fRecalib;
952 contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");
955 TObjArray *recal=(TObjArray*)contRF->GetObject(runRC);
958 AliError(Form("No Objects for run: %d",runRC));
962 TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
965 AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
969 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
972 AliError(Form("No Recalib histos found for %d - %s",runRC,fFilepass.Data()));
976 if (fDebugLevel>0) recalib->Print();
978 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
979 for (Int_t i=0; i<sms; ++i)
981 TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
984 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
987 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
991 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
996 //_____________________________________________________
997 Int_t AliEMCALTenderSupply::InitTimeCalibration()
999 // Initialising bad channel maps
1000 AliVEvent *event = GetEvent();
1006 AliInfo("Initialising time calibration map");
1008 // init default maps first
1009 if( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
1010 fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
1012 Int_t runBC = event->GetRunNumber();
1014 AliOADBContainer *contBC = new AliOADBContainer("");
1016 { //if fBasePath specified in the ->SetBasePath()
1017 if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
1019 TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
1020 if (!fbad || fbad->IsZombie())
1022 AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
1026 if (fbad) delete fbad;
1028 contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
1031 { // Else choose the one in the $ALICE_ROOT directory
1032 if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
1034 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
1035 if (!fbad || fbad->IsZombie())
1037 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
1041 if (fbad) delete fbad;
1043 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
1046 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
1049 AliError(Form("No external time calibration set for run number: %d", runBC));
1053 // Here, it looks for a specific pass
1054 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass);
1057 AliError(Form("No external time calibration set for: %d -%s", runBC,fFilepass.Data()));
1061 if (fDebugLevel>0) arrayBCpass->Print();
1063 for( Int_t i = 0; i < 4; i++ )
1065 TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
1069 h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
1073 AliError(Form("Can not get hAllTimeAvBC%d",i));
1077 fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
1082 //_____________________________________________________
1083 void AliEMCALTenderSupply::UpdateCells()
1085 //Remove bad cells from the cell list
1086 //Recalibrate energy and time cells
1087 //This is required for later reclusterization
1089 AliVEvent *event = GetEvent();
1093 AliVCaloCells *cells = event->GetEMCALCells();
1094 Int_t bunchCrossNo = event->GetBunchCrossNumber();
1096 fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo);
1098 // remove exotic cells - loop through cells and zero the exotic ones
1099 // just like with bad cell rejection in reco utils (inside RecalibrateCells)
1100 if( fRejectExoticCells )
1103 Bool_t isExot = kFALSE;
1105 // loop through cells
1106 Int_t nEMcell = cells->GetNumberOfCells() ;
1107 for (Int_t iCell = 0; iCell < nEMcell; iCell++)
1109 absId = cells->GetCellNumber(iCell);
1111 isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo );
1114 cells->SetCell( iCell, absId, 0.0, 0.0 );
1116 } // reject exotic cells
1121 //_____________________________________________________
1122 TString AliEMCALTenderSupply::GetBeamType()
1125 // Get beam type : pp-AA-pA
1126 // ESDs have it directly, AODs we hardcode it
1128 AliVEvent *event = GetEvent();
1131 AliError("Couldn't retrieve event!");
1137 if (event->InheritsFrom("AliESDEvent")) {
1138 AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
1139 const AliESDRun *run = esd->GetESDRun();
1140 beamType = run->GetBeamType();
1142 else if (event->InheritsFrom("AliAODEvent")) {
1143 Int_t runNumber = event->GetRunNumber();
1144 if ((runNumber >= 136851 && runNumber <= 139517) // LHC10h
1145 || (runNumber >= 166529 && runNumber <= 170593)) // LHC11h
1158 //_____________________________________________________
1159 Int_t AliEMCALTenderSupply::InitRecParam()
1161 // exit if reco params exist (probably shipped by the user already)
1162 if( fRecParam != 0 )
1165 TString beamType = GetBeamType();
1167 // set some default reco params
1168 fRecParam = new AliEMCALRecParam();
1169 fRecParam->SetClusteringThreshold(0.100);
1170 fRecParam->SetMinECut(0.050);
1171 fRecParam->SetTimeCut(250);
1172 fRecParam->SetTimeMin(425);
1173 fRecParam->SetTimeMax(825);
1174 if ( beamType == "A-A") {
1175 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1178 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1184 //_____________________________________________________
1185 Bool_t AliEMCALTenderSupply::InitClusterization()
1187 // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1189 AliVEvent *event = GetEvent();
1195 AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1197 //---setup clusterizer
1198 delete fClusterizer;
1199 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1200 fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1201 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
1202 fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1203 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN)
1205 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1206 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1207 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1208 fClusterizer = clusterizer;
1212 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1216 // Set the clustering parameters
1217 fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1218 fClusterizer->SetECALogWeight ( fRecParam->GetW0() );
1219 fClusterizer->SetMinECut ( fRecParam->GetMinECut() );
1220 fClusterizer->SetUnfolding ( fRecParam->GetUnfold() );
1221 fClusterizer->SetECALocalMaxCut ( fRecParam->GetLocMaxCut() );
1222 fClusterizer->SetTimeCut ( fRecParam->GetTimeCut() );
1223 fClusterizer->SetTimeMin ( fRecParam->GetTimeMin() );
1224 fClusterizer->SetTimeMax ( fRecParam->GetTimeMax() );
1225 fClusterizer->SetInputCalibrated ( kTRUE );
1226 fClusterizer->SetJustClusters ( kTRUE );
1228 // In case of unfolding after clusterization is requested, set the corresponding parameters
1229 if (fRecParam->GetUnfold())
1231 for (Int_t i = 0; i < 8; ++i)
1233 fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1235 for (Int_t i = 0; i < 3; ++i)
1237 fClusterizer->SetPar5 (i, fRecParam->GetPar5(i));
1238 fClusterizer->SetPar6 (i, fRecParam->GetPar6(i));
1240 fClusterizer->InitClusterUnfolding();
1243 fClusterizer->SetDigitsArr(fDigitsArr);
1244 fClusterizer->SetOutput(0);
1245 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1249 //_____________________________________________________
1250 void AliEMCALTenderSupply::FillDigitsArray()
1252 // Fill digits from cells to a TClonesArray.
1254 AliVEvent *event = GetEvent();
1259 fDigitsArr->Clear("C");
1260 AliVCaloCells *cells = event->GetEMCALCells();
1261 Int_t ncells = cells->GetNumberOfCells();
1262 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell)
1264 Double_t cellAmplitude=0, cellTime=0, efrac = 0;
1265 Short_t cellNumber=0, mcLabel=-1;
1267 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime, mcLabel, efrac) != kTRUE)
1270 // Do not add if already too low (some cells set to 0 if bad channels)
1271 if (cellAmplitude < fRecParam->GetMinECut() )
1274 // If requested, do not include exotic cells
1275 if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber()))
1278 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
1279 digit->SetId(cellNumber);
1280 digit->SetTime(cellTime);
1281 digit->SetTimeR(cellTime);
1282 digit->SetIndexInList(idigit);
1283 digit->SetType(AliEMCALDigit::kHG);
1284 digit->SetAmplitude(cellAmplitude);
1289 //_____________________________________________________
1290 void AliEMCALTenderSupply::Clusterize()
1294 fClusterizer->Digits2Clusters("");
1297 //_____________________________________________________
1298 void AliEMCALTenderSupply::UpdateClusters()
1300 // Update ESD cluster list.
1302 AliVEvent *event = GetEvent();
1307 TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1309 clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1312 AliError(" Null pointer to calo clusters array, returning");
1316 Int_t nents = clus->GetEntriesFast();
1317 for (Int_t i=0; i < nents; ++i)
1319 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->At(i));
1323 delete clus->RemoveAt(i);
1328 RecPoints2Clusters(clus);
1332 //_____________________________________________________
1333 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1335 // Convert AliEMCALRecoPoints to AliESDCaloClusters.
1336 // Cluster energy, global position, cells and their amplitude fractions are restored.
1338 AliVEvent *event = GetEvent();
1343 Int_t ncls = fClusterArr->GetEntriesFast();
1344 for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i)
1346 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1348 Int_t ncellsTrue = 0;
1349 const Int_t ncells = recpoint->GetMultiplicity();
1350 UShort_t absIds[ncells];
1351 Double32_t ratios[ncells];
1352 Int_t *dlist = recpoint->GetDigitsList();
1353 Float_t *elist = recpoint->GetEnergiesList();
1354 for (Int_t c = 0; c < ncells; ++c)
1356 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1357 absIds[ncellsTrue] = digit->GetId();
1358 ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1359 if (ratios[ncellsTrue] < 0.001)
1366 AliWarning("Skipping cluster with no cells");
1370 // calculate new cluster position
1372 recpoint->GetGlobalPosition(gpos);
1376 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->New(nout++));
1378 c->SetType(AliVCluster::kEMCALClusterv1);
1379 c->SetE(recpoint->GetEnergy());
1381 c->SetNCells(ncellsTrue);
1382 c->SetDispersion(recpoint->GetDispersion());
1383 c->SetEmcCpvDistance(-1); //not yet implemented
1384 c->SetChi2(-1); //not yet implemented
1385 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
1386 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1387 Float_t elipAxis[2];
1388 recpoint->GetElipsAxis(elipAxis);
1389 c->SetM02(elipAxis[0]*elipAxis[0]) ;
1390 c->SetM20(elipAxis[1]*elipAxis[1]) ;
1391 AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
1392 cesd->SetCellsAbsId(absIds);
1393 cesd->SetCellsAmplitudeFraction(ratios);
1397 //_____________________________________________________
1398 void AliEMCALTenderSupply::GetPass()
1400 // Get passx from filename.
1402 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1403 fInputTree = mgr->GetTree();
1407 AliError("Pointer to tree = 0, returning");
1411 fInputFile = fInputTree->GetCurrentFile();
1413 AliError("Null pointer input file, returning");
1417 TString fname(fInputFile->GetName());
1418 if (fname.Contains("pass1")) fFilepass = TString("pass1");
1419 else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1420 else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1423 AliError(Form("Pass number string not found: %s", fname.Data()));