+
+ //Equation of Plane from glob,glob2,glob3 (Ax+By+Cz+D=0)
+ Double_t a = glob[1]*(glob2[2]-glob3[2]) + glob2[1]*(glob3[2]-glob[2]) + glob3[1]*(glob[2]-glob2[2]);
+ Double_t b = glob[2]*(glob2[0]-glob3[0]) + glob2[2]*(glob3[0]-glob[0]) + glob3[2]*(glob[0]-glob2[0]);
+ Double_t c = glob[0]*(glob2[1]-glob3[1]) + glob2[0]*(glob3[1]-glob[1]) + glob3[0]*(glob[1]-glob2[1]);
+ Double_t d = glob[0]*(glob2[1]*glob3[2]-glob3[1]*glob2[2]) + glob2[0]*(glob3[1]*glob[2]-glob[1]*glob3[2]) + glob3[0]*(glob[1]*glob2[2]-glob2[1]*glob[2]);
+ d=-d;
+
+ //shift equation of plane from tower/module center to surface along vector (A,B,C) normal to tower/module plane
+ Double_t dist = fLongModuleSize/2.;
+ Double_t norm = TMath::Sqrt(a*a+b*b+c*c);
+ Double_t glob4[3]={};
+ TVector3 dir(a,b,c);
+ TVector3 point(glob[0],glob[1],glob[2]);
+ if(point.Dot(dir)<0) dist*=-1;
+ glob4[0]=glob[0]-dist*a/norm;
+ glob4[1]=glob[1]-dist*b/norm;
+ glob4[2]=glob[2]-dist*c/norm;
+ d = glob4[0]*a + glob4[1]*b + glob4[2]*c ;
+ d = -d;
+
+ //Line determination (2 points for equation of line : vtx and direction)
+ //impact between line (particle) and plane (module/tower plane)
+ Double_t den = a*(vtx(0)-direction(0)) + b*(vtx(1)-direction(1)) + c*(vtx(2)-direction(2));
+ if(den==0){
+ printf("ImpactOnEmcal() No solution :\n");
+ return;
+ }
+
+ Double_t length = a*vtx(0)+b*vtx(1)+c*vtx(2)+d;
+ length /=den;
+
+ vimpact.SetXYZ(vtx(0)+length*(direction(0)-vtx(0)),vtx(1)+length*(direction(1)-vtx(1)),vtx(2)+length*(direction(2)-vtx(2)));
+
+ //shift vimpact from tower/module surface to center along vector (A,B,C) normal to tower/module plane
+ vimpact.SetXYZ(vimpact(0)+dist*a/norm,vimpact(1)+dist*b/norm,vimpact(2)+dist*c/norm);
+
+ return;
+}
+
+//_____________________________________________________________________________
+Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const
+{
+ // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
+ //
+ // Code uses cylindrical approximation made of inner radius (for speed)
+ //
+ // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
+ // are considered to inside
+
+ Double_t r=sqrt(x*x+y*y);
+
+ if ( r > fEnvelop[0] ) {
+ Double_t theta;
+ theta = TMath::ATan2(r,z);
+ Double_t eta;
+ if(theta == 0)
+ eta = 9999;
+ else
+ eta = -TMath::Log(TMath::Tan(theta/2.));
+ if (eta < fArm1EtaMin || eta > fArm1EtaMax)
+ return 0;
+
+ Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
+ if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
+ if (phi > fArm1PhiMin && phi < fArm1PhiMax)
+ return 1;
+ }
+ return 0;
+}
+
+//________________________________________________________________________________________________
+Int_t AliEMCALGeometry::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int_t col, const Int_t sm) const
+{
+ // Nov 6, 2007
+ // Get TRU absolute number from column, row and Super Module number
+ Int_t itru = row + col*fEMCGeometry->GetNModulesInTRUPhi() + sm*fEMCGeometry->GetNTRU();
+ // printf(" GetAbsTRUNumberFromNumberInSm : row %2i col %2i sm %2i -> itru %2i\n", row, col, sm, itru);
+ return itru;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const
+{
+ //Trigger mapping method, get FastOr Index from TRU
+
+ if (iTRU > 31 || iTRU < 0 || iADC > 95 || iADC < 0)
+ {
+ AliError("TRU out of range!");
+ return kFALSE;
+ }
+
+ id = ( iTRU % 2 ) ? iADC%4 + 4 * (23 - int(iADC/4)) : (3 - iADC%4) + 4 * int(iADC/4);
+ id += iTRU * 96;
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const
+{
+ //Trigger mapping method, get TRU number from FastOr Index
+
+ if (id > 3071 || id < 0)
+ {
+ AliError("Id out of range!");
+ return kFALSE;
+ }
+
+ iTRU = id / 96;
+ iADC = id % 96;
+ iADC = ( iTRU % 2 ) ? iADC%4 + 4 * (23 - int(iADC/4)) : (3 - iADC%4) + 4 * int(iADC/4);
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const
+{
+ //Trigger mapping method, get position in TRU from FasOr Index
+
+ Int_t iADC=-1;
+ if (!GetTRUFromAbsFastORIndex(id, iTRU, iADC)) return kFALSE;
+
+ Int_t x = iADC / 4;
+ Int_t y = iADC % 4;
+ if ( iTRU % 2 ) // C side
+ {
+ iEta = 23 - x;
+ iPhi = y;
+ }
+ else // A side
+ {
+ iEta = x;
+ iPhi = 3 - y;
+ }
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const
+{
+ //Trigger mapping method, get position in Super Module from FasOr Index
+
+ Int_t iTRU=-1;
+ if (!GetPositionInTRUFromAbsFastORIndex(id, iTRU, iEta, iPhi)) return kFALSE;
+ if (iTRU % 2) // C side
+ {
+ iSM = 2 * ( int( int(iTRU / 2) / 3 ) ) + 1;
+ }
+ else // A side
+ {
+ iSM = 2 * ( int( int(iTRU / 2) / 3 ) );
+ }
+ iPhi += 4 * int((iTRU % 6) / 2);
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetPositionInEMCALFromAbsFastORIndex(const Int_t id, Int_t& iEta, Int_t& iPhi) const
+{
+ //Trigger mapping method, get position in EMCAL from FastOR index
+
+ Int_t iSM=-1;
+ if (GetPositionInSMFromAbsFastORIndex(id, iSM, iEta, iPhi))
+ {
+ if (iSM % 2) iEta += 24;
+ iPhi += 12 * int(iSM / 2);
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+ //Trigger mapping method, get Index if FastOr from Position in TRU
+ if (iTRU < 0 || iTRU > 31 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 3)
+ {
+ AliError("Out of range!");
+ return kFALSE;
+ }
+ id = iPhi + 4 * iEta + iTRU * 96;
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetAbsFastORIndexFromPositionInSM(const Int_t iSM, const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+ //Trigger mapping method, from position in SM Index get FastOR index
+
+ if (iSM < 0 || iSM > 11 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 11)
+ {
+ AliError("Out of range!");
+ return kFALSE;
+ }
+ Int_t x = iEta;
+ Int_t y = iPhi % 4;
+ Int_t iOff = (iSM % 2) ? 1 : 0;
+ Int_t iTRU = 2 * int(iPhi / 4) + 6 * int(iSM / 2) + iOff;
+ if (GetAbsFastORIndexFromPositionInTRU(iTRU, x, y, id))
+ {
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetAbsFastORIndexFromPositionInEMCAL(const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+ //Trigger mapping method, from position in EMCAL Index get FastOR index
+
+ if (iEta < 0 || iEta > 47 || iPhi < 0 || iPhi > 63 )
+ {
+ AliError(Form("Out of range! eta: %2d phi: %2d", iEta, iPhi));
+ return kFALSE;
+ }
+ if (fFastOR2DMap[iEta][iPhi] == -1)
+ {
+ AliError("Invalid index!");
+ return kFALSE;
+ }
+ id = fFastOR2DMap[iEta][iPhi];
+ return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetFastORIndexFromCellIndex(const Int_t id, Int_t& idx) const
+{
+ //Trigger mapping method, from cell index get FastOR index
+
+ Int_t iSupMod, nModule, nIphi, nIeta, iphim, ietam;
+ Bool_t isOK = GetCellIndex( id, iSupMod, nModule, nIphi, nIeta );
+ GetModulePhiEtaIndexInSModule( iSupMod, nModule, iphim, ietam );
+ if (isOK && GetAbsFastORIndexFromPositionInSM(iSupMod, ietam, iphim, idx))
+ {
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetCellIndexFromFastORIndex(const Int_t id, Int_t idx[4]) const
+{
+ //Trigger mapping method, from FASTOR index get cell index
+
+ Int_t iSM=-1, iEta=-1, iPhi=-1;
+ if (GetPositionInSMFromAbsFastORIndex(id, iSM, iEta, iPhi))
+ {
+ Int_t ix = 2 * iEta;
+ Int_t iy = 2 * iPhi;
+ for (Int_t i=0; i<2; i++)
+ {
+ for (Int_t j=0; j<2; j++)
+ {
+ idx[2*i+j] = GetAbsCellIdFromCellIndexes(iSM, iy + i, ix + j);
+ }