18 #include <TClonesArray.h>
22 #include <THnSparse.h>
23 #include <THashList.h>
28 #include "AliCentrality.h"
29 #include "AliVCluster.h"
30 #include "AliVParticle.h"
31 #include "AliVTrack.h"
33 #include "AliEMCALGeometry.h"
34 #include "AliEMCALGeoParams.h"
36 #include "AliVVZERO.h"
37 #include "AliESDUtils.h"
47 fParticleLevel(kFALSE),
53 fDoLeadingObjectPosition(0),
54 fMaxCellsInCluster(50),
57 fSeparateEMCalDCal(kTRUE),
66 fHistManager("AliAnalysisTaskEmcalJetQA")
70 memset(fNTotClusters, 0,
sizeof(Int_t)*2);
72 SetMakeGeneralHistograms(kTRUE);
79 fParticleLevel(kFALSE),
85 fDoLeadingObjectPosition(0),
86 fMaxCellsInCluster(50),
89 fSeparateEMCalDCal(kTRUE),
120 AliEmcalContainer* cont = 0;
128 while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) {
132 histname = TString::Format(
"%s/fHistTrNegativeLabels_%d", cont->GetArrayName().Data(), i);
133 title = histname +
";% of negative labels;counts";
136 histname = TString::Format(
"%s/fHistTrZeroLabels_%d", cont->GetArrayName().Data(), i);
137 title = histname +
";% of zero labels;counts";
146 histname = TString::Format(
"%s/fHistRejectionReason_%d", cont->GetArrayName().Data(), i);
147 title = histname +
";Rejection reason;#it{p}_{T,track} (GeV/#it{c});counts";
151 for (Int_t j = 0; j < nlabels; j++) {
152 histname = TString::Format(
"%s/fHistTrPhiEtaPt_%d_%d", cont->GetArrayName().Data(), i, j);
153 title = histname +
";#eta;#phi;#it{p}_{T} (GeV/#it{c})";
154 fHistManager.
CreateTH3(histname.Data(), title.Data(), 100, -1, 1, 100, 0, TMath::TwoPi(),
nPtBins, 0,
fMaxPt);
159 histname = TString::Format(
"%s/fHistTrPhiEtaZeroLab_%d", cont->GetArrayName().Data(), i);
160 title = histname +
";#eta;#phi;counts";
163 histname = TString::Format(
"%s/fHistTrPtZeroLab_%d", cont->GetArrayName().Data(), i);
164 title = histname +
";#it{p}_{T} (GeV/#it{c});counts";
168 histname = TString::Format(
"%s/fHistTrEmcPhiEta_%d", cont->GetArrayName().Data(), i);
169 title = histname +
";#eta;#phi;counts";
172 histname = TString::Format(
"%s/fHistTrEmcPt_%d", cont->GetArrayName().Data(), i);
173 title = histname +
";#it{p}_{T} (GeV/#it{c});counts";
176 histname = TString::Format(
"%s/fHistTrPhiEtaNonProp_%d", cont->GetArrayName().Data(), i);
177 title = histname +
";#eta;#phi;counts";
180 histname = TString::Format(
"%s/fHistTrPtNonProp_%d", cont->GetArrayName().Data(), i);
181 title = histname +
";#it{p}_{T} (GeV/#it{c});counts";
184 histname = TString::Format(
"%s/fHistDeltaEtaPt_%d", cont->GetArrayName().Data(), i);
185 title = histname +
";#it{p}_{T} (GeV/#it{c});#delta#eta;counts";
188 histname = TString::Format(
"%s/fHistDeltaPhiPt_%d", cont->GetArrayName().Data(), i);
189 title = histname +
";#it{p}_{T} (GeV/#it{c});#delta#phi;counts";
192 histname = TString::Format(
"%s/fHistDeltaPtvsPt_%d", cont->GetArrayName().Data(), i);
193 title = histname +
";#it{p}_{T} (GeV/#it{c});#delta#it{p}_{T} (GeV/#it{c});counts";
200 while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) {
205 const Int_t nSM = 20;
207 for (Int_t sm = 0; sm < nSM; sm++) {
208 histname = TString::Format(
"%s/BySM/fHistClusEnergy_SM%d_%d", cont->GetArrayName().Data(), sm, i);
209 title = histname +
";#it{E}_{cluster} (GeV);counts";
213 histname = TString::Format(
"%s/fHistRejectionReason_%d", cont->GetArrayName().Data(), i);
214 title = histname +
";Rejection reason;#it{E}_{cluster} (GeV);counts";
218 histname = TString::Format(
"%s/fHistClusPosition_%d", cont->GetArrayName().Data(), i);
219 title = histname +
";#it{x} (cm);#it{y} (cm);#it{z} (cm)";
220 fHistManager.
CreateTH3(histname.Data(), title.Data(), 50, -500, 500, 50, -500, 500, 50, -500, 500);
222 histname = TString::Format(
"%s/fHistClusPhiEtaEnergy_%d", cont->GetArrayName().Data(), i);
223 title = histname +
";#eta;#phi;#it{E}_{cluster} (GeV)";
224 fHistManager.
CreateTH3(histname.Data(), title.Data(), 50, -1, 1, 50, 0, TMath::TwoPi(),
nPtBins, 0,
fMaxPt);
227 histname = TString::Format(
"%s/fHistClusDeltaPhiEPEnergy_%d", cont->GetArrayName().Data(), i);
228 title = histname +
";#it{E}_{cluster} (GeV);#phi_{cluster} - #psi_{EP};counts";
233 histname = TString::Format(
"%s/fHistClusMCEnergyFraction_%d", cont->GetArrayName().Data(), i);
234 title = histname +
";MC fraction;counts";
238 histname = TString::Format(
"%s/fHistClusTimeEnergy_%d", cont->GetArrayName().Data(), i);
239 title = histname +
";#it{E}_{cluster} (GeV);time (s);counts";
243 while (nbins > nPtBins) nbins /= 2;
244 histname = TString::Format(
"%s/fHistNCellsEnergy_%d", cont->GetArrayName().Data(), i);
245 title = histname +
";#it{E}_{cluster} (GeV);#it{N}_{cells};counts";
248 histname = TString::Format(
"%s/fHistFcrossEnergy_%d", cont->GetArrayName().Data(), i);
249 title = histname +
";#it{E}_{cluster} (GeV);#it{F}_{cross};counts";
252 histname = TString::Format(
"%s/fHistClusEnergy_%d", cont->GetArrayName().Data(), i);
253 title = histname +
";#it{E}_{cluster} (GeV);counts";
256 histname = TString::Format(
"%s/fHistClusNonLinCorrEnergy_%d", cont->GetArrayName().Data(), i);
257 title = histname +
";#it{E}_{cluster} (GeV);counts";
260 histname = TString::Format(
"%s/fHistClusHadCorrEnergy_%d", cont->GetArrayName().Data(), i);
261 title = histname +
";#it{E}_{cluster} (GeV);counts";
269 histname = TString::Format(
"%s/fHistCellsAbsIdEnergy_%d",
fCaloCellsName.Data(), i);
270 title = histname +
";cell abs. Id;#it{E}_{cell} (GeV);counts";
276 TString axistitle[40];
277 Int_t
nbins[40] = {0};
278 Double_t min[40] = {0};
279 Double_t max[40] = {0};
282 axistitle[dim] =
"Centrality %";
289 axistitle[dim] = Form(
"Centrality %s %%",
fCentMethod2.Data());
297 axistitle[dim] = Form(
"Centrality %s %%",
fCentMethod3.Data());
305 axistitle[dim] =
"V0A total multiplicity";
311 axistitle[dim] =
"V0C total multiplicity";
318 axistitle[dim] =
"V0A+V0C total multiplicity";
326 axistitle[dim] =
"#psi_{EP}";
328 min[dim] = -TMath::Pi();
329 max[dim] = TMath::Pi();
335 axistitle[dim] =
"No. of tracks";
348 axistitle[dim] =
"#it{p}_{T,track}^{leading} (GeV/c)";
355 axistitle[dim] =
"#eta_{track}^{leading}";
361 axistitle[dim] =
"#phi_{track}^{leading}";
364 max[dim] = TMath::TwoPi();
370 axistitle[dim] =
"No. of clusters";
385 axistitle[dim] =
"#it{E}_{EMCal cluster}^{leading} (GeV)";
391 axistitle[dim] =
"#it{E}_{DCal cluster}^{leading} (GeV)";
398 axistitle[dim] =
"#eta_{EMCal cluster}^{leading}";
404 axistitle[dim] =
"#phi_{EMCal cluster}^{leading}";
407 max[dim] = TMath::TwoPi();
410 axistitle[dim] =
"#eta_{DCal cluster}^{leading}";
416 axistitle[dim] =
"#phi_{DCal cluster}^{leading}";
419 max[dim] = TMath::TwoPi();
424 axistitle[dim] =
"#it{E}_{cluster}^{leading} (GeV)";
431 axistitle[dim] =
"#eta_{cluster}^{leading}";
437 axistitle[dim] =
"#phi_{cluster}^{leading}";
440 max[dim] = TMath::TwoPi();
447 axistitle[dim] =
"No. of cells";
452 max[dim] = 10000-0.5;
464 for (Int_t i = 0; i < dim; i++)
465 hn->GetAxis(i)->SetTitle(axistitle[i]);
485 fVZERO = InputEvent()->GetVZEROData();
487 AliError(
"AliVVZERO not available");
501 AliCentrality *aliCent = InputEvent()->GetCentrality();
527 AliDebug(2,Form(
"%d tracks found in the event",
fNTotTracks));
532 for (Int_t i = 0; i < 2; i++) {
538 AliDebug(2,Form(
"%d cells found in the event", eventQA.
fNCells));
559 Double_t contents[40]={0};
568 for (Int_t i = 0; i < histEventQA->GetNdimensions(); i++) {
569 TString
title(histEventQA->GetAxis(i)->GetTitle());
570 if (
title==
"Centrality %")
571 contents[i] = eventQA.
fCent;
573 contents[i] = eventQA.
fCent2;
575 contents[i] = eventQA.
fCent3;
576 else if (
title==
"V0A total multiplicity")
577 contents[i] = eventQA.
fV0A;
578 else if (
title==
"V0C total multiplicity")
579 contents[i] = eventQA.
fV0C;
580 else if (
title==
"V0A+V0C total multiplicity")
581 contents[i] = eventQA.
fV0A+eventQA.
fV0C;
582 else if (
title==
"#psi_{RP}")
583 contents[i] = eventQA.
fEP;
584 else if (
title==
"No. of tracks")
586 else if (
title==
"No. of clusters")
587 contents[i] = globalNclusters;
588 else if (
title==
"No. of cells")
590 else if (
title==
"#it{p}_{T,track}^{leading} (GeV/c)")
592 else if (
title==
"#eta_{track}^{leading}")
594 else if (
title==
"#phi_{track}^{leading}")
596 else if (
title==
"#it{E}_{cluster}^{leading} (GeV)")
597 contents[i] = globalMaxCluster.E();
598 else if (
title==
"#eta_{cluster}^{leading}")
599 contents[i] = globalMaxCluster.Eta();
600 else if (
title==
"#phi_{cluster}^{leading}")
601 contents[i] = globalMaxCluster.Phi();
602 else if (
title==
"#it{E}_{EMCal cluster}^{leading} (GeV)")
604 else if (
title==
"#eta_{EMCal cluster}^{leading}")
606 else if (
title==
"#phi_{EMCal cluster}^{leading}")
608 else if (
title==
"#it{E}_{DCal cluster}^{leading} (GeV)")
610 else if (
title==
"#phi_{DCal cluster}^{leading}")
612 else if (
title==
"#eta_{DCal cluster}^{leading}")
615 AliWarning(Form(
"Unable to fill dimension %s!",
title.Data()));
618 histEventQA->Fill(contents);
630 const Int_t ncells =
fCaloCells->GetNumberOfCells();
633 for (Int_t pos = 0; pos < ncells; pos++) {
649 Int_t AbsIdseed = -1;
651 for (Int_t i = 0; i < cluster->GetNCells(); i++) {
652 if (cells->GetCellAmplitude(cluster->GetCellAbsId(i)) > Eseed) {
653 Eseed = cells->GetCellAmplitude(cluster->GetCellAbsId(i));
654 AbsIdseed = cluster->GetCellAbsId(i);
661 Int_t imod = -1, iphi =-1, ieta=-1,iTower = -1, iIphi = -1, iIeta = -1;
662 fGeom->GetCellIndex(AbsIdseed,imod,iTower,iIphi,iIeta);
663 fGeom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi,iIeta,iphi,ieta);
670 if (iphi < AliEMCALGeoParams::fgkEMCALRows-1) absID1 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi+1, ieta);
671 if (iphi > 0) absID2 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi-1, ieta);
678 if (ieta == AliEMCALGeoParams::fgkEMCALCols-1 && !(imod%2)) {
679 absID3 =
fGeom->GetAbsCellIdFromCellIndexes(imod+1, iphi, 0);
680 absID4 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi, ieta-1);
682 else if (ieta == 0 && imod%2) {
683 absID3 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi, ieta+1);
684 absID4 =
fGeom->GetAbsCellIdFromCellIndexes(imod-1, iphi, AliEMCALGeoParams::fgkEMCALCols-1);
687 if (ieta < AliEMCALGeoParams::fgkEMCALCols-1)
688 absID3 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi, ieta+1);
690 absID4 =
fGeom->GetAbsCellIdFromCellIndexes(imod, iphi, ieta-1);
693 Double_t ecell1 = cells->GetCellAmplitude(absID1);
694 Double_t ecell2 = cells->GetCellAmplitude(absID2);
695 Double_t ecell3 = cells->GetCellAmplitude(absID3);
696 Double_t ecell4 = cells->GetCellAmplitude(absID4);
698 Double_t Ecross = ecell1 + ecell2 + ecell3 + ecell4;
700 Double_t Fcross = 1 - Ecross/Eseed;
717 while ((clusters = static_cast<AliClusterContainer*>(nextClusColl()))) {
722 UInt_t rejectionReason = 0;
723 if (!clusters->
AcceptCluster(it.current_index(), rejectionReason)) {
724 histname = TString::Format(
"%s/fHistRejectionReason_%d", clusters->GetArrayName().Data(),
fCentBin);
725 fHistManager.
FillTH2(histname, clusters->GetRejectionReasonBitPosition(rejectionReason), it->first.E());
730 it->second->GetPosition(pos);
731 histname = TString::Format(
"%s/fHistClusPosition_%d", clusters->GetArrayName().Data(),
fCentBin);
734 Double_t phi = it->first.Phi_0_2pi();
738 histname = TString::Format(
"%s/fHistClusPhiEtaEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
743 histname = TString::Format(
"%s/fHistClusDeltaPhiEPEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
746 while (ep < 0) ep += TMath::Pi();
747 while (ep >= TMath::Pi()) ep -= TMath::Pi();
751 histname = TString::Format(
"%s/fHistNCellsEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
754 histname = TString::Format(
"%s/fHistClusTimeEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
758 histname = TString::Format(
"%s/fHistFcrossEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
762 histname = TString::Format(
"%s/fHistClusMCEnergyFraction_%d", clusters->GetArrayName().Data(),
fCentBin);
767 histname = TString::Format(
"%s/fHistClusEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
770 if (it->second->GetNonLinCorrEnergy() > 0.) {
771 histname = TString::Format(
"%s/fHistClusNonLinCorrEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
775 if (it->second->GetHadCorrEnergy() > 0.) {
776 histname = TString::Format(
"%s/fHistClusHadCorrEnergy_%d", clusters->GetArrayName().Data(),
fCentBin);
780 Int_t sm =
fGeom->GetSuperModuleNumber(it->second->GetCellAbsId(0));
781 if (sm >=0 && sm < 20) {
782 histname = TString::Format(
"%s/BySM/fHistClusEnergy_SM%d_%d", clusters->GetArrayName().Data(), sm,
fCentBin);
786 AliError(Form(
"Supermodule %d does not exist!", sm));
810 while ((particles = static_cast<AliParticleContainer*>(nextPartColl()))) {
814 UInt_t rejectionReason = 0;
815 if (!particles->
AcceptParticle(it.current_index(), rejectionReason)) {
816 histname = TString::Format(
"%s/fHistRejectionReason_%d", particles->GetArrayName().Data(),
fCentBin);
817 fHistManager.
FillTH2(histname, particles->GetRejectionReasonBitPosition(rejectionReason), it->first.Pt());
826 histname = TString::Format(
"%s/fHistTrPhiEtaPt_%d", particles->GetArrayName().Data(),
fCentBin);
830 if (it->second->GetLabel() == 0) {
832 histname = TString::Format(
"%s/fHistTrPhiEtaZeroLab_%d", particles->GetArrayName().Data(),
fCentBin);
838 histname = TString::Format(
"%s/fHistTrPtZeroLab_%d", particles->GetArrayName().Data(),
fCentBin);
844 if (it->second->GetLabel() < 0) neg++;
856 AliVTrack* vtrack =
dynamic_cast<AliVTrack*
>(it->second);
858 if (vtrack->GetTrackEtaOnEMCal() == -999 || vtrack->GetTrackPhiOnEMCal() == -999) {
859 histname = TString::Format(
"%s/fHistTrPhiEtaNonProp_%d", particles->GetArrayName().Data(),
fCentBin);
863 histname = TString::Format(
"%s/fHistTrPtNonProp_%d", particles->GetArrayName().Data(),
fCentBin);
869 histname = TString::Format(
"%s/fHistTrEmcPhiEta_%d", particles->GetArrayName().Data(),
fCentBin);
871 fHistManager.
FillTH2(histname, vtrack->GetTrackEtaOnEMCal(), vtrack->GetTrackPhiOnEMCal());
873 histname = TString::Format(
"%s/fHistTrEmcPt_%d", particles->GetArrayName().Data(),
fCentBin);
877 histname = TString::Format(
"%s/fHistDeltaEtaPt_%d", particles->GetArrayName().Data(),
fCentBin);
879 fHistManager.
FillTH2(histname, it->first.Pt(), it->first.Eta() - vtrack->GetTrackEtaOnEMCal());
881 histname = TString::Format(
"%s/fHistDeltaPhiPt_%d", particles->GetArrayName().Data(),
fCentBin);
883 fHistManager.
FillTH2(histname, it->first.Pt(), it->first.Phi_0_2pi() - vtrack->GetTrackPhiOnEMCal());
885 histname = TString::Format(
"%s/fHistDeltaPtvsPt_%d", particles->GetArrayName().Data(),
fCentBin);
887 fHistManager.
FillTH2(histname, it->first.Pt(), it->first.Pt() - vtrack->GetTrackPtOnEMCal());
891 if (type >= 0 && type <= 3) {
892 histname = TString::Format(
"%s/fHistTrPhiEtaPt_%d_%d", particles->GetArrayName().Data(),
fCentBin, type);
896 AliWarning(Form(
"%s: track type %d not recognized!", GetName(), type));
901 histname = TString::Format(
"%s/fHistTrNegativeLabels_%d", particles->GetArrayName().Data(),
fCentBin);
905 histname = TString::Format(
"%s/fHistTrZeroLabels_%d", particles->GetArrayName().Data(),
fCentBin);
void SetRejectionReasonLabels(TAxis *axis)
void UserCreateOutputObjects()
Int_t fNcentBins
how many centrality bins
AliEMCALGeometry * fGeom
!emcal geometry
Float_t fMaxPt
Histogram pt limit.
EBeamType_t fBeamType
!event beam type
TList * fOutput
!output list
void FillEventQAHisto(const EventQA_t &eventQA)
Double_t fCent3
!Event centrality with method 3
TObjArray fClusterCollArray
cluster collection array
Bool_t fSeparateEMCalDCal
Separate EMCal from DCal in QA plots.
AliTLorentzVector fLeadingCluster[2]
!Leading cluster in current event (EMCal/DCal)
TString fCentMethod3
Centrality method 3.
Int_t fNTotTracks
!Total number of accepted tracks in current event
Double_t fEPV0
!event plane V0
bidirectional stl iterator over the EMCAL iterable container
TObjArray fParticleCollArray
particle/track collection array
Container with name, TClonesArray and cuts for particles.
AliAnalysisTaskEmcalJetQA()
Double_t GetFcross(AliVCluster *cluster, AliVCaloCells *cells)
void FillTH2(const char *hname, double x, double y, double weight=1., Option_t *opt="")
AliTLorentzVector fMaxCluster[2]
void FillTH3(const char *hname, double x, double y, double z, double weight=1., Option_t *opt="")
Implementation of a task to perform basic QA on tracks and clusters.
Int_t fDoLeadingObjectPosition
Add axis for leading object position (eta-phi)
Double_t fV0CTotMult
!Event V0C total multiplicity
TString fCaloCellsName
name of calo cell collection
Bool_t fIsEmbedded
Embedded data present.
Container for particles within the EMCAL framework.
Int_t fMaxCellsInCluster
Maximum number (approx) of cells in a cluster.
Bool_t fParticleLevel
Set particle level analysis.
static Double_t fgkEMCalDCalPhiDivide
phi value used to distinguish between DCal and EMCal
THashList * CreateHistoGroup(const char *groupname, const char *parent="/")
EBeamType_t fForceBeamType
forced beam type
AliVCaloCells * fCaloCells
!cells
THistManager fHistManager
Histogram manager.
TH2 * CreateTH2(const char *name, const char *title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax, Option_t *opt="")
TObject * FindObject(const char *name) const
THashList * GetListOfHistograms() const
virtual ~AliAnalysisTaskEmcalJetQA()
Int_t fDoV0QA
Add V0 QA histograms.
Base task in the EMCAL framework (lighter version of AliAnalysisTaskEmcal)
Double_t Phi_0_2pi() const
Double_t fVertex[3]
!event vertex
TH1 * CreateTH1(const char *name, const char *title, int nbins, double xmin, double xmax, Option_t *opt="")
TString fCentMethod2
Centrality method 2.
virtual Bool_t AcceptCluster(Int_t i, UInt_t &rejectionReason) const
Bool_t RetrieveEventObjects()
Declaration of class AliAnalysisTaskEmcalJetQA.
ETrackFilterType_t GetTrackFilterType() const
Int_t fCentBin
!event centrality bin
virtual Bool_t AcceptParticle(const AliVParticle *vp, UInt_t &rejectionReason) const
void FillTH1(const char *hname, double x, double weight=1., Option_t *opt="")
virtual Bool_t RetrieveEventObjects()
Int_t fDoEPQA
Add event plane QA histograms.
const AliClusterIterableMomentumContainer all_momentum() const
void UserCreateOutputObjects()
Char_t GetTrackType(const AliVTrack *track) const
Int_t fNTotClusters[2]
!Total number of accepted clusters in current event (DCal/EMCal)
Double_t fCent2
!Event centrality with method 2
Float_t fPtBinWidth
Histogram pt bin width.
Float_t fCellEnergyCut
Energy cell cut.
AliTLorentzVector fMaxTrack
THnSparse * CreateTHnSparse(const char *name, const char *title, int ndim, const int *nbins, const double *min, const double *max, Option_t *opt="")
AliTLorentzVector fLeadingTrack
!Leading track in current event
Double_t fV0ATotMult
!Event V0A total multiplicity
Container structure for EMCAL clusters.
AliVVZERO * fVZERO
!Event V0 object
void SetMakeGeneralHistograms(Bool_t g)
const AliParticleIterableMomentumContainer all_momentum() const
Double_t fCent
!event centrality
ClassImp(AliAnalysisTaskEmcalJetQA) AliAnalysisTaskEmcalJetQA
TH3 * CreateTH3(const char *name, const char *title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax, int nbinsz, double zmin, double zmax, Option_t *opt="")
Bool_t fNeedEmcalGeom
whether or not the task needs the emcal geometry