Library with PHOS geometry transformations for AliRoot-independent analysis
authorprsnko <prsnko@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Oct 2008 15:01:14 +0000 (15:01 +0000)
committerprsnko <prsnko@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Oct 2008 15:01:14 +0000 (15:01 +0000)
PHOS/AliPHOSGeoUtils.cxx [new file with mode: 0644]
PHOS/AliPHOSGeoUtils.h [new file with mode: 0644]
PHOS/PHOSUtilsLinkDef.h [new file with mode: 0644]
PHOS/PROOF-INF.PHOSUtils/BUILD.sh [new file with mode: 0755]
PHOS/PROOF-INF.PHOSUtils/SETUP.C [new file with mode: 0644]
PHOS/libPHOSUtils.pkg [new file with mode: 0644]

diff --git a/PHOS/AliPHOSGeoUtils.cxx b/PHOS/AliPHOSGeoUtils.cxx
new file mode 100644 (file)
index 0000000..7c59688
--- /dev/null
@@ -0,0 +1,541 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliPHOSGeometry.cxx 25590 2008-05-06 07:09:11Z prsnko $ */
+
+//_________________________________________________________________________
+// Geometry class  for PHOS : singleton  
+// 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) & Dmitri Peressounko (RRC "KI" & SUBATECH)
+
+// --- ROOT system ---
+
+#include "TVector3.h"
+#include "TParticle.h"
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+
+// --- Standard library ---
+
+// --- AliRoot header files ---
+#include "AliPHOSEMCAGeometry.h"
+#include "AliPHOSCPVGeometry.h"
+#include "AliPHOSGeoUtils.h"
+
+ClassImp(AliPHOSGeoUtils)
+
+//____________________________________________________________________________
+AliPHOSGeoUtils::AliPHOSGeoUtils():
+  fNModules(0),fNCristalsInModule(0),fNPhi(0),fNZ(0),
+  fNumberOfCPVPadsPhi(0),fNumberOfCPVPadsZ(0),
+  fNCellsXInStrip(0),fNCellsZInStrip(0),fNStripZ(0),
+  fCrystalShift(0.),fCryCellShift(0.),fCellStep(0.),
+  fPadSizePhi(0.),fPadSizeZ(0.),fCPVBoxSizeY(0.)
+{
+    // default ctor 
+    // must be kept public for root persistency purposes, but should never be called by the outside world
+}  
+
+//____________________________________________________________________________
+AliPHOSGeoUtils::AliPHOSGeoUtils(const AliPHOSGeoUtils & rhs)
+  : TNamed(rhs),
+  fNModules(0),fNCristalsInModule(0),fNPhi(0),fNZ(0),
+  fNumberOfCPVPadsPhi(0),fNumberOfCPVPadsZ(0),
+  fNCellsXInStrip(0),fNCellsZInStrip(0),fNStripZ(0),
+  fCrystalShift(0.),fCryCellShift(0.),fCellStep(0.),
+  fPadSizePhi(0.),fPadSizeZ(0.),fCPVBoxSizeY(0.)
+{
+  Fatal("cpy ctor", "not implemented") ; 
+}
+
+//____________________________________________________________________________
+AliPHOSGeoUtils::AliPHOSGeoUtils(const Text_t* name, const Text_t* title) 
+    : TNamed(name, title),
+  fNModules(0),fNCristalsInModule(0),fNPhi(0),fNZ(0),
+  fNumberOfCPVPadsPhi(0),fNumberOfCPVPadsZ(0),
+  fNCellsXInStrip(0),fNCellsZInStrip(0),fNStripZ(0),
+  fCrystalShift(0.),fCryCellShift(0.),fCellStep(0.),
+  fPadSizePhi(0.),fPadSizeZ(0.),fCPVBoxSizeY(0.)
+{ 
+  // ctor only for normal usage 
+  Init() ;
+}
+
+//____________________________________________________________________________
+AliPHOSGeoUtils & AliPHOSGeoUtils::operator = (const AliPHOSGeoUtils  & /*rvalue*/) { 
+    Init() ;
+    return *this ;
+}
+
+//____________________________________________________________________________
+AliPHOSGeoUtils::~AliPHOSGeoUtils(void)
+{
+  // dtor
+}
+//____________________________________________________________________________
+Bool_t AliPHOSGeoUtils::AbsToRelNumbering(Int_t absId, Int_t * relid) const
+{
+  // Converts the absolute numbering into the following array
+  //  relid[0] = PHOS Module number 1:fNModules 
+  //  relid[1] = 0 if PbW04
+  //           = -1 if CPV
+  //  relid[2] = Row number inside a PHOS module
+  //  relid[3] = Column number inside a PHOS module
+
+  Float_t id = absId ;
+
+  Int_t phosmodulenumber = (Int_t)TMath:: Ceil( id / fNCristalsInModule ) ; 
+  
+  if ( phosmodulenumber >  fNModules ) { // it is a CPV pad
+    
+    id -=  fNPhi * fNZ *  fNModules ; 
+    Float_t nCPV  = fNumberOfCPVPadsPhi * fNumberOfCPVPadsZ ;
+    relid[0] = (Int_t) TMath::Ceil( id / nCPV ) ;
+    relid[1] = -1 ;
+    id -= ( relid[0] - 1 ) * nCPV ; 
+    relid[2] = (Int_t) TMath::Ceil( id / fNumberOfCPVPadsZ ) ;
+    relid[3] = (Int_t) ( id - ( relid[2] - 1 ) * fNumberOfCPVPadsZ ) ; 
+  } 
+  else { // it is a PW04 crystal
+
+    relid[0] = phosmodulenumber ;
+    relid[1] = 0 ;
+    id -= ( phosmodulenumber - 1 ) *  fNPhi * fNZ ; 
+    relid[2] = (Int_t)TMath::Ceil( id / fNZ )  ;
+    relid[3] = (Int_t)( id - ( relid[2] - 1 ) * fNZ ) ; 
+  } 
+  return kTRUE ; 
+}
+//____________________________________________________________________________
+Bool_t AliPHOSGeoUtils::RelToAbsNumbering(const Int_t * relid, Int_t &  absId) const
+{
+  // Converts the relative numbering into the absolute numbering
+  // EMCA crystals:
+  //  absId = from 1 to fNModules * fNPhi * fNZ
+  // CPV pad:
+  //  absId = from N(total PHOS crystals) + 1
+  //          to NCPVModules * fNumberOfCPVPadsPhi * fNumberOfCPVPadsZ
+
+  if ( relid[1] ==  0 ) {                            // it is a Phos crystal
+    absId =
+      ( relid[0] - 1 ) * fNPhi * fNZ         // the offset of PHOS modules
+      + ( relid[2] - 1 ) * fNZ                   // the offset along phi
+      +   relid[3] ;                                 // the offset along z
+  }
+  else { // it is a CPV pad
+    absId =    fNPhi * fNZ *  fNModules         // the offset to separate EMCA crystals from CPV pads
+      + ( relid[0] - 1 ) * fNumberOfCPVPadsPhi * fNumberOfCPVPadsZ   // the pads offset of PHOS modules 
+      + ( relid[2] - 1 ) * fNumberOfCPVPadsZ                            // the pads offset of a CPV row
+      +   relid[3] ;                                                         // the column number
+  }
+  
+  return kTRUE ; 
+}
+
+//____________________________________________________________________________
+void AliPHOSGeoUtils::RelPosInModule(const Int_t * relid, Float_t & x, Float_t & z) const 
+{
+  // Converts the relative numbering into the local PHOS-module (x, z) coordinates
+
+  if (!gGeoManager){
+    printf("Geo manager not initialized\n");
+    abort() ;
+  }
+  //construct module name
+  char path[100] ;
+  if(relid[1]==0){ //this is PHOS
+
+    Double_t pos[3]= {0.0,-fCryCellShift,0.}; //Position incide the crystal 
+    Double_t posC[3]={0.0,0.0,0.}; //Global position
+
+    //Shift and possibly apply misalignment corrections
+    Int_t strip=1+((Int_t) TMath::Ceil((Double_t)relid[2]/fNCellsXInStrip))*fNStripZ-
+                (Int_t) TMath::Ceil((Double_t)relid[3]/fNCellsZInStrip) ;
+    Int_t cellraw= relid[3]%fNCellsZInStrip ;
+    if(cellraw==0)cellraw=fNCellsZInStrip ;
+    Int_t cell= ((relid[2]-1)%fNCellsXInStrip)*fNCellsZInStrip + cellraw ; 
+    sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_%d/PCEL_%d",
+            relid[0],strip,cell) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort() ;
+    }
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    if (m) m->LocalToMaster(pos,posC);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    //Return to PHOS local system  
+    Double_t posL[3]={posC[0],posC[1],posC[2]};
+    sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",relid[0]) ;
+    //    sprintf(path,"/ALIC_1/PHOS_%d",relid[0]) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort();
+    }
+    TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+    if (mPHOS) mPHOS->MasterToLocal(posC,posL);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    x=posL[0] ;
+    z=-posL[2];
+    return ;
+  }
+  else{//CPV
+    //first calculate position with respect to CPV plain 
+    Int_t row        = relid[2] ; //offset along x axis
+    Int_t column     = relid[3] ; //offset along z axis
+    Double_t pos[3]= {0.0,0.0,0.}; //Position incide the CPV printed circuit
+    Double_t posC[3]={0.0,0.0,0.}; //Global position
+    pos[0] = - ( fNumberOfCPVPadsPhi/2. - row    - 0.5 ) * fPadSizePhi  ; // position of pad  with respect
+    pos[2] = - ( fNumberOfCPVPadsZ  /2. - column - 0.5 ) * fPadSizeZ  ; // of center of PHOS module
+
+    //now apply possible shifts and rotations
+    sprintf(path,"/ALIC_1/PHOS_%d/PCPV_1",relid[0]) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort() ;
+    }
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    if (m) m->LocalToMaster(pos,posC);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    //Return to PHOS local system
+    Double_t posL[3]={0.,0.,0.,} ;
+    sprintf(path,"/ALIC_1/PHOS_%d",relid[0]) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort() ;
+    }
+    TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+    if (mPHOS) mPHOS->MasterToLocal(posC,posL);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    x=posL[0] ;
+    z=posL[1];
+    return ;
+  }
+  
+}
+//____________________________________________________________________________
+void AliPHOSGeoUtils::RelPosToAbsId(Int_t module, Double_t x, Double_t z, Int_t & absId) const
+{
+  // converts local PHOS-module (x, z) coordinates to absId 
+
+  //find Global position
+  if (!gGeoManager){
+    printf("Geo manager not initialized\n");
+    abort() ;
+  }
+  Double_t posL[3]={x,-fCrystalShift,-z} ; //Only for EMC!!!
+  Double_t posG[3] ;
+  char path[100] ;
+  sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",module) ;
+  if (!gGeoManager->cd(path)){
+    printf("Geo manager can not find path \n");
+    abort() ;
+  }
+  TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+  if (mPHOS){
+     mPHOS->LocalToMaster(posL,posG);
+  }
+  else{
+    printf("Geo matrixes are not loaded \n") ;
+    abort() ;
+  }
+
+  Int_t relid[4] ;
+  gGeoManager->FindNode(posG[0],posG[1],posG[2]) ;
+  //Check that path contains PSTR and extract strip number
+  TString cpath(gGeoManager->GetPath()) ;
+  Int_t indx = cpath.Index("PCEL") ;
+  if(indx==-1){ //for the few events when particle hits between srips use ideal geometry
+    relid[0] = module ;
+    relid[1] = 0 ;
+    relid[2] = static_cast<Int_t>(TMath::Ceil( x/ fCellStep + fNPhi / 2.) );
+    relid[3] = static_cast<Int_t>(TMath::Ceil(-z/ fCellStep + fNZ   / 2.) ) ;
+    if(relid[2]<1)relid[2]=1 ;
+    if(relid[3]<1)relid[3]=1 ;
+    if(relid[2]>fNPhi)relid[2]=fNPhi ;
+    if(relid[3]>fNZ)relid[3]=fNZ ;
+    RelToAbsNumbering(relid,absId) ;
+  }
+  else{
+    Int_t indx2 = cpath.Index("/",indx) ;
+    if(indx2==-1)
+      indx2=cpath.Length() ;
+    TString cell=cpath(indx+5,indx2-indx-5) ;
+    Int_t icell=cell.Atoi() ;
+    indx = cpath.Index("PSTR") ;
+    indx2 = cpath.Index("/",indx) ;
+    TString strip=cpath(indx+5,indx2-indx-5) ;
+    Int_t iStrip = strip.Atoi() ; 
+
+    Int_t row = fNStripZ - (iStrip - 1) % (fNStripZ) ;
+    Int_t col = (Int_t) TMath::Ceil((Double_t) iStrip/(fNStripZ)) -1 ;
+    // Absid for 8x2-strips. Looks nice :)
+    absId = (module-1)*fNCristalsInModule +
+                  row * 2 + (col*fNCellsXInStrip + (icell - 1) / 2)*fNZ - (icell & 1 ? 1 : 0);
+  }
+}
+
+//____________________________________________________________________________
+void AliPHOSGeoUtils::RelPosToRelId(Int_t module, Double_t x, Double_t z, Int_t * relId) const
+{
+  //Evaluates RelId of the crystall with given coordinates
+
+  Int_t absId ;
+  RelPosToAbsId(module, x,z,absId) ;
+  AbsToRelNumbering(absId,relId) ;
+}
+
+//____________________________________________________________________________
+void AliPHOSGeoUtils::RelPosInAlice(Int_t id, TVector3 & pos ) const
+{
+  // Converts the absolute numbering into the global ALICE coordinate system
+  
+  if (!gGeoManager){
+    printf("Geo manager not initialized\n");
+    abort();
+  }
+    
+  Int_t relid[4] ;
+    
+  AbsToRelNumbering(id , relid) ;
+    
+  //construct module name
+  char path[100] ;
+  if(relid[1]==0){ //this is EMC
+    Double_t ps[3]= {0.0,-fCryCellShift,0.}; //Position incide the crystal 
+    Double_t psC[3]={0.0,0.0,0.}; //Global position
+    //Shift and possibly apply misalignment corrections
+    Int_t strip=1+((Int_t) TMath::Ceil((Double_t)relid[2]/fNCellsXInStrip))*fNStripZ-
+                (Int_t) TMath::Ceil((Double_t)relid[3]/fNCellsZInStrip) ;
+    Int_t cellraw= relid[3]%fNCellsZInStrip ;
+    if(cellraw==0)cellraw=fNCellsZInStrip ;
+    Int_t cell= ((relid[2]-1)%fNCellsXInStrip)*fNCellsZInStrip + cellraw ;
+    sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_%d/PCEL_%d",
+            relid[0],strip,cell) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort() ;
+    }
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    if (m) m->LocalToMaster(ps,psC);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    pos.SetXYZ(psC[0],psC[1],psC[2]) ; 
+  }
+  else{
+    //first calculate position with respect to CPV plain
+    Int_t row        = relid[2] ; //offset along x axis
+    Int_t column     = relid[3] ; //offset along z axis
+    Double_t ps[3]= {0.0,fCPVBoxSizeY/2.,0.}; //Position on top of CPV
+    Double_t psC[3]={0.0,0.0,0.}; //Global position
+    pos[0] = - ( fNumberOfCPVPadsPhi/2. - row    - 0.5 ) * fPadSizePhi  ; // position of pad  with respect
+    pos[2] = - ( fNumberOfCPVPadsZ  /2. - column - 0.5 ) * fPadSizeZ  ; // of center of PHOS module
+    //now apply possible shifts and rotations
+    sprintf(path,"/ALIC_1/PHOS_%d/PCPV_1",relid[0]) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort();
+    }
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    if (m) m->LocalToMaster(ps,psC);
+    else{
+      printf("Geo matrixes are not loaded \n") ;
+      abort() ;
+    }
+    pos.SetXYZ(psC[0],psC[1],-psC[2]) ; 
+  }
+} 
+
+//____________________________________________________________________________
+void AliPHOSGeoUtils::Local2Global(Int_t mod, Float_t x, Float_t z,
+                                  TVector3& globalPosition) const 
+{
+  char path[100] ;
+  sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",mod) ;
+  if (!gGeoManager->cd(path)){
+    printf("Geo manager can not find path \n");
+    abort() ;
+  }
+  Double_t posL[3]={x,-fCrystalShift,-z} ; //Only for EMC!!!
+  Double_t posG[3] ;
+  TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+  if (mPHOS){
+     mPHOS->LocalToMaster(posL,posG);
+  }    
+  else{
+    printf("Geo matrixes are not loaded \n") ;
+    abort() ;
+  }
+  globalPosition.SetXYZ(posG[0],posG[1],posG[2]) ;
+}
+//____________________________________________________________________________
+void AliPHOSGeoUtils::Global2Local(TVector3& localPosition,
+                                  const TVector3& globalPosition,
+                                  Int_t module) const
+{
+  // Transforms a global position to the local coordinate system
+  // of the module 
+  //Return to PHOS local system
+  Double_t posG[3]={globalPosition.X(),globalPosition.Y(),globalPosition.Z()} ;
+  Double_t posL[3]={0.,0.,0.} ;
+  char path[100] ;
+  sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",module) ;
+  if (!gGeoManager->cd(path)){
+    printf("Geo manager can not find path \n");
+    abort() ;
+  }
+  TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+  if (mPHOS) mPHOS->MasterToLocal(posG,posL);
+  else{
+    printf("Geo matrixes are not loaded \n") ;
+    abort() ;
+  }
+  localPosition.SetXYZ(posL[0],posL[1]+fCrystalShift,-posL[2]) ;  
+}
+//____________________________________________________________________________
+Bool_t AliPHOSGeoUtils::ImpactOnEmc(const TParticle * particle,
+       Int_t & moduleNumber, Double_t & z, Double_t & x) const
+{
+  // Tells if a particle enters PHOS and evaluates hit position
+  Double_t vtx[3]={particle->Vx(),particle->Vy(),particle->Vz()} ;
+  return ImpactOnEmc(vtx,particle->Theta(),particle->Phi(),moduleNumber,z,x);
+}
+//____________________________________________________________________________
+Bool_t AliPHOSGeoUtils::ImpactOnEmc(const Double_t * vtx, Double_t theta, Double_t phi, 
+                                  Int_t & moduleNumber, Double_t & z, Double_t & x) const
+{
+  // calculates the impact coordinates on PHOS of a neutral particle  
+  // emitted in the vertex vtx[3] with direction vec(p) in the ALICE global coordinate system
+  TVector3 p(TMath::Sin(theta)*TMath::Cos(phi),TMath::Sin(theta)*TMath::Sin(phi),TMath::Cos(theta)) ;
+  return ImpactOnEmc(vtx,p,moduleNumber,z,x) ;
+
+}
+//____________________________________________________________________________
+Bool_t AliPHOSGeoUtils::ImpactOnEmc(const Double_t * vtx, const TVector3 &p,
+                                  Int_t & moduleNumber, Double_t & z, Double_t & x) const
+{
+  // calculates the impact coordinates on PHOS of a neutral particle  
+  // emitted in the vertex vtx[3] with direction theta and phi in the ALICE global coordinate system
+  TVector3 v(vtx[0],vtx[1],vtx[2]) ;
+
+  if (!gGeoManager){
+    printf("Geo manager not initialized\n");
+    abort() ;
+    return kFALSE ;
+  }
+  for(Int_t imod=1; imod<=fNModules ; imod++){
+    //create vector from (0,0,0) to center of crystal surface of imod module
+    Double_t tmp[3]={0.,-fCrystalShift,0.} ;
+    char path[100] ;
+    sprintf(path,"/ALIC_1/PHOS_%d/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1",imod) ;
+    if (!gGeoManager->cd(path)){
+      printf("Geo manager can not find path \n");
+      abort() ;
+      return kFALSE ;
+    }
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    Double_t posG[3]={0.,0.,0.} ;
+    if (m) m->LocalToMaster(tmp,posG);
+    TVector3 n(posG[0],posG[1],posG[2]) ; 
+    Double_t direction=n.Dot(p) ;
+    if(direction<=0.)
+      continue ; //momentum directed FROM module
+    Double_t fr = (n.Mag2()-n.Dot(v))/direction ;  
+    //Calculate direction in module plain
+    n-=v+fr*p ;
+    n*=-1. ;
+    if(TMath::Abs(TMath::Abs(n.Z())<fXtlArrSize[2]) && n.Pt()<fXtlArrSize[0]){
+      moduleNumber = imod ;
+      z=n.Z() ;
+      x=TMath::Sign(n.Pt(),n.X()) ;
+      //no need to return to local system since we calcilated distance from module center
+      //and tilts can not be significant.
+      return kTRUE ;
+    }
+  }
+  //Not in acceptance
+  x=0; z=0 ;
+  moduleNumber=0 ;
+  return kFALSE ;
+
+}
+
+//____________________________________________________________________________
+void AliPHOSGeoUtils::Init(void){
+  //Reads geometry parameters from dedicated classes
+
+  AliPHOSEMCAGeometry emcGeom ;
+
+  fNModules     = 5;
+  fNPhi  = emcGeom.GetNPhi() ;
+  fNZ    = emcGeom.GetNZ() ;
+  fNCristalsInModule = fNPhi*fNZ ;
+  fNCellsXInStrip= emcGeom.GetNCellsXInStrip() ;
+  fNCellsZInStrip= emcGeom.GetNCellsZInStrip() ;
+  fNStripZ = emcGeom.GetNStripZ() ;
+  fXtlArrSize[0]=emcGeom.GetInnerThermoHalfSize()[0] ; //Wery close to the zise of the Xtl set
+  fXtlArrSize[1]=emcGeom.GetInnerThermoHalfSize()[1] ; //Wery close to the zise of the Xtl set
+  fXtlArrSize[2]=emcGeom.GetInnerThermoHalfSize()[2] ; //Wery close to the zise of the Xtl set
+
+  //calculate offset to crystal surface
+  Float_t * inthermo = emcGeom.GetInnerThermoHalfSize() ;
+  Float_t * strip = emcGeom.GetStripHalfSize() ;
+  Float_t* splate = emcGeom.GetSupportPlateHalfSize();
+  Float_t * crystal = emcGeom.GetCrystalHalfSize() ;
+  Float_t * pin = emcGeom.GetAPDHalfSize() ;
+  Float_t * preamp = emcGeom.GetPreampHalfSize() ;
+  fCrystalShift=-inthermo[1]+strip[1]+splate[1]+crystal[1]-emcGeom.GetAirGapLed()/2.+pin[1]+preamp[1] ;
+  fCryCellShift=crystal[1]-(emcGeom.GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
+  fCellStep = 2.*emcGeom.GetAirCellHalfSize()[0] ;
+
+  AliPHOSCPVGeometry cpvGeom ;
+
+  fNumberOfCPVPadsPhi = cpvGeom.GetNumberOfCPVPadsPhi() ;
+  fNumberOfCPVPadsZ   = cpvGeom.GetNumberOfCPVPadsZ() ;
+  fPadSizePhi = cpvGeom.GetCPVPadSizePhi() ;
+  fPadSizeZ   = cpvGeom.GetCPVPadSizeZ() ; 
+  fCPVBoxSizeY= cpvGeom.GetCPVBoxSize(1) ;
+}
diff --git a/PHOS/AliPHOSGeoUtils.h b/PHOS/AliPHOSGeoUtils.h
new file mode 100644 (file)
index 0000000..7bbae78
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef ALIPHOSGEOUTILS_H
+#define ALIPHOSGEOUTILS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//_________________________________________________________________________
+// class for geometry transformations in PHOS
+// PHOS consists of the electromagnetic calorimeter (EMCA)
+// and a charged particle veto (CPV)
+// 
+//*-- Author: Dmitri Peressounko (RRC "KI")
+
+// --- ROOT system ---
+#include "TNamed.h"
+
+// --- AliRoot header files ---
+
+class TVector3;
+class TParticle ;
+
+class AliPHOSGeoUtils : public TNamed {
+
+public: 
+
+  AliPHOSGeoUtils() ;
+  AliPHOSGeoUtils(const Text_t* name, const Text_t* title="") ;
+  AliPHOSGeoUtils(const AliPHOSGeoUtils & geom) ;
+  
+  virtual ~AliPHOSGeoUtils(void) ; 
+  AliPHOSGeoUtils & operator = (const AliPHOSGeoUtils  & rvalue) ;
+
+  Bool_t AbsToRelNumbering(Int_t AbsId, Int_t * RelId) const ; 
+                                         // converts the absolute PHOS cell numbering to a relative 
+  Bool_t RelToAbsNumbering(const Int_t * RelId, Int_t & AbsId) const ; 
+                                         // converts the absolute PHOS numbering to a relative         
+                                         
+  void RelPosInModule(const Int_t * relId, Float_t & y, Float_t & z) const ; 
+                                         // gets the position of element (pad or Xtal) relative to 
+                                         // center of PHOS module  
+  void RelPosToAbsId(Int_t module, Double_t x, Double_t z, Int_t & AbsId) const; 
+                                         // converts local PHOS-module (x, z) coordinates to absId 
+  void RelPosToRelId(Int_t module, Double_t x, Double_t z, Int_t * relId) const; 
+                                         // converts local PHOS-module (x, z) coordinates to relId 
+  void RelPosInAlice(Int_t AbsId, TVector3 &  pos) const ;             
+                                         // gets the position of element (pad or Xtal) relative to Alice
+
+  void Local2Global(Int_t module, Float_t x, Float_t z, TVector3 &globaPos) const ;
+              
+  void Global2Local(TVector3& localPosition,const TVector3& globalPosition,Int_t module) const ;
+
+  Bool_t ImpactOnEmc(const TParticle * particle,Int_t & ModuleNumber, Double_t & z, Double_t & x) const ;
+                                         //Checks if NEUTRAL particle hits PHOS
+  Bool_t ImpactOnEmc(const Double_t * vtx, const TVector3& vec,                
+                  Int_t & ModuleNumber, Double_t & z, Double_t & x) const ; 
+                                         // calculates the impact coordinates of a neutral particle  
+                                         // emitted in direction theta and phi in ALICE
+  Bool_t ImpactOnEmc(const Double_t * vtx, const Double_t theta, const Double_t phi, 
+                  Int_t & ModuleNumber, Double_t & z, Double_t & x) const ; 
+                                         // calculates the impact coordinates of a neutral particle  
+                                         // emitted in direction theta and phi in ALICE
+  void  GetIncidentVector(const TVector3 &vtx, Int_t module, Float_t x, Float_t z, TVector3& vInc) const ;
+                                         //calculates vector from vertex to current point in module local frame
+
+  Bool_t IsInEMC(Int_t id) const { if (id > fNModules *  fNCristalsInModule ) return kFALSE; return kTRUE; } 
+
+
+private:
+  void Init(void) ;  //Read all sizes etc. for EMC and CPV geometries
+
+private:
+
+  Int_t fNModules ;          // Maximal designed number of modules in PHOS
+  Int_t fNCristalsInModule ; //Number of crystals in one module
+  Int_t fNPhi ;              //Number of crystals along Phi direction
+  Int_t fNZ ;                //Number of crystals along Z direction
+  Int_t fNumberOfCPVPadsPhi; //Number of CPV pads along Phi direction
+  Int_t fNumberOfCPVPadsZ ;  //Number of CPV pads along Z direction
+  Int_t fNCellsXInStrip ;    //Number of crystals in strip
+  Int_t fNCellsZInStrip ;    //Number of crystals in strip in Z direction 
+  Int_t fNStripZ ;           //Number of strips in Z direction
+
+  Float_t fCrystalShift ;    //Distance between center of module and crystal surface
+  Float_t fXtlArrSize[3] ;   //Total size of cristals array
+  Float_t fCryCellShift ; 
+  Float_t fCellStep ; 
+  Float_t fPadSizePhi ;      //Size of CPV pad in Phi direction
+  Float_t fPadSizeZ ;        //Size of CPV pad in Z direction
+  Float_t fCPVBoxSizeY ;
+
+  ClassDef(AliPHOSGeoUtils,1)       // PHOS geometry class 
+
+} ;
+
+#endif // AliPHOSGEOUTILS_H
diff --git a/PHOS/PHOSUtilsLinkDef.h b/PHOS/PHOSUtilsLinkDef.h
new file mode 100644 (file)
index 0000000..0a3d7bd
--- /dev/null
@@ -0,0 +1,9 @@
+#ifdef __CINT__
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliPHOSGeoUtils+;
+
+#endif
diff --git a/PHOS/PROOF-INF.PHOSUtils/BUILD.sh b/PHOS/PROOF-INF.PHOSUtils/BUILD.sh
new file mode 100755 (executable)
index 0000000..fc9490a
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+make 
diff --git a/PHOS/PROOF-INF.PHOSUtils/SETUP.C b/PHOS/PROOF-INF.PHOSUtils/SETUP.C
new file mode 100644 (file)
index 0000000..222a8b9
--- /dev/null
@@ -0,0 +1,13 @@
+void SETUP()
+{
+
+   // Load library
+   gSystem->Load("libPPHOSUtils");
+
+   // Set the Include paths
+//   gSystem->SetIncludePath("-I$ROOTSYS/include -IPHOS");
+   gROOT->ProcessLine(".include PHOS");
+
+   // Set our location, so that other packages can find us
+   gSystem->Setenv("PHOSUtils_INCLUDE", "PHOS");
+}
diff --git a/PHOS/libPHOSUtils.pkg b/PHOS/libPHOSUtils.pkg
new file mode 100644 (file)
index 0000000..bd3e21c
--- /dev/null
@@ -0,0 +1,12 @@
+#-*- Mode: Makefile -*-
+
+SRCS          =  AliPHOSGeoUtils.cxx AliPHOSEMCAGeometry.cxx AliPHOSCPVGeometry.cxx
+
+HDRS:= $(SRCS:.cxx=.h) 
+
+DHDR= PHOSUtilsLinkDef.h
+
+ifeq (win32gcc,$(ALICE_TARGET))
+PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
+                         -L$(shell root-config --libdir) -lGeom 
+endif