X-Git-Url: http://git.uio.no/git/?p=u%2Fmrichter%2FAliRoot.git;a=blobdiff_plain;f=PHOS%2FAliPHOSGeometry.cxx;h=35fd78b18338f836f2aca6d68da03ea69cb4a89f;hp=541e6f4bcd7bf09fd72b832743a06710e0309e9d;hb=fa7cce36cc9d89d826b515b7bd8c08120ca3c24d;hpb=5cda30f6c0a449e85be08ae83ad0a890f5f7eb47 diff --git a/PHOS/AliPHOSGeometry.cxx b/PHOS/AliPHOSGeometry.cxx index 541e6f4bcd7..35fd78b1833 100644 --- a/PHOS/AliPHOSGeometry.cxx +++ b/PHOS/AliPHOSGeometry.cxx @@ -17,8 +17,12 @@ //_________________________________________________________________________ // Geometry class for PHOS : singleton -// The EMC modules are parametrized so that any configuration can be easily implemented -// The title is used to identify the type of CPV used. So far only PPSD implemented +// PHOS consists of the electromagnetic calorimeter (EMCA) +// and a charged particle veto either in the Subatech's version (PPSD) +// or in the IHEP's one (CPV). +// The EMCA/PPSD/CPV modules are parametrized so that any configuration +// can be easily implemented +// The title is used to identify the version of CPV used. // //*-- Author: Yves Schutz (SUBATECH) @@ -26,6 +30,8 @@ #include "TVector3.h" #include "TRotation.h" +#include "TFolder.h" +#include "TROOT.h" // --- Standard library --- @@ -34,11 +40,13 @@ // --- AliRoot header files --- #include "AliPHOSGeometry.h" +#include "AliPHOSEMCAGeometry.h" #include "AliPHOSPpsdRecPoint.h" #include "AliConst.h" ClassImp(AliPHOSGeometry) ; +// these initialisations are needed for a singleton AliPHOSGeometry * AliPHOSGeometry::fgGeom = 0 ; Bool_t AliPHOSGeometry::fgInit = kFALSE ; @@ -47,10 +55,139 @@ AliPHOSGeometry::~AliPHOSGeometry(void) { // dtor - fRotMatrixArray->Delete() ; - delete fRotMatrixArray ; + if (fRotMatrixArray) fRotMatrixArray->Delete() ; + if (fRotMatrixArray) delete fRotMatrixArray ; + if (fPHOSAngle ) delete fPHOSAngle ; +} + +//____________________________________________________________________________ + +void AliPHOSGeometry::Init(void) +{ + // Initializes the PHOS parameters : + // IHEP is the Protvino CPV (cathode pad chambers) + // GPS2 is the Subatech Pre-Shower (two micromegas sandwiching a passive lead converter) + // MIXT 4 PHOS modules withe the IHEP CPV qnd one PHOS module with the Subatche Pre-Shower + + if ( ((strcmp( fName, "GPS2" )) == 0) || + ((strcmp( fName, "IHEP" )) == 0) || + ((strcmp( fName, "MIXT" )) == 0) ) { + fgInit = kTRUE ; + + fNModules = 5; + fNPPSDModules = 0; + fAngle = 20; + + fGeometryEMCA = new AliPHOSEMCAGeometry(); + if ( ((strcmp( fName, "GPS2" )) == 0) ) { + fGeometryPPSD = new AliPHOSPPSDGeometry(); + fGeometryCPV = 0; + fNPPSDModules = fNModules; + } + else if ( ((strcmp( fName, "IHEP" )) == 0) ) { + fGeometryCPV = new AliPHOSCPVGeometry (); + fGeometryPPSD = 0; + fNPPSDModules = 0; + } + else if ( ((strcmp( fName, "MIXT" )) == 0) ) { + fGeometryCPV = new AliPHOSCPVGeometry (); + fGeometryPPSD = new AliPHOSPPSDGeometry(); + fNPPSDModules = 1; + } + fGeometrySUPP = new AliPHOSSupportGeometry(); + + fPHOSAngle = new Float_t[fNModules] ; + Int_t index ; + for ( index = 0; index < fNModules; index++ ) + fPHOSAngle[index] = 0.0 ; // Module position angles are set in CreateGeometry() + + this->SetPHOSAngles() ; + fRotMatrixArray = new TObjArray(fNModules) ; - delete fPHOSAngle ; + // post the geometry into the appropriate folder + // get the alice folder + TFolder * alice = (TFolder*)gROOT->GetListOfBrowsables()->FindObject("YSAlice") ; + // the folder that contains the alarms for PHOS + TFolder * folder = (TFolder*)alice->FindObject("folders/Geometry/PHOS"); + folder->SetOwner() ; + folder->Add(this) ; + } + else { + fgInit = kFALSE ; + cout << "PHOS Geometry setup: option not defined " << fName << endl ; + } +} + +//____________________________________________________________________________ +Float_t AliPHOSGeometry::GetCPVBoxSize(Int_t index) const +{ + // returns the coarse dimension CPV depending on the CPV option set + + if (strcmp(fName,"GPS2") ==0 ) + return fGeometryPPSD->GetCPVBoxSize(index); + else if (strcmp(fName,"IHEP")==0) + return fGeometryCPV ->GetCPVBoxSize(index); + else if (strcmp(fName,"MIXT")==0) + return TMath::Max(fGeometryCPV ->GetCPVBoxSize(index), fGeometryPPSD->GetCPVBoxSize(index)); + else + return 0; +} + +//____________________________________________________________________________ +AliPHOSGeometry * AliPHOSGeometry::GetInstance() +{ + // Returns the pointer of the unique instance; singleton specific + + return (AliPHOSGeometry *) fgGeom ; +} + +//____________________________________________________________________________ +AliPHOSGeometry * AliPHOSGeometry::GetInstance(const Text_t* name, const Text_t* title) +{ + // Returns the pointer of the unique instance + // Creates it with the specified options (name, title) if it does not exist yet + + AliPHOSGeometry * rv = 0 ; + if ( fgGeom == 0 ) { + if ( strcmp(name,"") == 0 ) + rv = 0 ; + else { + fgGeom = new AliPHOSGeometry(name, title) ; + if ( fgInit ) + rv = (AliPHOSGeometry * ) fgGeom ; + else { + rv = 0 ; + delete fgGeom ; + fgGeom = 0 ; + } + } + } + else { + if ( strcmp(fgGeom->GetName(), name) != 0 ) { + cout << "AliPHOSGeometry : current geometry is " << fgGeom->GetName() << endl + << " you cannot call " << name << endl ; + } + else + rv = (AliPHOSGeometry *) fgGeom ; + } + return rv ; +} + +//____________________________________________________________________________ +void AliPHOSGeometry::SetPHOSAngles() +{ + // Calculates the position of the PHOS modules in ALICE global coordinate system + + Double_t const kRADDEG = 180.0 / kPI ; + Float_t pphi = 2 * TMath::ATan( GetOuterBoxSize(0) / ( 2.0 * GetIPtoOuterCoverDistance() ) ) ; + pphi *= kRADDEG ; + if (pphi > fAngle) cout << "AliPHOSGeometry: PHOS modules overlap!\n"; + pphi = fAngle; + + for( Int_t i = 1; i <= fNModules ; i++ ) { + Float_t angle = pphi * ( i - fNModules / 2.0 - 0.5 ) ; + fPHOSAngle[i-1] = - angle ; + } } //____________________________________________________________________________ @@ -68,16 +205,49 @@ Bool_t AliPHOSGeometry::AbsToRelNumbering(const Int_t AbsId, Int_t * relid) Int_t phosmodulenumber = (Int_t)TMath:: Ceil( id / ( GetNPhi() * GetNZ() ) ) ; - if ( phosmodulenumber > GetNModules() ) { // its a PPSD pad - - id -= GetNPhi() * GetNZ() * GetNModules() ; - Float_t tempo = 2 * GetNumberOfModulesPhi() * GetNumberOfModulesZ() * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; - relid[0] = (Int_t)TMath::Ceil( id / tempo ) ; - id -= ( relid[0] - 1 ) * tempo ; - relid[1] = (Int_t)TMath::Ceil( id / ( GetNumberOfPadsPhi() * GetNumberOfPadsZ() ) ) ; - id -= ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; - relid[2] = (Int_t)TMath::Ceil( id / GetNumberOfPadsPhi() ) ; - relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * GetNumberOfPadsPhi() ) ; + if ( phosmodulenumber > GetNModules() ) { // it is a PPSD or CPV pad + + if ( strcmp(fName,"GPS2") == 0 ) { + id -= GetNPhi() * GetNZ() * GetNModules() ; + Float_t tempo = 2 * GetNumberOfModulesPhi() * GetNumberOfModulesZ() * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; + relid[0] = (Int_t)TMath::Ceil( id / tempo ) ; + id -= ( relid[0] - 1 ) * tempo ; + relid[1] = (Int_t)TMath::Ceil( id / ( GetNumberOfPadsPhi() * GetNumberOfPadsZ() ) ) ; + id -= ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; + relid[2] = (Int_t)TMath::Ceil( id / GetNumberOfPadsPhi() ) ; + relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * GetNumberOfPadsPhi() ) ; + } + else if ( strcmp(fName,"IHEP") == 0 ) { + id -= GetNPhi() * GetNZ() * GetNModules() ; + Float_t nCPV = GetNumberOfCPVPadsPhi() * GetNumberOfCPVPadsZ() ; + relid[0] = (Int_t) TMath::Ceil( id / nCPV ) ; + relid[1] = 1 ; + id -= ( relid[0] - 1 ) * nCPV ; + relid[2] = (Int_t) TMath::Ceil( id / GetNumberOfCPVPadsZ() ) ; + relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * GetNumberOfCPVPadsZ() ) ; + } + else if ( strcmp(fName,"MIXT") == 0 ) { + id -= GetNPhi() * GetNZ() * GetNModules() ; + Float_t nPPSD = 2 * GetNumberOfModulesPhi() * GetNumberOfModulesZ() * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; + Float_t nCPV = GetNumberOfCPVPadsPhi() * GetNumberOfCPVPadsZ() ; + if (id <= nCPV*GetNCPVModules()) { // this pad belons to CPV + relid[0] = (Int_t) TMath::Ceil( id / nCPV ) ; + relid[1] = 1 ; + id -= ( relid[0] - 1 ) * nCPV ; + relid[2] = (Int_t) TMath::Ceil( id / GetNumberOfCPVPadsZ() ) ; + relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * GetNumberOfCPVPadsZ() ) ; + } + else { // this pad belons to PPSD + id -= nCPV*GetNCPVModules(); + relid[0] = (Int_t)TMath::Ceil( id / nPPSD ); + id -= ( relid[0] - 1 ) * nPPSD ; + relid[0] += GetNCPVModules(); + relid[1] = (Int_t)TMath::Ceil( id / ( GetNumberOfPadsPhi() * GetNumberOfPadsZ() ) ) ; + id -= ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; + relid[2] = (Int_t)TMath::Ceil( id / GetNumberOfPadsPhi() ) ; + relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * GetNumberOfPadsPhi() ) ; + } + } } else { // its a PW04 crystal @@ -89,10 +259,11 @@ Bool_t AliPHOSGeometry::AbsToRelNumbering(const Int_t AbsId, Int_t * relid) } return rv ; } + //____________________________________________________________________________ void AliPHOSGeometry::EmcModuleCoverage(const Int_t mod, Double_t & tm, Double_t & tM, Double_t & pm, Double_t & pM, Option_t * opt) { - // calculates the angular coverage in theta and phi of a EMC module + // calculates the angular coverage in theta and phi of one EMC (=PHOS) module Double_t conv ; if ( opt == Radian() ) @@ -126,7 +297,7 @@ void AliPHOSGeometry::EmcModuleCoverage(const Int_t mod, Double_t & tm, Double_t //____________________________________________________________________________ void AliPHOSGeometry::EmcXtalCoverage(Double_t & theta, Double_t & phi, Option_t * opt) { - // calculates the angular coverage in theta and phi of a single crystal in a EMC module + // calculates the angular coverage in theta and phi of a single crystal in a EMC(=PHOS) module Double_t conv ; if ( opt == Radian() ) @@ -146,36 +317,9 @@ void AliPHOSGeometry::EmcXtalCoverage(Double_t & theta, Double_t & phi, Option_t //____________________________________________________________________________ -void AliPHOSGeometry::ImpactOnEmc(const Double_t theta, const Double_t phi, Int_t & ModuleNumber, Double_t & z, Double_t & x) -{ - // calculates the impact coordinates of a neutral particle - // emitted in direction theta and phi in ALICE - - // searches for the PHOS EMC module - ModuleNumber = 0 ; - Double_t tm, tM, pm, pM ; - Int_t index = 1 ; - while ( ModuleNumber == 0 && index <= GetNModules() ) { - EmcModuleCoverage(index, tm, tM, pm, pM) ; - if ( (theta >= tm && theta <= tM) && (phi >= pm && phi <= pM ) ) - ModuleNumber = index ; - index++ ; - } - if ( ModuleNumber != 0 ) { - Float_t phi0 = GetPHOSAngle(ModuleNumber) * (TMath::Pi() / 180.) + 1.5 * TMath::Pi() ; - Float_t y0 = GetIPtoOuterCoverDistance() + GetUpperPlateThickness() - + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness() ; - Double_t angle = phi - phi0; - x = y0 * TMath::Tan(angle) ; - angle = theta - TMath::Pi() / 2 ; - z = y0 * TMath::Tan(angle) ; - } -} - -//____________________________________________________________________________ -void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos, TMatrix & gmat) const +void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos, TMatrix & gmat) const { - // Calculates the ALICE global coordinates of a RecPoint and the error matrix + // Calculates the coordinates of a RecPoint and the error matrix in the ALICE global coordinate system AliPHOSRecPoint * tmpPHOS = (AliPHOSRecPoint *) RecPoint ; TVector3 localposition ; @@ -216,7 +360,7 @@ void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos, TM //____________________________________________________________________________ void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos) const { - // Calculates the ALICE global coordinates of a RecPoint + // Calculates the coordinates of a RecPoint in the ALICE global coordinate system AliPHOSRecPoint * tmpPHOS = (AliPHOSRecPoint *) RecPoint ; TVector3 localposition ; @@ -252,202 +396,82 @@ void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos) co } //____________________________________________________________________________ -void AliPHOSGeometry::Init(void) +void AliPHOSGeometry::ImpactOnEmc(const Double_t theta, const Double_t phi, Int_t & ModuleNumber, Double_t & z, Double_t & x) { - // Initializes the PHOS parameters + // calculates the impact coordinates on PHOS of a neutral particle + // emitted in the direction theta and phi in the ALICE global coordinate system - cout << "PHOS geometry setup: parameters for option " << fName << " " << fTitle << endl ; - if ( ((strcmp( fName, "default" )) == 0) || ((strcmp( fName, "GPS2" )) == 0) ) { - fgInit = kTRUE ; - this->InitPHOS() ; - this->InitPPSD() ; - this->SetPHOSAngles() ; - fRotMatrixArray = new TObjArray(fNModules) ; + // searches for the PHOS EMC module + ModuleNumber = 0 ; + Double_t tm, tM, pm, pM ; + Int_t index = 1 ; + while ( ModuleNumber == 0 && index <= GetNModules() ) { + EmcModuleCoverage(index, tm, tM, pm, pM) ; + if ( (theta >= tm && theta <= tM) && (phi >= pm && phi <= pM ) ) + ModuleNumber = index ; + index++ ; } - else { - fgInit = kFALSE ; - cout << "PHOS Geometry setup: option not defined " << fName << endl ; - } -} - -//____________________________________________________________________________ -void AliPHOSGeometry::InitPHOS(void) -{ - // Initializes the EMC parameters - - fNPhi = 64 ; - fNZ = 64 ; - fNModules = 5 ; - - fPHOSAngle = new Float_t[fNModules] ; - Int_t index ; - for ( index = 0; index < fNModules; index++ ) - fPHOSAngle[index] = 0.0 ; // Module position angles are set in CreateGeometry() - - fXtlSize[0] = 2.2 ; - fXtlSize[1] = 18.0 ; - fXtlSize[2] = 2.2 ; - - // all these numbers coming next are subject to changes - - fOuterBoxThickness[0] = 2.8 ; - fOuterBoxThickness[1] = 5.0 ; - fOuterBoxThickness[2] = 5.0 ; - - fUpperPlateThickness = 4.0 ; - - fSecondUpperPlateThickness = 5.0 ; - - fCrystalSupportHeight = 6.95 ; - fCrystalWrapThickness = 0.01 ; - fCrystalHolderThickness = 0.005 ; - fModuleBoxThickness = 2.0 ; - fIPtoOuterCoverDistance = 447.0 ; - fIPtoCrystalSurface = 460.0 ; - - fPinDiodeSize[0] = 1.71 ; //Values given by Odd Harald feb 2000 - fPinDiodeSize[1] = 0.0280 ; // 0.0280 is the depth of active layer in the silicon - fPinDiodeSize[2] = 1.61 ; - - fUpperCoolingPlateThickness = 0.06 ; - fSupportPlateThickness = 10.0 ; - fLowerThermoPlateThickness = 3.0 ; - fLowerTextolitPlateThickness = 1.0 ; - fGapBetweenCrystals = 0.03 ; - - fTextolitBoxThickness[0] = 1.5 ; - fTextolitBoxThickness[1] = 0.0 ; - fTextolitBoxThickness[2] = 3.0 ; - - fAirThickness[0] = 1.56 ; - fAirThickness[1] = 20.5175 ; - fAirThickness[2] = 2.48 ; - - Float_t xtalModulePhiSize = fNPhi * ( fXtlSize[0] + 2 * fGapBetweenCrystals ) ; - Float_t xtalModuleZSize = fNZ * ( fXtlSize[2] + 2 * fGapBetweenCrystals ) ; - - // The next dimensions are calculated from the above parameters - - fOuterBoxSize[0] = xtalModulePhiSize + 2 * ( fAirThickness[0] + fModuleBoxThickness - + fTextolitBoxThickness[0] + fOuterBoxThickness[0] ) ; - fOuterBoxSize[1] = ( fXtlSize[1] + fCrystalSupportHeight + fCrystalWrapThickness + fCrystalHolderThickness ) - + 2 * (fAirThickness[1] + fModuleBoxThickness + fTextolitBoxThickness[1] + fOuterBoxThickness[1] ) ; - fOuterBoxSize[2] = xtalModuleZSize + 2 * ( fAirThickness[2] + fModuleBoxThickness - + fTextolitBoxThickness[2] + fOuterBoxThickness[2] ) ; - - fTextolitBoxSize[0] = fOuterBoxSize[0] - 2 * fOuterBoxThickness[0] ; - fTextolitBoxSize[1] = fOuterBoxSize[1] - fOuterBoxThickness[1] - fUpperPlateThickness ; - fTextolitBoxSize[2] = fOuterBoxSize[2] - 2 * fOuterBoxThickness[2] ; - - fAirFilledBoxSize[0] = fTextolitBoxSize[0] - 2 * fTextolitBoxThickness[0] ; - fAirFilledBoxSize[1] = fTextolitBoxSize[1] - fSecondUpperPlateThickness ; - fAirFilledBoxSize[2] = fTextolitBoxSize[2] - 2 * fTextolitBoxThickness[2] ; - -} - -//____________________________________________________________________________ -void AliPHOSGeometry::InitPPSD(void) -{ - // Initializes the PPSD parameters - - fAnodeThickness = 0.0009 ; - fAvalancheGap = 0.01 ; - fCathodeThickness = 0.0009 ; - fCompositeThickness = 0.3 ; - fConversionGap = 0.6 ; - fLeadConverterThickness = 0.56 ; - fLeadToMicro2Gap = 0.1 ; - fLidThickness = 0.2 ; - fMicro1ToLeadGap = 0.1 ; - fMicromegasWallThickness = 0.6 ; - fNumberOfModulesPhi = 4 ; - fNumberOfModulesZ = 4 ; - fNumberOfPadsPhi = 24 ; - fNumberOfPadsZ = 24 ; - fPCThickness = 0.1 ; - fPhiDisplacement = 0.8 ; - fZDisplacement = 0.8 ; - - fMicromegas1Thickness = fLidThickness + 2 * fCompositeThickness + fCathodeThickness + fPCThickness - + fAnodeThickness + fConversionGap + fAvalancheGap ; - fMicromegas2Thickness = fMicromegas1Thickness ; - - - fPPSDModuleSize[0] = 38.0 ; - fPPSDModuleSize[1] = fMicromegas1Thickness ; - fPPSDModuleSize[2] = 38.0 ; - - fPPSDBoxSize[0] = fNumberOfModulesPhi * fPPSDModuleSize[0] + 2 * fPhiDisplacement ; - fPPSDBoxSize[1] = fMicromegas2Thickness + fMicromegas2Thickness + fLeadConverterThickness + fMicro1ToLeadGap + fLeadToMicro2Gap ; - fPPSDBoxSize[2] = fNumberOfModulesZ * fPPSDModuleSize[2] + 2 * fZDisplacement ; - - fIPtoTopLidDistance = fIPtoOuterCoverDistance - fPPSDBoxSize[1] - 1. ; - -} - -//____________________________________________________________________________ -AliPHOSGeometry * AliPHOSGeometry::GetInstance() -{ - // Returns the pointer of the unique instance - return (AliPHOSGeometry *) fgGeom ; -} - -//____________________________________________________________________________ -AliPHOSGeometry * AliPHOSGeometry::GetInstance(const Text_t* name, const Text_t* title) -{ - // Returns the pointer of the unique instance - AliPHOSGeometry * rv = 0 ; - if ( fgGeom == 0 ) { - if ( strcmp(name,"") == 0 ) - rv = 0 ; - else { - fgGeom = new AliPHOSGeometry(name, title) ; - if ( fgInit ) - rv = (AliPHOSGeometry * ) fgGeom ; - else { - rv = 0 ; - delete fgGeom ; - fgGeom = 0 ; - } - } + if ( ModuleNumber != 0 ) { + Float_t phi0 = GetPHOSAngle(ModuleNumber) * (TMath::Pi() / 180.) + 1.5 * TMath::Pi() ; + Float_t y0 = GetIPtoOuterCoverDistance() + GetUpperPlateThickness() + + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness() ; + Double_t angle = phi - phi0; + x = y0 * TMath::Tan(angle) ; + angle = theta - TMath::Pi() / 2 ; + z = y0 * TMath::Tan(angle) ; } - else { - if ( strcmp(fgGeom->GetName(), name) != 0 ) { - cout << "AliPHOSGeometry : current geometry is " << fgGeom->GetName() << endl - << " you cannot call " << name << endl ; - } - else - rv = (AliPHOSGeometry *) fgGeom ; - } - return rv ; } //____________________________________________________________________________ Bool_t AliPHOSGeometry::RelToAbsNumbering(const Int_t * relid, Int_t & AbsId) { // Converts the relative numbering into the absolute numbering - // AbsId = 1:fNModules * fNPhi * fNZ -> PbWO4 - // AbsId = 1:fNModules * 2 * (fNumberOfModulesPhi * fNumberOfModulesZ) * fNumberOfPadsPhi * fNumberOfPadsZ -> PPSD + // EMCA crystals: + // AbsId = from 1 to fNModules * fNPhi * fNZ + // PPSD gas cell: + // AbsId = from N(total EMCA crystals) + 1 + // to NCPVModules * fNumberOfCPVPadsPhi * fNumberOfCPVPadsZ + + // fNModules * 2 * (fNumberOfModulesPhi * fNumberOfModulesZ) * fNumberOfPadsPhi * fNumberOfPadsZ + // CPV pad: + // AbsId = from N(total PHOS crystals) + 1 + // to NCPVModules * fNumberOfCPVPadsPhi * fNumberOfCPVPadsZ Bool_t rv = kTRUE ; - if ( relid[1] > 0 ) { // its a PPSD pad + if ( relid[1] > 0 && strcmp(fName,"GPS2")==0) { // it is a PPSD pad + AbsId = GetNPhi() * GetNZ() * GetNModules() // the offset to separate EMCA crystals from PPSD pads + + ( relid[0] - 1 ) * GetNumberOfModulesPhi() * GetNumberOfModulesZ() // the pads offset of PPSD modules + * GetNumberOfPadsPhi() * GetNumberOfPadsZ() * 2 + + ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() // the pads offset of PPSD modules + + ( relid[2] - 1 ) * GetNumberOfPadsPhi() // the pads offset of a PPSD row + + relid[3] ; // the column number + } - AbsId = GetNPhi() * GetNZ() * GetNModules() // the offset to separate emcal crystals from PPSD pads - + ( relid[0] - 1 ) * GetNumberOfModulesPhi() * GetNumberOfModulesZ() // the pads offset of PHOS modules + else if ( relid[1] > 0 && strcmp(fName,"MIXT")==0) { // it is a PPSD pad + AbsId = GetNPhi() * GetNZ() * GetNModules() // the offset to separate EMCA crystals from PPSD pads + + GetNCPVModules() * GetNumberOfCPVPadsPhi() * GetNumberOfCPVPadsZ() // the pads offset of CPV modules if any + + ( relid[0] - 1 - GetNCPVModules()) + * GetNumberOfModulesPhi() * GetNumberOfModulesZ() // the pads offset of PPSD modules * GetNumberOfPadsPhi() * GetNumberOfPadsZ() * 2 - + ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() // the pads offset of PPSD modules - + ( relid[2] - 1 ) * GetNumberOfPadsPhi() // the pads offset of a PPSD row - + relid[3] ; // the column number + + ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() // the pads offset of PPSD modules + + ( relid[2] - 1 ) * GetNumberOfPadsPhi() // the pads offset of a PPSD row + + relid[3] ; // the column number } - else { - if ( relid[1] == 0 ) { // its a Phos crystal - AbsId = ( relid[0] - 1 ) * GetNPhi() * GetNZ() // the offset of PHOS modules - + ( relid[2] - 1 ) * GetNPhi() // the offset of a xtal row - + relid[3] ; // the column number - } + + else if ( relid[1] == 0 ) { // it is a Phos crystal + AbsId = + ( relid[0] - 1 ) * GetNPhi() * GetNZ() // the offset of PHOS modules + + ( relid[2] - 1 ) * GetNPhi() // the offset of a xtal row + + relid[3] ; // the column number } + else if ( relid[1] == -1 ) { // it is a CPV pad + AbsId = GetNPhi() * GetNZ() * GetNModules() // the offset to separate EMCA crystals from CPV pads + + ( relid[0] - 1 ) * GetNumberOfCPVPadsPhi() * GetNumberOfCPVPadsZ() // the pads offset of PHOS modules + + ( relid[2] - 1 ) * GetNumberOfCPVPadsZ() // the pads offset of a CPV row + + relid[3] ; // the column number + } + return rv ; } @@ -455,110 +479,111 @@ Bool_t AliPHOSGeometry::RelToAbsNumbering(const Int_t * relid, Int_t & AbsId) void AliPHOSGeometry::RelPosInAlice(const Int_t id, TVector3 & pos ) { - // Converts the absolute numbering into the global ALICE coordinates - - if (id > 0) { - - Int_t relid[4] ; - - AbsToRelNumbering(id , relid) ; - - Int_t phosmodule = relid[0] ; - - Float_t y0 = 0 ; - - if ( relid[1] == 0 ) // it is a PbW04 crystal - { y0 = -(GetIPtoOuterCoverDistance() + GetUpperPlateThickness() - + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()) ; - } - if ( relid[1] > 0 ) { // its a PPSD pad - if ( relid[1] > GetNumberOfModulesPhi() * GetNumberOfModulesZ() ) // its an bottom module - { - y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() / 2.0) ; - } - else // its an upper module - y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() - GetLeadToMicro2Gap() - - GetLeadConverterThickness() - GetMicro1ToLeadGap() - GetMicromegas1Thickness() / 2.0) ; - } - - Float_t x, z ; - RelPosInModule(relid, x, z) ; - - pos.SetX(x) ; - pos.SetZ(z) ; - pos.SetY( TMath::Sqrt(x*x + z*z + y0*y0) ) ; - - - - Float_t phi = GetPHOSAngle( phosmodule) ; - Double_t const kRADDEG = 180.0 / kPI ; - Float_t rphi = phi / kRADDEG ; - - TRotation rot ; - rot.RotateZ(-rphi) ; // a rotation around Z by angle - - TRotation dummy = rot.Invert() ; // to transform from original frame to rotate frame + // Converts the absolute numbering into the global ALICE coordinate system + // It works only for the GPS2 geometry - pos.Transform(rot) ; // rotate the baby + if (id > 0 && strcmp(fName,"GPS2")==0) { + + Int_t relid[4] ; + + AbsToRelNumbering(id , relid) ; + + Int_t phosmodule = relid[0] ; + + Float_t y0 = 0 ; + + if ( relid[1] == 0 ) { // it is a PbW04 crystal + y0 = -(GetIPtoOuterCoverDistance() + GetUpperPlateThickness() + + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()) ; + } + if ( relid[1] > 0 ) { // its a PPSD pad + if ( relid[1] > GetNumberOfModulesPhi() * GetNumberOfModulesZ() ) { // its an bottom module + y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() / 2.0) ; + } + else // its an upper module + y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() - GetLeadToMicro2Gap() + - GetLeadConverterThickness() - GetMicro1ToLeadGap() - GetMicromegas1Thickness() / 2.0) ; + } + + Float_t x, z ; + RelPosInModule(relid, x, z) ; + + pos.SetX(x) ; + pos.SetZ(z) ; + pos.SetY( TMath::Sqrt(x*x + z*z + y0*y0) ) ; + + + + Float_t phi = GetPHOSAngle( phosmodule) ; + Double_t const kRADDEG = 180.0 / kPI ; + Float_t rphi = phi / kRADDEG ; + + TRotation rot ; + rot.RotateZ(-rphi) ; // a rotation around Z by angle + + TRotation dummy = rot.Invert() ; // to transform from original frame to rotate frame + + pos.Transform(rot) ; // rotate the baby } else { - pos.SetX(0.); - pos.SetY(0.); - pos.SetZ(0.); - } + pos.SetX(0.); + pos.SetY(0.); + pos.SetZ(0.); + } } //____________________________________________________________________________ void AliPHOSGeometry::RelPosInModule(const Int_t * relid, Float_t & x, Float_t & z) { // Converts the relative numbering into the local PHOS-module (x, z) coordinates - - Int_t ppsdmodule ; - Int_t row = relid[2] ; //offset along z axiz - Int_t column = relid[3] ; //offset along x axiz + // Note: sign of z differs from that in the previous version (Yu.Kharlov, 12 Oct 2000) - Float_t padsizeZ = GetPPSDModuleSize(2)/ GetNumberOfPadsZ(); - Float_t padsizeX = GetPPSDModuleSize(0)/ GetNumberOfPadsPhi(); - - if ( relid[1] == 0 ) { // its a PbW04 crystal - x = -( GetNPhi()/2. - row + 0.5 ) * GetCrystalSize(0) ; // position ox Xtal with respect - z = ( GetNZ() /2. - column + 0.5 ) * GetCrystalSize(2) ; // of center of PHOS module - } - else { - if ( relid[1] > GetNumberOfModulesPhi() * GetNumberOfModulesZ() ) - ppsdmodule = relid[1]-GetNumberOfModulesPhi() * GetNumberOfModulesZ(); - else ppsdmodule = relid[1] ; - Int_t modrow = 1+(Int_t)TMath::Ceil( (Float_t)ppsdmodule / GetNumberOfModulesPhi()-1. ) ; - Int_t modcol = ppsdmodule - ( modrow - 1 ) * GetNumberOfModulesPhi() ; - Float_t x0 = ( GetNumberOfModulesPhi() / 2. - modrow + 0.5 ) * GetPPSDModuleSize(0) ; - Float_t z0 = ( GetNumberOfModulesZ() / 2. - modcol + 0.5 ) * GetPPSDModuleSize(2) ; - x = - ( GetNumberOfPadsPhi()/2. - row - 0.5 ) * padsizeX + x0 ; // position of pad with respect - z = ( GetNumberOfPadsZ()/2. - column - 0.5 ) * padsizeZ - z0 ; // of center of PHOS module - } -} - -//____________________________________________________________________________ -void AliPHOSGeometry::SetPHOSAngles() -{ - // Calculates the position in ALICE of the PHOS modules - - Double_t const kRADDEG = 180.0 / kPI ; - Float_t pphi = TMath::ATan( fOuterBoxSize[0] / ( 2.0 * fIPtoOuterCoverDistance ) ) ; - pphi *= kRADDEG ; + Bool_t padOfCPV = (strcmp(fName,"IHEP")==0) || + ((strcmp(fName,"MIXT")==0) && relid[0]<=GetNCPVModules()) ; + Bool_t padOfPPSD = (strcmp(fName,"GPS2")==0) || + ((strcmp(fName,"MIXT")==0) && relid[0]> GetNCPVModules()) ; - for( Int_t i = 1; i <= fNModules ; i++ ) { - Float_t angle = pphi * 2 * ( i - fNModules / 2.0 - 0.5 ) ; - fPHOSAngle[i-1] = - angle ; - } -} - -//____________________________________________________________________________ -void AliPHOSGeometry::SetLeadConverterThickness(Float_t e) -{ - // should ultimately disappear + Int_t ppsdmodule ; + Float_t x0,z0; + Int_t row = relid[2] ; //offset along x axiz + Int_t column = relid[3] ; //offset along z axiz + + Float_t padsizeZ = 0; + Float_t padsizeX = 0; + Int_t nOfPadsPhi = 0; + Int_t nOfPadsZ = 0; + if ( padOfPPSD ) { + padsizeZ = GetPPSDModuleSize(2) / GetNumberOfPadsZ(); + padsizeX = GetPPSDModuleSize(0) / GetNumberOfPadsPhi(); + nOfPadsPhi = GetNumberOfPadsPhi(); + nOfPadsZ = GetNumberOfPadsZ(); + } + else if ( padOfCPV ) { + padsizeZ = GetPadSizeZ(); + padsizeX = GetPadSizePhi(); + nOfPadsPhi = GetNumberOfCPVPadsPhi(); + nOfPadsZ = GetNumberOfCPVPadsZ(); + } - cout << " AliPHOSGeometry WARNING : You have changed LeadConverterThickness from " - << fLeadConverterThickness << " to " << e << endl ; - - fLeadConverterThickness = e ; + if ( relid[1] == 0 ) { // its a PbW04 crystal + x = - ( GetNPhi()/2. - row + 0.5 ) * GetCrystalSize(0) ; // position ox Xtal with respect + z = ( GetNZ() /2. - column + 0.5 ) * GetCrystalSize(2) ; // of center of PHOS module + } + else { + if ( padOfPPSD ) { + if ( relid[1] > GetNumberOfModulesPhi() * GetNumberOfModulesZ() ) + ppsdmodule = relid[1]-GetNumberOfModulesPhi() * GetNumberOfModulesZ(); + else + ppsdmodule = relid[1] ; + Int_t modrow = 1+(Int_t)TMath::Ceil( (Float_t)ppsdmodule / GetNumberOfModulesPhi()-1. ) ; + Int_t modcol = ppsdmodule - ( modrow - 1 ) * GetNumberOfModulesPhi() ; + x0 = ( GetNumberOfModulesPhi() / 2. - modrow + 0.5 ) * GetPPSDModuleSize(0) ; + z0 = ( GetNumberOfModulesZ() / 2. - modcol + 0.5 ) * GetPPSDModuleSize(2) ; + } else { + x0 = 0; + z0 = 0; + } + x = - ( nOfPadsPhi/2. - row - 0.5 ) * padsizeX + x0 ; // position of pad with respect + z = ( nOfPadsZ /2. - column - 0.5 ) * padsizeZ - z0 ; // of center of PHOS module + } }