+//________________________________________________________________________________________________
+Int_t AliEMCALGeometry::GetTRUIndexFromOnlineIndex(const Int_t id) const
+{
+ //Trigger mapping method, from STU index get TRU index
+
+ if (id > GetNTotalTRU()-1 || id < 0)
+ {
+ AliError(Form("TRU index out of range: %d",id));
+ }
+ if (id == 31) {
+ return 31;
+ }
+ if (fGeoName.Contains("DCAL_8SM") && id == 51) {
+ return 51;
+ }
+
+ //jump 4 TRUs for DCAL
+ Int_t tmp=0;
+ if(id > 31) tmp = id+4;
+ else tmp = id;
+ Int_t idx = ((tmp% 6) < 3) ? 6 * int(tmp/ 6) + 2 * (tmp% 3) : 6 * int(tmp/ 6) + 2 * (2 - (tmp% 3)) + 1;
+ if(id > 31) idx-=4;
+ return idx;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetOnlineIndexFromTRUIndex(const Int_t id, Int_t& idx) const
+{
+ //Trigger mapping method, from STU index get TRU index
+
+ idx = GetOnlineIndexFromTRUIndex(id);
+ if (idx > GetNTotalTRU()-1 || idx < 0)
+ {
+ AliError(Form("TRU index out of range: %d",idx));
+ return kFALSE;
+ }
+ return kTRUE;
+}
+//________________________________________________________________________________________________
+Int_t AliEMCALGeometry::GetOnlineIndexFromTRUIndex(const Int_t id) const
+{
+ //Trigger mapping method, from STU index get TRU index
+
+ if (id > GetNTotalTRU()-1 || id < 0)
+ {
+ AliError(Form("TRU index out of range: %d",id));
+ }
+ if (id == 31) {
+ return 31;
+ }
+ if (fGeoName.Contains("DCAL_8SM") && id == 51) {
+ return 51;
+ }
+
+ //jump 4 TRUs for DCAL
+ Int_t tmp=0;
+ if(id > 31) tmp = id+4;
+ else tmp = id;
+ Int_t idx = (tmp % 2) ? int((6 - (tmp % 6)) / 2) + 3 * (2 * int(tmp / 6) + 1) : 3 * int(tmp / 6) + int(tmp / 2);
+ if(id > 31) idx-=4;
+ return idx;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::GetFastORIndexFromL0Index(const Int_t iTRU, const Int_t id, Int_t idx[], const Int_t size) const
+{
+ //Trigger mapping method, from L0 index get FastOR index
+
+ if (size <= 0 ||size > 4)
+ {
+ AliError("Size not supported!");
+ return kFALSE;
+ }
+
+ Int_t motif[4] = {0, 1, 4, 5};
+ switch (size)
+ {
+ case 1: // Cosmic trigger
+ if (!GetAbsFastORIndexFromTRU(iTRU, id, idx[1])) return kFALSE;
+ break;
+ case 4: // 4 x 4
+ for (Int_t k = 0; k < 4; k++)
+ {
+ Int_t iADC = motif[k] + 4 * int(id / 3) + (id % 3);
+
+ if (!GetAbsFastORIndexFromTRU(iTRU, iADC, idx[k])) return kFALSE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return kTRUE;
+}
+
+//____________________________________________________________________________
+const TGeoHMatrix * AliEMCALGeometry::GetMatrixForSuperModule(Int_t smod) const
+{
+ //Provides shift-rotation matrix for EMCAL
+
+ if(smod < 0 || smod > fEMCGeometry->GetNumberOfSuperModules())
+ AliFatal(Form("Wrong supermodule index -> %d",smod));
+
+ //If GeoManager exists, take matrixes from it
+
+ //
+ // if(fKey110DEG && ind>=10) {
+ // }
+ //
+ // if(!gGeoManager->cd(volpath.Data()))
+ // AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
+ //
+ // TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
+
+ //Use matrices set externally
+ if(!gGeoManager || (gGeoManager && fUseExternalMatrices)){
+ if(fkSModuleMatrix[smod]){
+ return fkSModuleMatrix[smod] ;
+ }
+ else{
+ AliInfo("Stop:");
+ printf("\t Can not find EMCAL misalignment matrixes\n") ;
+ printf("\t Either import TGeoManager from geometry.root or \n");
+ printf("\t read stored matrixes from AliESD Header: \n") ;
+ printf("\t AliEMCALGeometry::SetMisalMatrixes(header->GetEMCALMisalMatrix()) \n") ;
+ AliFatal("") ;
+ }
+ }//external matrices
+
+ if(gGeoManager){
+ const Int_t buffersize = 255;
+ char path[buffersize] ;
+ TString SMName;
+ Int_t tmpType = -1;
+ Int_t SMOrder = 0;
+//Get the order for SM
+ for( Int_t i = 0; i < smod+1; i++){
+ if(GetSMType(i) == tmpType) {
+ SMOrder++;
+ } else {
+ tmpType = GetSMType(i);
+ SMOrder = 1;
+ }
+ }
+
+ if(GetSMType(smod) == kEMCAL_Standard ) SMName = "SMOD";
+ else if(GetSMType(smod) == kEMCAL_Half ) SMName = "SM10";
+ else if(GetSMType(smod) == kEMCAL_3rd ) SMName = "SM3rd";
+ else if( GetSMType(smod) == kDCAL_Standard ) SMName = "DCSM";
+ else if( GetSMType(smod) == kDCAL_Ext ) SMName = "DCEXT";
+ else AliError("Unkown SM Type!!");
+ snprintf(path,buffersize,"/ALIC_1/XEN1_1/%s_%d", SMName.Data(), SMOrder) ;
+
+ if (!gGeoManager->cd(path)){
+ AliFatal(Form("Geo manager can not find path %s!\n",path));
+ }
+ return gGeoManager->GetCurrentMatrix();
+ }
+ return 0 ;
+}
+
+//______________________________________________________________________
+void AliEMCALGeometry::GetModulePhiEtaIndexInSModuleFromTRUIndex(Int_t itru, Int_t iphitru, Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
+{
+ // This method transforms the (eta,phi) index of module in a
+ // TRU matrix into Super Module (eta,phi) index.
+
+ // Calculate in which row and column where the TRU are
+ // ordered in the SM
+
+ Int_t col = itru/fEMCGeometry->GetNTRUPhi() ; // indexes of TRU in SM
+ Int_t row = itru - col*fEMCGeometry->GetNTRUPhi();
+
+ iphiSM = fEMCGeometry->GetNModulesInTRUPhi()*row + iphitru ;
+ ietaSM = fEMCGeometry->GetNModulesInTRUEta()*col + ietatru ;
+}
+
+//__________________________________________________________________________________________________________________
+void AliEMCALGeometry::RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, const Float_t depth,
+ const Float_t misaligTransShifts[15], const Float_t misaligRotShifts[15], Float_t global[3]) const
+{
+ //Transform clusters cell position into global with alternative method, taking into account the depth calculation.
+ //Input are: the tower indeces,
+ // supermodule,
+ // particle type (photon 0, electron 1, hadron 2 )
+ // misalignment shifts to global position in case of need.
+ // Federico.Ronchetti@cern.ch
+
+ // To use in a print later
+ Float_t droworg = drow;
+ Float_t dcolorg = dcol;
+
+ if(gGeoManager){
+ //Recover some stuff
+
+ const Int_t nSMod = fEMCGeometry->GetNumberOfSuperModules();
+
+ gGeoManager->cd("ALIC_1/XEN1_1");
+ TGeoNode *geoXEn1 = gGeoManager->GetCurrentNode();
+ TGeoNodeMatrix *geoSM[nSMod];
+ TGeoVolume *geoSMVol[nSMod];
+ TGeoShape *geoSMShape[nSMod];
+ TGeoBBox *geoBox[nSMod];
+ TGeoMatrix *geoSMMatrix[nSMod];
+
+ for(int iSM = 0; iSM < nSMod; iSM++) {
+ geoSM[iSM] = dynamic_cast<TGeoNodeMatrix *>(geoXEn1->GetDaughter(iSM));
+ geoSMVol[iSM] = geoSM[iSM]->GetVolume();
+ geoSMShape[iSM] = geoSMVol[iSM]->GetShape();
+ geoBox[iSM] = dynamic_cast<TGeoBBox *>(geoSMShape[iSM]);
+ geoSMMatrix[iSM] = geoSM[iSM]->GetMatrix();
+ }
+
+ if(sm % 2 == 0) {
+ dcol = 47. - dcol;
+ drow = 23. - drow;
+ }
+
+ Int_t istrip = 0;
+ Float_t z0 = 0;
+ Float_t zb = 0;
+ Float_t zIs = 0;
+
+ Float_t x,y,z; // return variables in terry's RF
+
+ //***********************************************************
+ //Do not like this: too many hardcoded values, is it not already stored somewhere else?
+ // : need more comments in the code
+ //***********************************************************
+
+ Float_t dz = 6.0; // base cell width in eta
+ Float_t dx = 6.004; // base cell width in phi
+
+
+ //Float_t L = 26.04; // active tower length for hadron (lead+scint+paper)
+ // we use the geant numbers 13.87*2=27.74
+ Float_t teta1 = 0.;
+
+ //Do some basic checks
+ if (dcol >= 47.5 || dcol<-0.5) {
+ AliError(Form("Bad tower coordinate dcol=%f, where dcol >= 47.5 || dcol<-0.5; org: %f", dcol, dcolorg));
+ return;
+ }
+ if (drow >= 23.5 || drow<-0.5) {
+ AliError(Form("Bad tower coordinate drow=%f, where drow >= 23.5 || drow<-0.5; org: %f", drow, droworg));
+ return;
+ }
+ if (sm >= nSMod || sm < 0) {
+ AliError(Form("Bad SM number sm=%d, where sm >= %d || sm < 0", nSMod, sm));
+ return;
+ }
+
+ istrip = int ((dcol+0.5)/2);
+
+ // tapering angle
+ teta1 = TMath::DegToRad() * istrip * 1.5;
+
+ // calculation of module corner along z
+ // as a function of strip
+
+ for (int is=0; is<= istrip; is++) {
+
+ teta1 = TMath::DegToRad() * (is*1.5 + 0.75);
+ if(is==0)
+ zIs = zIs + 2*dz*TMath::Cos(teta1);
+ else
+ zIs = zIs + 2*dz*TMath::Cos(teta1) + 2*dz*TMath::Sin(teta1)*TMath::Tan(teta1-0.75*TMath::DegToRad());
+
+ }
+
+ z0 = dz*(dcol-2*istrip+0.5);
+ zb = (2*dz-z0-depth*TMath::Tan(teta1));
+
+ z = zIs - zb*TMath::Cos(teta1);
+ y = depth/TMath::Cos(teta1) + zb*TMath::Sin(teta1);
+
+ x = (drow + 0.5)*dx;
+
+ // moving the origin from terry's RF
+ // to the GEANT one
+
+ double xx = y - geoBox[sm]->GetDX();
+ double yy = -x + geoBox[sm]->GetDY();
+ double zz = z - geoBox[sm]->GetDZ();
+ const double localIn[3] = {xx, yy, zz};
+ double dglobal[3];
+ //geoSMMatrix[sm]->Print();
+ //printf("TFF Local (row = %d, col = %d, x = %3.2f, y = %3.2f, z = %3.2f)\n", iroworg, icolorg, localIn[0], localIn[1], localIn[2]);
+ geoSMMatrix[sm]->LocalToMaster(localIn, dglobal);
+ //printf("TFF Global (row = %2.0f, col = %2.0f, x = %3.2f, y = %3.2f, z = %3.2f)\n", drow, dcol, dglobal[0], dglobal[1], dglobal[2]);
+
+ //apply global shifts
+ if(sm == 2 || sm == 3) {//sector 1
+ global[0] = dglobal[0] + misaligTransShifts[3] + misaligRotShifts[3]*TMath::Sin(TMath::DegToRad()*20) ;
+ global[1] = dglobal[1] + misaligTransShifts[4] + misaligRotShifts[4]*TMath::Cos(TMath::DegToRad()*20) ;
+ global[2] = dglobal[2] + misaligTransShifts[5];
+ }
+ else if(sm == 0 || sm == 1){//sector 0
+ global[0] = dglobal[0] + misaligTransShifts[0];
+ global[1] = dglobal[1] + misaligTransShifts[1];
+ global[2] = dglobal[2] + misaligTransShifts[2];
+ }
+ else {
+ AliInfo("Careful, correction not implemented yet!");
+ global[0] = dglobal[0] ;
+ global[1] = dglobal[1] ;
+ global[2] = dglobal[2] ;
+ }
+ }
+ else{
+ AliFatal("Geometry boxes information, check that geometry.root is loaded\n");
+ }
+}
+
+//__________________________________________________________________________________________________________________
+void AliEMCALGeometry::SetMisalMatrix(const TGeoHMatrix * m, Int_t smod)
+{
+ // Method to set shift-rotational matrixes from ESDHeader
+ // Move from header due to coding violations : Dec 2,2011 by PAI
+ fUseExternalMatrices = kTRUE;
+
+ if (smod >= 0 && smod < fEMCGeometry->GetNumberOfSuperModules()){
+ if(!fkSModuleMatrix[smod]) fkSModuleMatrix[smod] = new TGeoHMatrix(*m) ; //Set only if not set yet
+ } else AliFatal(Form("Wrong supermodule index -> %d",smod));
+}
+
+//__________________________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::IsDCALSM(Int_t iSupMod) const
+{
+ if( fEMCSMSystem[iSupMod] == kDCAL_Standard || fEMCSMSystem[iSupMod] == kDCAL_Ext ) return kTRUE;
+ return kFALSE;
+}
+
+//__________________________________________________________________________________________________________________
+Bool_t AliEMCALGeometry::IsDCALExtSM(Int_t iSupMod) const
+{
+ if( fEMCSMSystem[iSupMod] == kDCAL_Ext ) return kTRUE;
+ return kFALSE;