LCOV - code coverage report
Current view: top level - PHOS/PHOSbase - AliPHOSGeometry.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 85 146 58.2 %
Date: 2016-06-14 17:26:59 Functions: 8 17 47.1 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       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             :  **************************************************************************/
      15             : 
      16             : /* $Id$ */
      17             : 
      18             : //_________________________________________________________________________
      19             : // Geometry class  for PHOS : singleton  
      20             : // PHOS consists of the electromagnetic calorimeter (EMCA)
      21             : // and a charged particle veto either in the Subatech's version (PPSD)
      22             : // or in the IHEP's one (CPV).
      23             : // The EMCA/PPSD/CPV modules are parametrized so that any configuration
      24             : // can be easily implemented 
      25             : // The title is used to identify the version of CPV used.
      26             : //                  
      27             : // -- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC "KI" & SUBATECH)
      28             : 
      29             : // --- ROOT system ---
      30             : 
      31             : #include "TVector3.h"
      32             : #include "TRotation.h" 
      33             : #include "TParticle.h"
      34             : #include <TGeoManager.h>
      35             : #include <TGeoMatrix.h>
      36             : 
      37             : // --- Standard library ---
      38             : 
      39             : // --- AliRoot header files ---
      40             : #include "AliLog.h"
      41             : #include "AliPHOSGeometry.h"
      42             : #include "AliPHOSEMCAGeometry.h" 
      43             : #include "AliPHOSRecPoint.h"
      44             : 
      45          22 : ClassImp(AliPHOSGeometry)
      46             : 
      47             : // these initialisations are needed for a singleton
      48             : AliPHOSGeometry  * AliPHOSGeometry::fgGeom = 0 ;
      49             : Bool_t             AliPHOSGeometry::fgInit = kFALSE ;
      50             : 
      51             : //____________________________________________________________________________
      52             : AliPHOSGeometry::AliPHOSGeometry() : 
      53           0 :                     AliPHOSGeoUtils(),
      54           0 :                     fAngle(0.f),
      55           0 :                     fPHOSAngle(0),
      56           0 :                     fIPtoUpperCPVsurface(0),
      57           0 :                     fCrystalShift(0),
      58           0 :                     fCryCellShift(0),
      59           0 :                     fRotMatrixArray(0)
      60           0 : {
      61             :     // default ctor 
      62             :     // must be kept public for root persistency purposes, but should never be called by the outside world
      63           0 :     fgGeom          = 0 ;
      64             : 
      65           0 :     fPHOSParams[0] = 0.;
      66           0 :     fPHOSParams[1] = 0.;
      67           0 :     fPHOSParams[2] = 0.;
      68           0 :     fPHOSParams[3] = 0.;
      69           0 : }  
      70             : 
      71             : //____________________________________________________________________________
      72             : AliPHOSGeometry::AliPHOSGeometry(const AliPHOSGeometry & rhs)
      73           0 :                     : AliPHOSGeoUtils(rhs),
      74           0 :                       fAngle(rhs.fAngle),
      75           0 :                       fPHOSAngle(0),
      76           0 :                       fIPtoUpperCPVsurface(rhs.fIPtoUpperCPVsurface),
      77           0 :                       fCrystalShift(rhs.fCrystalShift),
      78           0 :                       fCryCellShift(rhs.fCryCellShift),
      79           0 :                       fRotMatrixArray(0)
      80           0 : {
      81           0 :   Fatal("cpy ctor", "not implemented") ; 
      82           0 : }
      83             : 
      84             : //____________________________________________________________________________
      85             : AliPHOSGeometry::AliPHOSGeometry(const Text_t* name, const Text_t* title) 
      86           3 :                   : AliPHOSGeoUtils(name, title),
      87           3 :                     fAngle(0.f),
      88           3 :                     fPHOSAngle(0),
      89           3 :                     fIPtoUpperCPVsurface(0),
      90           3 :                     fCrystalShift(0),
      91           3 :                     fCryCellShift(0),
      92           3 :                     fRotMatrixArray(0)
      93          15 : { 
      94             :   // ctor only for internal usage (singleton)
      95           3 :   Init() ; 
      96           3 :   fgGeom = this;
      97           6 : }
      98             : 
      99             : //____________________________________________________________________________
     100             : AliPHOSGeometry::~AliPHOSGeometry(void)
     101           0 : {
     102             :   // dtor
     103             : 
     104           0 :   if (fRotMatrixArray) fRotMatrixArray->Delete() ; 
     105           0 :   if (fRotMatrixArray) delete fRotMatrixArray ; 
     106           0 :   if (fPHOSAngle     ) delete[] fPHOSAngle ; 
     107           0 : }
     108             : 
     109             : //____________________________________________________________________________
     110             : void AliPHOSGeometry::Init(void)
     111             : {
     112             :   // Initializes the PHOS parameters :
     113             :   //  IHEP is the Protvino CPV (cathode pad chambers)
     114             :   
     115           6 :   fgInit     = kTRUE ; 
     116             : 
     117           3 :   fAngle        = 20;
     118             : 
     119             :   
     120           3 :   fPHOSAngle = new Float_t[fNModules] ;
     121             :   
     122           3 :   const Float_t * emcParams = fGeometryEMCA->GetEMCParams() ;
     123             :   
     124           6 :   fPHOSParams[0] =  TMath::Max((Double_t)fGeometryCPV->GetCPVBoxSize(0)/2., 
     125           9 :                                (Double_t)(emcParams[0] - (emcParams[1]-emcParams[0])*
     126           6 :                                           fGeometryCPV->GetCPVBoxSize(1)/2/emcParams[3]));
     127           3 :   fPHOSParams[1] = emcParams[1] ;
     128           3 :   fPHOSParams[2] = TMath::Max((Double_t)emcParams[2], (Double_t)fGeometryCPV->GetCPVBoxSize(2)/2.);
     129           3 :   fPHOSParams[3] = emcParams[3] + fGeometryCPV->GetCPVBoxSize(1)/2. ;
     130             :   
     131           3 :   fIPtoUpperCPVsurface = fGeometryEMCA->GetIPtoOuterCoverDistance() - fGeometryCPV->GetCPVBoxSize(1) ;
     132             : 
     133             :   //calculate offset to crystal surface
     134           3 :   const Float_t * inthermo = fGeometryEMCA->GetInnerThermoHalfSize() ;
     135           3 :   const Float_t * strip = fGeometryEMCA->GetStripHalfSize() ;
     136           3 :   const Float_t * splate = fGeometryEMCA->GetSupportPlateHalfSize();
     137           3 :   const Float_t * crystal = fGeometryEMCA->GetCrystalHalfSize() ;
     138           3 :   const Float_t * pin = fGeometryEMCA->GetAPDHalfSize() ;
     139           3 :   const Float_t * preamp = fGeometryEMCA->GetPreampHalfSize() ;
     140           3 :   fCrystalShift=-inthermo[1]+strip[1]+splate[1]+crystal[1]-fGeometryEMCA->GetAirGapLed()/2.+pin[1]+preamp[1] ;
     141           3 :   fCryCellShift=crystal[1]-(fGeometryEMCA->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
     142             :  
     143             :   Int_t index ;
     144          36 :   for ( index = 0; index < fNModules; index++ )
     145          15 :     fPHOSAngle[index] = 0.0 ; // Module position angles are set in CreateGeometry()
     146             :   
     147           6 :   fRotMatrixArray = new TObjArray(fNModules) ; 
     148             : 
     149             :   // Geometry parameters are calculated
     150             : 
     151           3 :   SetPHOSAngles();
     152           3 :   Double_t const kRADDEG = 180.0 / TMath::Pi() ;
     153           3 :   Float_t r = GetIPtoOuterCoverDistance() + fPHOSParams[3] - GetCPVBoxSize(1) ;
     154          36 :   for (Int_t iModule=0; iModule<fNModules; iModule++) {
     155          15 :     fModuleCenter[iModule][0] = r * TMath::Sin(fPHOSAngle[iModule] / kRADDEG );
     156          15 :     fModuleCenter[iModule][1] =-r * TMath::Cos(fPHOSAngle[iModule] / kRADDEG );
     157          15 :     fModuleCenter[iModule][2] = 0.;
     158             :     
     159          15 :     fModuleAngle[iModule][0][0] =  90;
     160          15 :     fModuleAngle[iModule][0][1] =   fPHOSAngle[iModule];
     161          15 :     fModuleAngle[iModule][1][0] =   0;
     162          15 :     fModuleAngle[iModule][1][1] =   0;
     163          15 :     fModuleAngle[iModule][2][0] =  90;
     164          15 :     fModuleAngle[iModule][2][1] = 270 + fPHOSAngle[iModule];
     165             :   }
     166             : 
     167           3 : }
     168             : 
     169             : //____________________________________________________________________________
     170             : AliPHOSGeometry *  AliPHOSGeometry::GetInstance() 
     171             : { 
     172             :   // Returns the pointer of the unique instance; singleton specific
     173             :   
     174       91882 :   return static_cast<AliPHOSGeometry *>( fgGeom ) ; 
     175             : }
     176             : 
     177             : //____________________________________________________________________________
     178             : AliPHOSGeometry *  AliPHOSGeometry::GetInstance(const Text_t* name, const Text_t* title) 
     179             : {
     180             :   // Returns the pointer of the unique instance
     181             :   // Creates it with the specified options (name, title) if it does not exist yet
     182             : 
     183             :   AliPHOSGeometry * rv = 0  ; 
     184     4065774 :   if ( fgGeom == 0 ) {
     185           3 :     if ( strcmp(name,"") == 0 ) 
     186           0 :       rv = 0 ;
     187             :     else {    
     188           6 :       fgGeom = new AliPHOSGeometry(name, title) ;
     189           3 :       if ( fgInit )
     190           3 :         rv = (AliPHOSGeometry * ) fgGeom ;
     191             :       else {
     192             :         rv = 0 ; 
     193           0 :         delete fgGeom ; 
     194           0 :         fgGeom = 0 ; 
     195             :       }
     196             :     }
     197             :   }
     198             :   else {
     199     4065768 :     if ( strcmp(fgGeom->GetName(), name) != 0 ) 
     200           0 :       ::Error("GetInstance", "Current geometry is %s. You cannot call %s", 
     201     2032884 :                       fgGeom->GetName(), name) ; 
     202             :     else
     203             :       rv = (AliPHOSGeometry *) fgGeom ; 
     204             :   } 
     205     2032887 :   return rv ; 
     206           0 : }
     207             : 
     208             : //____________________________________________________________________________
     209             : void AliPHOSGeometry::SetPHOSAngles() 
     210             : { 
     211             :   // Calculates the position of the PHOS modules in ALICE global coordinate system
     212             :   // in ideal geometry
     213             :   
     214           6 :   Double_t const kRADDEG = 180.0 / TMath::Pi() ;
     215           3 :   Float_t pphi =  2 * TMath::ATan( GetOuterBoxSize(0)  / ( 2.0 * GetIPtoUpperCPVsurface() ) ) ;
     216           3 :   pphi *= kRADDEG ;
     217           3 :   if (pphi > fAngle){ 
     218           0 :     AliError(Form("PHOS modules overlap!\n pphi = %f fAngle = %f", 
     219             :                   pphi, fAngle));
     220             : 
     221           0 :   }
     222           3 :   pphi = fAngle;
     223             :   
     224          36 :   for( Int_t i = 1; i <= fNModules ; i++ ) {
     225          15 :     Float_t angle = pphi * ( i - fNModules / 2.0 - 0.5 ) ;
     226          15 :     fPHOSAngle[i-1] = -  angle ;
     227             :   } 
     228           3 : }
     229             : //____________________________________________________________________________
     230             : void AliPHOSGeometry::GetGlobal(const AliRecPoint* , TVector3 & ) const
     231             : {
     232           0 :   AliFatal(Form("Please use GetGlobalPHOS(recPoint,gpos) instead of GetGlobal!"));
     233           0 : }
     234             : 
     235             : //____________________________________________________________________________
     236             : void AliPHOSGeometry::GetGlobalPHOS(const AliPHOSRecPoint* recPoint, TVector3 & gpos) const
     237             : {
     238             :   // Calculates the coordinates of a RecPoint and the error matrix in the ALICE global coordinate system
     239             :  
     240             :   const AliPHOSRecPoint * tmpPHOS = recPoint ;  
     241          20 :   TVector3 localposition ;
     242             : 
     243          10 :   tmpPHOS->GetLocalPosition(gpos) ;
     244             : 
     245          10 :   if (!gGeoManager){
     246           0 :     AliFatal("Geo manager not initialized\n");
     247             :   }
     248             :   //construct module name
     249             :   TGeoHMatrix *m = 0x0;
     250          10 :   char path[100] ; 
     251             :   Double_t dy ;
     252          20 :   if(tmpPHOS->IsEmc()){
     253          30 :     snprintf(path,100,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",tmpPHOS->GetPHOSMod()) ;
     254          20 :     if (!gGeoManager->CheckPath(path)){
     255           0 :       snprintf(path,100,"/ALIC_1/PHOC_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",tmpPHOS->GetPHOSMod()) ;
     256           0 :       if (!gGeoManager->CheckPath(path)){
     257           0 :         snprintf(path,100,"/ALIC_1/PHOH_%d/PEMH_1/PCLH_1/PIOH_1/PCOH_1/PAGH_1/PTIH_1",tmpPHOS->GetPHOSMod()) ;
     258           0 :         if(!gGeoManager->CheckPath(path)){     
     259           0 :           AliFatal("Geo manager can not find path \n");
     260             :         }
     261             :       }
     262             :     }
     263          10 :     gGeoManager->cd(path) ;
     264          10 :     m = gGeoManager->GetCurrentMatrix();
     265          10 :     dy=fCrystalShift ;
     266          10 :   }
     267             :   else{
     268           0 :     snprintf(path,100,"/ALIC_1/PHOC_%d/PCPV_1",tmpPHOS->GetPHOSMod());
     269           0 :     if (!gGeoManager->CheckPath(path)){
     270           0 :       snprintf(path,100,"/ALIC_1/PHOH_%d/PCPV_1",tmpPHOS->GetPHOSMod());
     271           0 :       if (!gGeoManager->CheckPath(path))
     272           0 :         AliFatal(Form("Geo manager can not find path /ALIC_1/PHOC(H)_%d/PCPV_1 \n",tmpPHOS->GetPHOSMod()));
     273             :     }
     274           0 :     gGeoManager->cd(path) ;
     275           0 :     m = gGeoManager->GetCurrentMatrix();
     276           0 :     dy= GetCPVBoxSize(1)/2. ; //center of CPV module 
     277             :   }
     278          10 :   Double_t pos[3]={gpos.X(),gpos.Y()-dy,gpos.Z()} ;
     279          20 :   if(tmpPHOS->IsEmc())
     280          10 :     pos[2]=-pos[2] ; //Opposite z directions in EMC matrix and local frame!!!
     281          10 :   Double_t posC[3] = {};
     282             :   //now apply possible shifts and rotations
     283          10 :   if (m){
     284          10 :      m->LocalToMaster(pos,posC);
     285             :   }
     286             :   else{
     287           0 :     AliFatal("Geo matrixes are not loaded \n") ;
     288             :   }
     289          10 :   gpos.SetXYZ(posC[0],posC[1],posC[2]) ;
     290             : 
     291          10 : }
     292             : //____________________________________________________________________________
     293             : 
     294             : void AliPHOSGeometry::GetModuleCenter(TVector3& center, 
     295             :                                       const char *det,
     296             :                                       Int_t module) const
     297             : {
     298             :   // Returns a position of the center of the CPV or EMC module
     299             :   // in ideal (not misaligned) geometry
     300             :   Float_t rDet = 0.;
     301           0 :   if      (strcmp(det,"CPV") == 0) rDet  = GetIPtoCPVDistance   ();
     302           0 :   else if (strcmp(det,"EMC") == 0) rDet  = GetIPtoCrystalSurface();
     303             :   else 
     304           0 :     AliFatal(Form("Wrong detector name %s",det));
     305             : 
     306           0 :   Float_t angle = GetPHOSAngle(module); // (40,20,0,-20,-40) degrees
     307           0 :   angle *= TMath::Pi()/180;
     308           0 :   angle += 3*TMath::Pi()/2.;
     309           0 :   center.SetXYZ(rDet*TMath::Cos(angle), rDet*TMath::Sin(angle), 0.);
     310           0 : }
     311             : 

Generated by: LCOV version 1.11