LCOV - code coverage report
Current view: top level - PHOS/PHOSsim - AliPHOSv0.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 331 494 67.0 %
Date: 2016-06-14 17:26:59 Functions: 7 11 63.6 %

          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             : /* $Id$ */
      16             : 
      17             : /* History of cvs commits:
      18             :  *
      19             :  * $Log$
      20             :  * Revision 1.94  2007/10/18 08:40:02  kharlov
      21             :  * Misalignment-related bug fixed
      22             :  *
      23             :  * Revision 1.93  2007/10/06 22:24:40  kharlov
      24             :  * Bug in strip unit geometry is corrected
      25             :  *
      26             :  * Revision 1.92  2007/07/04 16:38:19  policheh
      27             :  * Tracking2LocalCS matrices corrected for CPV.
      28             :  *
      29             :  * Revision 1.91  2007/07/02 14:50:49  policheh
      30             :  * Tracking2LocalCS matrices corrected.
      31             :  *
      32             :  * Revision 1.90  2007/05/24 13:04:05  policheh
      33             :  * AddAlignableVolumes: local to tracking CS transformation matrices creates for each
      34             :  * PHOS supermodule
      35             :  *
      36             :  * Revision 1.89  2007/04/24 14:34:39  hristov
      37             :  * Additional protection: do not search for alignable object if the CPV is not in the geometry
      38             :  *
      39             :  * Revision 1.88  2007/04/19 15:28:30  kharlov
      40             :  * Modify strip unit geometry according to the final drawings (Timur)
      41             :  *
      42             :  * Revision 1.87  2007/04/01 07:37:10  kharlov
      43             :  * TGeo RS to Local RS transf matr added
      44             :  *
      45             :  * Revision 1.86  2007/03/06 06:55:46  kharlov
      46             :  * DP:Misalignment of CPV added
      47             :  *
      48             :  * Revision 1.85  2007/03/01 11:37:37  kharlov
      49             :  * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
      50             :  *
      51             :  * Revision 1.84  2006/12/20 16:56:43  kharlov
      52             :  * Optional geometry without CPV
      53             :  *
      54             :  * Revision 1.83  2006/11/14 17:11:15  hristov
      55             :  * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
      56             :  *
      57             :  * Revision 1.82  2006/09/27 19:55:57  kharlov
      58             :  * Alignment object with symbolic volume names are introduced
      59             :  *
      60             :  * Revision 1.81  2006/03/04 20:25:56  kharlov
      61             :  * Set geom parameters from CDB
      62             :  *
      63             :  * Revision 1.80  2005/06/17 07:39:07  hristov
      64             :  * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
      65             :  *
      66             :  * Revision 1.79  2005/05/28 14:19:05  schutz
      67             :  * Compilation warnings fixed by T.P.
      68             :  *
      69             :  */
      70             : 
      71             : //_________________________________________________________________________
      72             : // Implementation version v0 of PHOS Manager class 
      73             : // An object of this class does not produce hits nor digits
      74             : // It is the one to use if you do not want to produce outputs in TREEH or TREED
      75             : //                  
      76             : //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
      77             : 
      78             : 
      79             : // --- ROOT system ---
      80             : 
      81             : #include <TFolder.h>
      82             : #include <TGeometry.h>
      83             : #include <TROOT.h>
      84             : #include <TRandom.h>
      85             : #include <TTree.h>
      86             : #include <TVirtualMC.h>
      87             : #include <TGeoPhysicalNode.h>
      88             : #include <TGeoManager.h>
      89             : #include <TGeoMatrix.h>
      90             : #include <TVector3.h>
      91             : 
      92             : // --- Standard library ---
      93             : 
      94             : #include <string.h>
      95             : #include <stdlib.h>
      96             : 
      97             : // --- AliRoot header files ---
      98             : 
      99             : #include "AliConst.h"
     100             : #include "AliPHOSGeometry.h"
     101             : #include "AliPHOSLoader.h"
     102             : #include "AliPHOSv0.h"
     103             : #include "AliRun.h"
     104             : #include "AliLog.h"
     105             : #include "AliGeomManager.h"
     106             : 
     107          20 : ClassImp(AliPHOSv0)
     108             : 
     109             : //____________________________________________________________________________
     110             : AliPHOSv0::AliPHOSv0(const char *name, const char *title): 
     111           1 :   AliPHOS(name,title),
     112           1 :  fCreateCPV(kFALSE), 
     113           1 :  fCreateHalfMod(kFALSE) 
     114           3 : {
     115             :   // ctor : title is used to identify the layout
     116             :   //Check possible configurations  
     117             :   
     118          14 :   for(Int_t mod=0; mod<6; mod++){
     119           6 :     fActiveModule[mod]=kFALSE ;
     120           6 :     fActiveCPV[mod]=kFALSE ;
     121             :   }
     122             :   //Default geometries
     123             :   //for period 2009-2013
     124           2 :   if(strstr(title,"Run1")!=0){
     125           1 :     fCreateCPV=kFALSE ;
     126           1 :     fCreateHalfMod=kFALSE;
     127           1 :     fActiveModule[1]=kTRUE ;
     128           1 :     fActiveModule[2]=kTRUE ;
     129           1 :     fActiveModule[3]=kTRUE ;
     130             :     //NO CPV in Run1   
     131           1 :   }
     132             :   else{
     133             :     //for period 2015-2018
     134           0 :     if(strstr(title,"Run2")!=0){
     135           0 :       fCreateCPV=kTRUE ;
     136           0 :       fCreateHalfMod=kTRUE;
     137           0 :       fActiveModule[1]=kTRUE ;
     138           0 :       fActiveModule[2]=kTRUE ;
     139           0 :       fActiveModule[3]=kTRUE ;
     140           0 :       fActiveModule[4]=kTRUE ;
     141           0 :       fActiveCPV[3]=kTRUE ;
     142           0 :     }
     143             :     else{
     144             :      //custom geometry can be set in form
     145             :      //Modxxx_CPVyyy, where xxx- list of PHOS modules in geometry, yyy -list of modules with CPVallFront
     146             :      Bool_t isOK=kFALSE ;
     147           0 :      TString a(title); 
     148           0 :      Int_t modPos=a.Index("Mod",0,TString::kIgnoreCase) ;
     149           0 :      Int_t cpvPos=a.Index("CPV",0,TString::kIgnoreCase) ;
     150           0 :      Int_t size = a.Sizeof() ;
     151           0 :      Int_t modEnd=(cpvPos>modPos)?cpvPos:size ;
     152           0 :      Int_t cpvEnd=(cpvPos>modPos)?size:modPos ;
     153           0 :      for(Int_t mod=1; mod<6; mod++){
     154           0 :        Int_t imod=a.Index(Form("%d",mod),modPos);
     155           0 :        if(imod>modPos && imod<modEnd){
     156           0 :          fActiveModule[mod]=kTRUE ;
     157             :          isOK=kTRUE ;
     158           0 :          if(mod==4)
     159           0 :            fCreateHalfMod=kTRUE;
     160             :        }
     161           0 :        Int_t icpv=a.Index(Form("%d",mod),cpvPos);
     162           0 :        if(icpv>cpvPos && icpv<cpvEnd){
     163           0 :          fActiveCPV[mod]=kTRUE ;
     164           0 :          fCreateCPV=kTRUE ;
     165           0 :        }
     166             :      }
     167           0 :      if(!isOK){
     168           0 :        AliFatal(Form("Unknown PHOS configuration: %s. Possible: 'Run1' for 2009-2013, 'Run2' for 2015-2018', 'Modxxx_CPVyyy' for castom",title)) ; 
     169             :      }
     170           0 :     }
     171             :   }
     172             :    
     173           1 :   GetGeometry() ; 
     174             : 
     175             :   
     176           1 : }
     177             : 
     178             : //____________________________________________________________________________
     179             : void AliPHOSv0::CreateGeometry()
     180             : {
     181             :   // Create the PHOS geometry for Geant
     182             : 
     183           4 :   AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
     184             : 
     185           1 :   if ( phostmp == NULL ) {
     186             :     
     187           0 :     fprintf(stderr, "PHOS detector not found!\n") ;
     188           0 :     return;
     189             :     
     190             :   }
     191             : 
     192           1 :   AliPHOSGeometry * geom = GetGeometry() ; 
     193             : 
     194             :   // Get pointer to the array containing media indeces
     195           1 :   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
     196             : 
     197             :   // Create a PHOS module.
     198             :   
     199           1 :   TVirtualMC::GetMC()->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
     200           1 :   if(fCreateHalfMod){
     201           0 :     TVirtualMC::GetMC()->Gsvolu("PHOH", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
     202           0 :   }
     203           1 :   if(fCreateCPV){
     204           0 :     TVirtualMC::GetMC()->Gsvolu("PHOC", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;             
     205           0 :   }
     206             :   
     207           1 :   this->CreateGeometryforEMC() ; 
     208             :   //Should we create 4-th module
     209             : 
     210           1 :   if (fCreateCPV) 
     211           0 :     this->CreateGeometryforCPV() ;
     212             :   
     213           1 :   this->CreateGeometryforSupport() ; 
     214             :   
     215             :   // --- Position  PHOS mdules in ALICE setup ---
     216           1 :   Int_t idrotm[99] ;
     217             :   Int_t iXYZ,iAngle;
     218           1 :   char im[5] ;
     219          12 :   for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
     220           5 :     snprintf(im,5,"%d",iModule+1) ;
     221           5 :     if(!fActiveModule[iModule+1])
     222             :       continue ;
     223           3 :     Float_t angle[3][2];
     224          24 :     for (iXYZ=0; iXYZ<3; iXYZ++)
     225          54 :       for (iAngle=0; iAngle<2; iAngle++)
     226          18 :         angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
     227           6 :     AliMatrix(idrotm[iModule],
     228           3 :               angle[0][0],angle[0][1],
     229           3 :               angle[1][0],angle[1][1],
     230           3 :               angle[2][0],angle[2][1]) ;
     231             :     
     232           3 :     Float_t pos[3];
     233          24 :     for (iXYZ=0; iXYZ<3; iXYZ++)
     234           9 :       pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
     235           3 :     if(iModule==3){ //special 1/2 module
     236           0 :        TVirtualMC::GetMC()->Gspos("PHOH", iModule+1, "ALIC", pos[0], pos[1], pos[2],
     237           0 :                idrotm[iModule], "ONLY") ;
     238           0 :     }
     239             :     else{
     240           6 :       if(fActiveCPV[iModule+1]){ //use module with CPV
     241           3 :         TVirtualMC::GetMC()->Gspos("PHOC", iModule+1, "ALIC", pos[0], pos[1], pos[2],
     242           3 :                idrotm[iModule], "ONLY") ;
     243           0 :       }
     244             :       else{ //module wihtout CPV
     245           3 :         TVirtualMC::GetMC()->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
     246             :                idrotm[iModule], "ONLY") ;
     247             :       }
     248             :    }
     249           3 :   }
     250           2 : }
     251             : 
     252             : //____________________________________________________________________________
     253             : void AliPHOSv0::CreateGeometryforEMC()
     254             : {
     255             :   // Create the PHOS-EMC geometry for GEANT
     256             :   // Author: Dmitri Peressounko August 2001
     257             :   // The used coordinate system: 
     258             :   //   1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
     259             :   //   2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
     260             : 
     261             : 
     262             :     //BEGIN_HTML
     263             :   /*
     264             :     <H2>
     265             :     Geant3 geometry tree of PHOS-EMC in ALICE
     266             :     </H2>
     267             :     <P><CENTER>
     268             :     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
     269             :     </CENTER><P>
     270             :   */
     271             :   //END_HTML  
     272             :   
     273             :   // Get pointer to the array containing media indexes
     274           2 :   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
     275             : 
     276           1 :   AliPHOSGeometry * geom = GetGeometry() ; 
     277           1 :   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
     278           1 :   Float_t par[4];
     279             :   Int_t  ipar;
     280             :   
     281             :   // ======= Define the strip ===============
     282             : 
     283           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetStripHalfSize() + ipar);
     284           1 :   TVirtualMC::GetMC()->Gsvolu("PSTR", "BOX ", idtmed[716], par, 3) ;  //Made of steel
     285             : 
     286             :   // --- define steel volume (cell of the strip unit)
     287           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirCellHalfSize() + ipar);
     288           1 :   TVirtualMC::GetMC()->Gsvolu("PCEL", "BOX ", idtmed[798], par, 3);
     289             : 
     290             :   // --- define wrapped crystal and put it into steel cell
     291             : 
     292           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWrappedHalfSize() + ipar);
     293           1 :   TVirtualMC::GetMC()->Gsvolu("PWRA", "BOX ", idtmed[702], par, 3);
     294           1 :   const Float_t * pin    = emcg->GetAPDHalfSize() ; 
     295           1 :   const Float_t * preamp = emcg->GetPreampHalfSize() ;
     296           1 :   Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
     297           1 :   TVirtualMC::GetMC()->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
     298             :     
     299             :   // --- Define crystal and put it into wrapped crystall ---
     300           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCrystalHalfSize() + ipar);
     301           1 :   TVirtualMC::GetMC()->Gsvolu("PXTL", "BOX ", idtmed[699], par, 3) ;
     302           1 :   TVirtualMC::GetMC()->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
     303             :   
     304             :   // --- define APD/PIN preamp and put it into AirCell
     305             :  
     306           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAPDHalfSize() + ipar);
     307           1 :   TVirtualMC::GetMC()->Gsvolu("PPIN", "BOX ", idtmed[705], par, 3) ;
     308           1 :   const Float_t * crystal = emcg->GetCrystalHalfSize() ;
     309           1 :   y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; 
     310           1 :   TVirtualMC::GetMC()->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
     311           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetPreampHalfSize() + ipar);
     312           1 :   TVirtualMC::GetMC()->Gsvolu("PREA", "BOX ", idtmed[711], par, 3) ;   // Here I assumed preamp as a printed Circuit
     313           1 :   y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1]  ;    // May it should be changed
     314           1 :   TVirtualMC::GetMC()->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
     315             :   
     316             :   
     317             :   // --- Fill strip with wrapped cristals in steel cells
     318             :   
     319           1 :   const Float_t* splate = emcg->GetSupportPlateHalfSize();  
     320           1 :   y = -splate[1] ;
     321           1 :   const Float_t* acel = emcg->GetAirCellHalfSize() ;
     322             :   
     323          18 :   for(Int_t lev = 2, icel = 1; 
     324           9 :       icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); 
     325           8 :       icel += 2, lev += 2) {
     326           8 :     Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
     327           8 :     Float_t z = acel[2];
     328           8 :     TVirtualMC::GetMC()->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
     329           8 :     TVirtualMC::GetMC()->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
     330             :   }
     331             : 
     332             :   // --- define the support plate, hole in it and position it in strip ----
     333           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateHalfSize() + ipar);
     334           1 :   TVirtualMC::GetMC()->Gsvolu("PSUP", "BOX ", idtmed[701], par, 3) ;
     335             :   
     336           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateInHalfSize() + ipar);
     337           1 :   TVirtualMC::GetMC()->Gsvolu("PSHO", "BOX ", idtmed[798], par, 3) ;
     338           1 :   Float_t z = emcg->GetSupportPlateThickness()/2 ;
     339           1 :   TVirtualMC::GetMC()->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
     340             : 
     341           1 :   y = acel[1] ;
     342           1 :   TVirtualMC::GetMC()->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
     343             : 
     344             :   
     345             :   // ========== Fill module with strips and put them into inner thermoinsulation=============
     346           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetInnerThermoHalfSize() + ipar);
     347           1 :   TVirtualMC::GetMC()->Gsvolu("PTII", "BOX ", idtmed[706], par, 3) ;     
     348             :   
     349           1 :   if(fCreateHalfMod)
     350           0 :     TVirtualMC::GetMC()->Gsvolu("PTIH", "BOX ", idtmed[706], par, 3) ;     
     351             :     
     352             :   
     353           1 :   const Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
     354           1 :   const Float_t * strip    = emcg->GetStripHalfSize() ;
     355           1 :   y = inthermo[1] - strip[1] ;
     356             :   Int_t irow;
     357             :   Int_t nr = 1 ;
     358             :   Int_t icol ;
     359             :   
     360          18 :   for(irow = 0; irow < emcg->GetNStripX(); irow ++){
     361           8 :     Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
     362         464 :     for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
     363         224 :       z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
     364         224 :       TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
     365         224 :       nr++ ;
     366             :     }
     367             :   }
     368           1 :   if(fCreateHalfMod){
     369             :     nr = 1 ;
     370           0 :     for(irow = 0; irow < emcg->GetNStripX(); irow ++){
     371           0 :       Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
     372           0 :       for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
     373           0 :         z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
     374           0 :         if(irow>=emcg->GetNStripX()/2)
     375           0 :           TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTIH", x, y, z, 0, "ONLY") ;
     376           0 :         nr++ ;
     377             :       }
     378             :     }
     379             :   }
     380             :   
     381             :   // ------- define the air gap between thermoinsulation and cooler
     382           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirGapHalfSize() + ipar);
     383           1 :   TVirtualMC::GetMC()->Gsvolu("PAGA", "BOX ", idtmed[798], par, 3) ;   
     384           1 :   if(fCreateHalfMod)
     385           0 :     TVirtualMC::GetMC()->Gsvolu("PAGH", "BOX ", idtmed[798], par, 3) ;   
     386           1 :   const Float_t * agap = emcg->GetAirGapHalfSize() ;
     387           1 :   y = agap[1] - inthermo[1]  ;
     388             :   
     389           1 :   TVirtualMC::GetMC()->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
     390           1 :   if(fCreateHalfMod)
     391           0 :     TVirtualMC::GetMC()->Gspos("PTIH", 1, "PAGH", 0.0, y, 0.0, 0, "ONLY") ;
     392             : 
     393             : 
     394             :   // ------- define the Al passive cooler 
     395           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCoolerHalfSize() + ipar);
     396           1 :   TVirtualMC::GetMC()->Gsvolu("PCOR", "BOX ", idtmed[701], par, 3) ;   
     397           1 :   if(fCreateHalfMod)
     398           0 :     TVirtualMC::GetMC()->Gsvolu("PCOH", "BOX ", idtmed[701], par, 3) ;   
     399             : 
     400           1 :   const Float_t * cooler = emcg->GetCoolerHalfSize() ;
     401           1 :   y = cooler[1] - agap[1]  ;
     402             :   
     403           1 :   TVirtualMC::GetMC()->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
     404           1 :   if(fCreateHalfMod)
     405           0 :     TVirtualMC::GetMC()->Gspos("PAGH", 1, "PCOH", 0.0, y, 0.0, 0, "ONLY") ;
     406             :   
     407             :   // ------- define the outer thermoinsulating cover
     408          10 :   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetOuterThermoParams() + ipar);
     409           1 :   TVirtualMC::GetMC()->Gsvolu("PTIO", "TRD1", idtmed[706], par, 4) ;        
     410           1 :   if(fCreateHalfMod)
     411           0 :     TVirtualMC::GetMC()->Gsvolu("PIOH", "TRD1", idtmed[706], par, 4) ;        
     412           1 :   const Float_t * outparams = emcg->GetOuterThermoParams() ; 
     413             :   
     414           1 :   Int_t idrotm[99] ;
     415           1 :   AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
     416             :   // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
     417             :   
     418           1 :   z = outparams[3] - cooler[1] ;
     419           1 :   TVirtualMC::GetMC()->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
     420           1 :   if(fCreateHalfMod)
     421           0 :     TVirtualMC::GetMC()->Gspos("PCOH", 1, "PIOH", 0., 0.0, z, idrotm[1], "ONLY") ;
     422             :   
     423             :   // -------- Define the outer Aluminium cover -----
     424          10 :   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetAlCoverParams() + ipar);
     425           1 :   TVirtualMC::GetMC()->Gsvolu("PCOL", "TRD1", idtmed[701], par, 4) ;        
     426           1 :   if(fCreateHalfMod)
     427           0 :     TVirtualMC::GetMC()->Gsvolu("PCLH", "TRD1", idtmed[701], par, 4) ;        
     428             : 
     429           1 :   const Float_t * covparams = emcg->GetAlCoverParams() ; 
     430           1 :   z = covparams[3] - outparams[3] ;  
     431           1 :   TVirtualMC::GetMC()->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
     432           1 :   if(fCreateHalfMod)
     433           0 :     TVirtualMC::GetMC()->Gspos("PIOH", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
     434             : 
     435             :   // --------- Define front fiberglass cover -----------
     436           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFiberGlassHalfSize() + ipar);
     437           1 :   TVirtualMC::GetMC()->Gsvolu("PFGC", "BOX ", idtmed[717], par, 3) ;  
     438           1 :   z = - outparams[3] ;
     439           1 :   TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
     440           1 :   if(fCreateHalfMod)
     441           0 :     TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
     442             : 
     443             :   //=============This is all with cold section==============
     444             :   
     445             : 
     446             :   //------ Warm Section --------------
     447           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmAlCoverHalfSize() + ipar);
     448           1 :   TVirtualMC::GetMC()->Gsvolu("PWAR", "BOX ", idtmed[701], par, 3) ; 
     449           1 :   const Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
     450             :   
     451             :   // --- Define the outer thermoinsulation ---
     452           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmThermoHalfSize() + ipar);
     453           1 :   TVirtualMC::GetMC()->Gsvolu("PWTI", "BOX ", idtmed[706], par, 3) ; 
     454           1 :   const Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
     455           1 :   z = -warmcov[2] + warmthermo[2] ;
     456             :   
     457           1 :   TVirtualMC::GetMC()->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;     
     458             :   
     459             :   // --- Define cables area and put in it T-supports ---- 
     460           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables1HalfSize() + ipar);
     461           1 :   TVirtualMC::GetMC()->Gsvolu("PCA1", "BOX ", idtmed[718], par, 3) ; 
     462           1 :   const Float_t * cbox = emcg->GetTCables1HalfSize() ;
     463             :   
     464           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport1HalfSize() + ipar);
     465           1 :   TVirtualMC::GetMC()->Gsvolu("PBE1", "BOX ", idtmed[701], par, 3) ;
     466           1 :   const Float_t * beams = emcg->GetTSupport1HalfSize() ;
     467             :   Int_t isup ;
     468          20 :   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
     469           9 :     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
     470           9 :     TVirtualMC::GetMC()->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
     471             :   }
     472             :   
     473           1 :   z = -warmthermo[2] + cbox[2];
     474           1 :   TVirtualMC::GetMC()->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
     475             :   
     476           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables2HalfSize() + ipar);
     477           1 :   TVirtualMC::GetMC()->Gsvolu("PCA2", "BOX ", idtmed[718], par, 3) ; 
     478           1 :   const Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
     479             :   
     480           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport2HalfSize() + ipar);
     481           1 :   TVirtualMC::GetMC()->Gsvolu("PBE2", "BOX ", idtmed[701], par, 3) ;
     482          20 :   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
     483           9 :     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
     484           9 :     TVirtualMC::GetMC()->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
     485             :   }
     486             :   
     487           1 :   z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
     488           1 :   TVirtualMC::GetMC()->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
     489             :   
     490             :   // --- Define frame ---
     491           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameXHalfSize() + ipar);
     492           1 :   TVirtualMC::GetMC()->Gsvolu("PFRX", "BOX ", idtmed[716], par, 3) ; 
     493           1 :   const Float_t * posit1 = emcg->GetFrameXPosition() ;
     494           1 :   TVirtualMC::GetMC()->Gspos("PFRX", 1, "PWTI", posit1[0],  posit1[1], posit1[2], 0, "ONLY") ;
     495           1 :   TVirtualMC::GetMC()->Gspos("PFRX", 2, "PWTI", posit1[0], -posit1[1], posit1[2], 0, "ONLY") ;
     496             :   
     497           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameZHalfSize() + ipar);
     498           1 :   TVirtualMC::GetMC()->Gsvolu("PFRZ", "BOX ", idtmed[716], par, 3) ; 
     499           1 :   const Float_t * posit2 = emcg->GetFrameZPosition() ;
     500           1 :   TVirtualMC::GetMC()->Gspos("PFRZ", 1, "PWTI",  posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
     501           1 :   TVirtualMC::GetMC()->Gspos("PFRZ", 2, "PWTI", -posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
     502             : 
     503             :  // --- Define Fiber Glass support ---
     504           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupXHalfSize() + ipar);
     505           1 :   TVirtualMC::GetMC()->Gsvolu("PFG1", "BOX ", idtmed[717], par, 3) ; 
     506           1 :   const Float_t * posit3 = emcg->GetFGupXPosition() ;
     507           1 :   TVirtualMC::GetMC()->Gspos("PFG1", 1, "PWTI", posit3[0],  posit3[1], posit3[2], 0, "ONLY") ;
     508           1 :   TVirtualMC::GetMC()->Gspos("PFG1", 2, "PWTI", posit3[0], -posit3[1], posit3[2], 0, "ONLY") ;
     509             :   
     510           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupZHalfSize() + ipar);
     511           1 :   TVirtualMC::GetMC()->Gsvolu("PFG2", "BOX ", idtmed[717], par, 3) ; 
     512           1 :   const Float_t * posit4 = emcg->GetFGupZPosition();
     513           1 :   TVirtualMC::GetMC()->Gspos("PFG2", 1, "PWTI",  posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
     514           1 :   TVirtualMC::GetMC()->Gspos("PFG2", 2, "PWTI", -posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
     515           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowXHalfSize() + ipar);
     516           1 :   TVirtualMC::GetMC()->Gsvolu("PFG3", "BOX ", idtmed[717], par, 3) ; 
     517           1 :   const Float_t * posit5 = emcg->GetFGlowXPosition() ;
     518           1 :   TVirtualMC::GetMC()->Gspos("PFG3", 1, "PWTI", posit5[0],  posit5[1], posit5[2], 0, "ONLY") ;
     519           1 :   TVirtualMC::GetMC()->Gspos("PFG3", 2, "PWTI", posit5[0], -posit5[1], posit5[2], 0, "ONLY") ;
     520             :     
     521           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowZHalfSize() + ipar);
     522           1 :   TVirtualMC::GetMC()->Gsvolu("PFG4", "BOX ", idtmed[717], par, 3) ; 
     523           1 :   const Float_t * posit6 = emcg->GetFGlowZPosition() ;
     524           1 :   TVirtualMC::GetMC()->Gspos("PFG4", 1, "PWTI",  posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
     525           1 :   TVirtualMC::GetMC()->Gspos("PFG4", 2, "PWTI", -posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
     526             : 
     527             :   // --- Define Air Gap for FEE electronics -----   
     528           8 :   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFEEAirHalfSize() + ipar);
     529           1 :   TVirtualMC::GetMC()->Gsvolu("PAFE", "BOX ", idtmed[798], par, 3) ; 
     530           1 :   const Float_t * posit7 = emcg->GetFEEAirPosition() ;
     531           1 :   TVirtualMC::GetMC()->Gspos("PAFE", 1, "PWTI",  posit7[0], posit7[1], posit7[2], 0, "ONLY") ;
     532             :   
     533             :   // Define the EMC module volume and combine Cool and Warm sections  
     534          10 :   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetEMCParams() + ipar);
     535           1 :   TVirtualMC::GetMC()->Gsvolu("PEMC", "TRD1", idtmed[798], par, 4) ;        
     536           1 :   if(fCreateHalfMod)
     537           0 :     TVirtualMC::GetMC()->Gsvolu("PEMH", "TRD1", idtmed[798], par, 4) ;        
     538           1 :   z =  - warmcov[2] ;
     539           1 :   TVirtualMC::GetMC()->Gspos("PCOL", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
     540           1 :   if(fCreateHalfMod)
     541           0 :     TVirtualMC::GetMC()->Gspos("PCLH", 1, "PEMH",  0., 0., z, 0, "ONLY") ;
     542           1 :   z = covparams[3] ;
     543           1 :   TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
     544           1 :   if(fCreateHalfMod)
     545           0 :     TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMH",  0., 0., z, 0, "ONLY") ;
     546             :   
     547             :   
     548             :   // Put created EMC geometry into PHOS volume
     549             :   
     550           1 :   z = geom->GetCPVBoxSize(1) / 2. ;
     551             :   //normal PHOS module
     552           1 :   TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; 
     553           1 :   if(fCreateCPV) //Module with CPV 
     554           0 :     TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOC", 0., 0., z, 0, "ONLY") ;   
     555           1 :   if(fCreateHalfMod) //half of PHOS module
     556           0 :     TVirtualMC::GetMC()->Gspos("PEMH", 1, "PHOH", 0., 0., z, 0, "ONLY") ; 
     557             :   
     558           1 : }
     559             : 
     560             : //____________________________________________________________________________
     561             : void AliPHOSv0::CreateGeometryforCPV()
     562             : {
     563             :   
     564           0 : printf("Create CPV geometry \n") ;  
     565             :   
     566             :   // Create the PHOS-CPV geometry for GEANT
     567             :   // Author: Yuri Kharlov 11 September 2000
     568             :   //BEGIN_HTML
     569             :   /*
     570             :     <H2>
     571             :     Geant3 geometry of PHOS-CPV in ALICE
     572             :     </H2>
     573             :     <table width=700>
     574             : 
     575             :     <tr>
     576             :          <td>CPV perspective view</td>
     577             :          <td>CPV front view      </td>
     578             :     </tr>
     579             : 
     580             :     <tr>
     581             :          <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
     582             :          <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
     583             :     </tr>
     584             : 
     585             :     <tr>
     586             :          <td>One CPV module, perspective view                            </td>
     587             :          <td>One CPV module, front view (extended in vertical direction) </td>
     588             :     </tr>
     589             : 
     590             :     <tr>
     591             :          <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
     592             :          <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
     593             :     </tr>
     594             : 
     595             :     </table>
     596             : 
     597             :     <H2>
     598             :     Geant3 geometry tree of PHOS-CPV in ALICE
     599             :     </H2>
     600             :     <center>
     601             :     <img height=300 width=290 src="../images/CPVtree.gif">
     602             :     </center>
     603             :   */
     604             :   //END_HTML  
     605             : 
     606           0 :   Float_t par[3], x,y,z;
     607             : 
     608             :   // Get pointer to the array containing media indexes
     609           0 :   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
     610             : 
     611           0 :   AliPHOSGeometry * geom = GetGeometry() ; 
     612             : 
     613             :   // The box containing all CPV for one PHOS module filled with air 
     614           0 :   par[0] = geom->GetCPVBoxSize(0) / 2.0 ;  
     615           0 :   par[1] = geom->GetCPVBoxSize(1) / 2.0 ; 
     616           0 :   par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
     617           0 :   TVirtualMC::GetMC()->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
     618             : 
     619           0 :   const Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
     620           0 :   z = - emcParams[3] ;
     621           0 :   Int_t rotm ;
     622           0 :   AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
     623             : 
     624           0 :   TVirtualMC::GetMC()->Gspos("PCPV", 1, "PHOC", 0.0, 0.0, z, rotm, "ONLY") ; 
     625             :   
     626             :   // Gassiplex board
     627             :   
     628           0 :   par[0] = geom->GetGassiplexChipSize(0)/2.;
     629           0 :   par[1] = geom->GetGassiplexChipSize(1)/2.;
     630           0 :   par[2] = geom->GetGassiplexChipSize(2)/2.;
     631           0 :   TVirtualMC::GetMC()->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
     632             :   
     633             :   // Cu+Ni foil covers Gassiplex board
     634             : 
     635           0 :   par[1] = geom->GetCPVCuNiFoilThickness()/2;
     636           0 :   TVirtualMC::GetMC()->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
     637           0 :   y      = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
     638           0 :   TVirtualMC::GetMC()->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
     639             : 
     640             :   // Position of the chip inside CPV
     641             : 
     642           0 :   Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
     643           0 :   Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
     644             :   Int_t   copy  = 0;
     645           0 :   y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
     646           0 :     geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
     647           0 :   for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
     648           0 :     x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
     649           0 :     for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
     650           0 :       copy++;
     651           0 :       z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
     652           0 :       TVirtualMC::GetMC()->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
     653             :     }
     654             :   }
     655             : 
     656             :   // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
     657             :   
     658           0 :   par[0] = geom->GetCPVActiveSize(0)        / 2;
     659           0 :   par[1] = geom->GetCPVTextoliteThickness() / 2;
     660           0 :   par[2] = geom->GetCPVActiveSize(1)        / 2;
     661           0 :   TVirtualMC::GetMC()->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
     662             : 
     663             :   // Argon gas volume
     664             : 
     665           0 :   par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
     666           0 :   TVirtualMC::GetMC()->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
     667             : 
     668           0 :   for (Int_t i=0; i<4; i++) {
     669           0 :     y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
     670           0 :     TVirtualMC::GetMC()->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
     671           0 :     if(i==1){
     672           0 :       y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
     673           0 :       TVirtualMC::GetMC()->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
     674           0 :     }
     675             :   }
     676             : 
     677             :   // Dummy sensitive plane in the middle of argone gas volume
     678             : 
     679           0 :   par[1]=0.001;
     680           0 :   TVirtualMC::GetMC()->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
     681           0 :   TVirtualMC::GetMC()->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
     682             : 
     683             :   // Cu+Ni foil covers textolite
     684             : 
     685           0 :   par[1] = geom->GetCPVCuNiFoilThickness() / 2;
     686           0 :   TVirtualMC::GetMC()->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
     687           0 :   y = geom->GetCPVTextoliteThickness()/2 - par[1];
     688           0 :   TVirtualMC::GetMC()->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
     689             : 
     690             :   // Aluminum frame around CPV
     691             : 
     692           0 :   par[0] = geom->GetCPVFrameSize(0)/2;
     693           0 :   par[1] = geom->GetCPVFrameSize(1)/2;
     694           0 :   par[2] = geom->GetCPVBoxSize(2)  /2;
     695           0 :   TVirtualMC::GetMC()->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
     696             : 
     697           0 :   par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
     698           0 :   par[1] = geom->GetCPVFrameSize(1)/2;
     699           0 :   par[2] = geom->GetCPVFrameSize(2)/2;
     700           0 :   TVirtualMC::GetMC()->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
     701             : 
     702           0 :   for (Int_t j=0; j<=1; j++) {
     703           0 :     x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
     704           0 :     TVirtualMC::GetMC()->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
     705           0 :     z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
     706           0 :     TVirtualMC::GetMC()->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
     707             :   }
     708             : 
     709           0 : }
     710             : 
     711             : 
     712             : //____________________________________________________________________________
     713             : void AliPHOSv0::CreateGeometryforSupport()
     714             : {
     715             :   // Create the PHOS' support geometry for GEANT
     716             :     //BEGIN_HTML
     717             :   /*
     718             :     <H2>
     719             :     Geant3 geometry of the PHOS's support
     720             :     </H2>
     721             :     <P><CENTER>
     722             :     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif"> 
     723             :     </CENTER><P>
     724             :   */
     725             :   //END_HTML  
     726             :   
     727           2 :   Float_t par[5], x0,y0,z0 ; 
     728             :   Int_t   i,j,copy;
     729             : 
     730             :   // Get pointer to the array containing media indexes
     731           1 :   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
     732             : 
     733           1 :   AliPHOSGeometry * geom = GetGeometry() ; 
     734             : 
     735             :   // --- Dummy box containing two rails on which PHOS support moves
     736             :   // --- Put these rails to the bottom of the L3 magnet
     737             : 
     738           1 :   par[0] =  geom->GetRailRoadSize(0) / 2.0 ;
     739           1 :   par[1] =  geom->GetRailRoadSize(1) / 2.0 ;
     740           1 :   par[2] =  geom->GetRailRoadSize(2) / 2.0 ;
     741           1 :   TVirtualMC::GetMC()->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
     742             : 
     743           1 :   y0     = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
     744           1 :   TVirtualMC::GetMC()->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ; 
     745             : 
     746             :   // --- Dummy box containing one rail
     747             : 
     748           1 :   par[0] =  geom->GetRailOuterSize(0) / 2.0 ;
     749           1 :   par[1] =  geom->GetRailOuterSize(1) / 2.0 ;
     750           1 :   par[2] =  geom->GetRailOuterSize(2) / 2.0 ;
     751           1 :   TVirtualMC::GetMC()->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
     752             : 
     753           6 :   for (i=0; i<2; i++) {
     754           2 :     x0     = (2*i-1) * geom->GetDistanceBetwRails()  / 2.0 ;
     755           2 :     TVirtualMC::GetMC()->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ; 
     756             :   }
     757             : 
     758             :   // --- Upper and bottom steel parts of the rail
     759             : 
     760           1 :   par[0] =  geom->GetRailPart1(0) / 2.0 ;
     761           1 :   par[1] =  geom->GetRailPart1(1) / 2.0 ;
     762           1 :   par[2] =  geom->GetRailPart1(2) / 2.0 ;
     763           1 :   TVirtualMC::GetMC()->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
     764             : 
     765           1 :   y0     = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 ;
     766           1 :   TVirtualMC::GetMC()->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
     767           1 :   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 - geom->GetRailPart3(1);
     768           1 :   TVirtualMC::GetMC()->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
     769             : 
     770             :   // --- The middle vertical steel parts of the rail
     771             : 
     772           1 :   par[0] =  geom->GetRailPart2(0) / 2.0 ;
     773           1 :   par[1] =  geom->GetRailPart2(1) / 2.0 ;
     774           1 :   par[2] =  geom->GetRailPart2(2) / 2.0 ;
     775           1 :   TVirtualMC::GetMC()->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
     776             : 
     777           1 :   y0     =   - geom->GetRailPart3(1) / 2.0 ;
     778           1 :   TVirtualMC::GetMC()->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
     779             : 
     780             :   // --- The most upper steel parts of the rail
     781             : 
     782           1 :   par[0] =  geom->GetRailPart3(0) / 2.0 ;
     783           1 :   par[1] =  geom->GetRailPart3(1) / 2.0 ;
     784           1 :   par[2] =  geom->GetRailPart3(2) / 2.0 ;
     785           1 :   TVirtualMC::GetMC()->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
     786             : 
     787           1 :   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart3(1))  / 2.0 ;
     788           1 :   TVirtualMC::GetMC()->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
     789             : 
     790             :   // --- The wall of the cradle
     791             :   // --- The wall is empty: steel thin walls and air inside
     792             : 
     793           3 :   par[1] =  TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
     794           2 :                         TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
     795           1 :   par[0] =  par[1] - geom->GetCradleWall(1) ;
     796           1 :   par[2] =  geom->GetCradleWall(2) / 2.0 ;
     797           1 :   par[3] =  geom->GetCradleWall(3) ;
     798           1 :   par[4] =  geom->GetCradleWall(4) ;
     799           1 :   TVirtualMC::GetMC()->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
     800             : 
     801           1 :   par[0] +=  geom->GetCradleWallThickness() ;
     802           1 :   par[1] -=  geom->GetCradleWallThickness() ;
     803           1 :   par[2] -=  geom->GetCradleWallThickness() ;
     804           1 :   TVirtualMC::GetMC()->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
     805           1 :   TVirtualMC::GetMC()->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ; 
     806             : 
     807           6 :   for (i=0; i<2; i++) {
     808           2 :     z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0  ;
     809           2 :         TVirtualMC::GetMC()->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ; 
     810             :   }
     811             : 
     812             :   // --- The "wheels" of the cradle
     813             :   
     814           1 :   par[0] = geom->GetCradleWheel(0) / 2;
     815           1 :   par[1] = geom->GetCradleWheel(1) / 2;
     816           1 :   par[2] = geom->GetCradleWheel(2) / 2;
     817           1 :   TVirtualMC::GetMC()->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
     818             : 
     819           2 :   y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
     820           1 :          geom->GetCradleWheel(1)/2) ;
     821           6 :   for (i=0; i<2; i++) {
     822           4 :     z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
     823           2 :                     geom->GetCradleWall(2));
     824          12 :     for (j=0; j<2; j++) {
     825           4 :       copy = 2*i + j;
     826           4 :       x0 = (2*j-1) * geom->GetDistanceBetwRails()  / 2.0 ;
     827           4 :       TVirtualMC::GetMC()->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ; 
     828             :     }
     829             :   }
     830             : 
     831           1 : }
     832             : 
     833             : //_____________________________________________________________________________
     834             : void AliPHOSv0::AddAlignableVolumes() const
     835             : {
     836             :   //
     837             :   // Create entries for alignable volumes associating the symbolic volume
     838             :   // name with the corresponding volume path. Needs to be syncronized with
     839             :   // eventual changes in the geometry
     840             :   // Alignable volumes are:
     841             :   // 1) PHOS modules as a whole
     842             :   // 2) Cradle
     843             :   // 3) Cradle wheels
     844             :   // 4) Strip units (group of 2x8 crystals)
     845             : 
     846           2 :   TString volpath, symname;
     847             : 
     848             :   // Alignable modules
     849             :   // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
     850             :   
     851             :   AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
     852             :   AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
     853             :   Int_t modUID, modnum = 0;
     854           1 :   TString physModulePath="/ALIC_1/PHOS_";
     855           1 :   TString physModulePath2="/ALIC_1/PHOH_";
     856           1 :   TString physModulePath3="/ALIC_1/PHOC_";
     857           1 :   TString symbModuleName="PHOS/Module";
     858           2 :   Int_t nModules = GetGeometry()->GetNModules();
     859             :   
     860          12 :   for(Int_t iModule=1; iModule<=nModules; iModule++){
     861           5 :     if(!fActiveModule[iModule])
     862             :       continue ;
     863           6 :     modUID = AliGeomManager::LayerToVolUID(idPHOS1,iModule-1);
     864           3 :      if(iModule==4)
     865           0 :       volpath = physModulePath2;
     866             :     else
     867           3 :       if(fActiveCPV[iModule])
     868           0 :         volpath = physModulePath3;
     869             :       else
     870           3 :         volpath = physModulePath;       
     871           3 :     volpath += iModule;
     872             :     //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
     873             :  
     874             :    // Check the volume path if not all 5 modules exist
     875           9 :     if (!gGeoManager->CheckPath(volpath.Data())) {                                                                                         
     876           0 :       AliError(Form("Volume path %s not valid!",volpath.Data()));                                                                          
     877             :       continue;                                                                                                                            
     878             :     }                                                                                                                                      
     879             :  
     880           3 :     symname = symbModuleName;
     881           3 :     symname += iModule;
     882          12 :     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
     883             :       continue ;
     884             : //      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
     885             : 
     886             :     // Creates the Tracking to Local transformation matrix for PHOS modules
     887           3 :     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
     888             : 
     889           6 :     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
     890           3 :     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
     891             : 
     892           6 :     TGeoHMatrix *matTtoL = new TGeoHMatrix;
     893           3 :     matTtoL->RotateZ(-90.+angle);
     894           6 :     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
     895           3 :     alignableEntry->SetMatrix(matTtoL);
     896           3 :   }
     897             : 
     898             :   //Aligning of CPV should be done for volume PCPV_1
     899           1 :   symbModuleName="PHOS/Module";
     900             :   modnum=0;
     901          12 :   for(Int_t iModule=1; iModule<=nModules; iModule++){
     902           5 :     if(!fActiveCPV[iModule])
     903             :       continue ;
     904           0 :     modUID = AliGeomManager::LayerToVolUID(idPHOS2,iModule-1);
     905           0 :     volpath = physModulePath3;
     906           0 :     volpath += iModule;
     907           0 :     volpath += "/PCPV_1";
     908             :     // Check the volume path
     909           0 :     if (!gGeoManager->CheckPath(volpath.Data())) {
     910           0 :       AliError(Form("Volume path %s not valid!",volpath.Data()));
     911             :       continue;
     912             :     }
     913             : 
     914           0 :     symname = symbModuleName;
     915           0 :     symname += iModule;
     916           0 :     symname += "/CPV";
     917           0 :     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
     918           0 :       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
     919             :           
     920             :     // Creates the TGeo Local to Tracking transformation matrix ...
     921           0 :     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
     922             : 
     923           0 :     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
     924           0 :     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
     925             : 
     926           0 :     TGeoHMatrix *matTtoL = new TGeoHMatrix;
     927           0 :     matTtoL->RotateZ(-90.+angle);
     928           0 :     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
     929           0 :     alignableEntry->SetMatrix(matTtoL);
     930             :     
     931           0 :   }
     932             :  
     933             : 
     934             :   // Alignable cradle walls
     935             :   // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
     936             : 
     937           1 :   TString physCradlePath="/ALIC_1/PCRA_";
     938           1 :   TString symbCradleName="PHOS/Cradle";
     939             :   Int_t nCradles = 2;
     940             : 
     941           6 :   for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
     942           2 :     volpath = physCradlePath;
     943           2 :     volpath += iCradle;
     944           2 :     symname = symbCradleName;
     945           2 :     symname += iCradle;
     946           6 :     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
     947             :   }
     948             : 
     949             :   // Alignable wheels
     950             :   // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
     951             : 
     952           1 :   TString physWheelPath="/ALIC_1/PWHE_";
     953           1 :   TString symbWheelName="PHOS/Wheel";
     954             :   Int_t nWheels = 4;
     955             : 
     956          10 :   for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
     957           4 :     volpath = physWheelPath;
     958           4 :     volpath += iWheel;
     959           4 :     symname = symbWheelName;
     960           4 :     symname += iWheel;
     961          12 :     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
     962             :   }
     963             : 
     964             :   
     965             : /*  
     966             :   //Physical strip path is a combination of: physModulePath + module number + 
     967             :   //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
     968             :   const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
     969             :   const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
     970             :   TString partialPhysStripName(100);
     971             :   TString fullPhysStripName(100);
     972             :   TString partialSymbStripName(100);
     973             :   TString fullSymbStripName(100);
     974             : 
     975             :   for(Int_t module = 1; module <= nModules; ++module){
     976             : 
     977             :     snprintf(im,5,"%d",module) ;
     978             :     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
     979             :       continue ;
     980             : 
     981             :     volpath = physModulePath;
     982             :     volpath += module;
     983             :     // Check the volume path if not all 5 modules exist
     984             :     if (!gGeoManager->CheckPath(volpath.Data())) {
     985             :       AliError(Form("Volume path %s does not exist",volpath.Data())) ;
     986             :       continue;
     987             :     }
     988             : 
     989             :     partialPhysStripName  = physModulePath;
     990             :     partialPhysStripName += module;
     991             :     if(module!=4)
     992             :       partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
     993             :     else
     994             :       partialPhysStripName += "/PEMH_1/PCLH_1/PIOH_1/PCOH_1/PAGH_1/PTIH_1/PSTR_";
     995             : 
     996             :     partialSymbStripName  = symbModuleName;
     997             :     partialSymbStripName += module;
     998             :     partialSymbStripName += "/Strip_";
     999             : 
    1000             :     for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
    1001             :       for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
    1002             :          fullPhysStripName = partialPhysStripName;
    1003             :          fullPhysStripName += ind1D;
    1004             :          
    1005             :          fullSymbStripName  = partialSymbStripName;
    1006             :          fullSymbStripName += i;//ind1D;
    1007             :          fullSymbStripName += '_';
    1008             :          fullSymbStripName += j;
    1009             : 
    1010             :          gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
    1011             : 
    1012             :          // Creates the TGeo Local to Tracking transformation matrix ...
    1013             :          TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
    1014             :          const char *path = alignableEntry->GetTitle();
    1015             :          if (!gGeoManager->cd(path))
    1016             :            AliFatal(Form("Volume path %s not valid!",path));
    1017             :          TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
    1018             :          Double_t refl[3]={-1.,-1.,-1.} ;
    1019             :          matLtoT.SetScale(refl) ;
    1020             :          TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
    1021             :  
    1022             :          char phosPath[50] ;
    1023             :          snprintf(phosPath,50,"/ALIC_1/PHOS_%d",module) ;
    1024             :          if (!gGeoManager->cd(phosPath)){
    1025             :             AliFatal("Geo manager can not find path \n");
    1026             :          }
    1027             :          TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
    1028             :          if (mPHOS) 
    1029             :            matTtoL->Multiply(mPHOS);
    1030             :          else{
    1031             :            AliFatal("Geo matrixes are not loaded \n") ;
    1032             :          }
    1033             :          //Switch y<->z
    1034             :          Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
    1035             :          matTtoL->SetRotation(rot) ;
    1036             :          alignableEntry->SetMatrix(matTtoL);
    1037             : */
    1038             : /*
    1039             :   //Check poisition of corner cell of the strip
    1040             :   AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
    1041             :   Int_t relid[4] ; 
    1042             :   relid[0] = module ;
    1043             :   relid[1] = 0 ;
    1044             :   Int_t iStrip=ind1D ;
    1045             :   Int_t icell=1 ;
    1046             :   Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
    1047             :                 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
    1048             :   Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
    1049             :                 (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
    1050             :   if(col==0) col=geom->GetNZ() ;
    1051             :   relid[2] = raw ;
    1052             :   relid[3] = col ;
    1053             :   Float_t xG,zG ; 
    1054             :   geom->RelPosInModule(relid, xG, zG) ;
    1055             : printf("============\n") ;
    1056             : printf("Geometry: x=%f, z=%f \n",xG,zG) ;
    1057             :   Int_t absid ; 
    1058             :   geom->RelToAbsNumbering(relid,absid) ;
    1059             :   Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
    1060             :   Double_t posC[3]={0.0,0.0,0.}; //Global position
    1061             :  
    1062             :   matTtoL->MasterToLocal(pos,posC);
    1063             : printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
    1064             : */
    1065             : //      }
    1066             : //    }
    1067             : //  }
    1068           1 : }
    1069             : 
    1070             : //____________________________________________________________________________
    1071             : Float_t AliPHOSv0::ZMin(void) const
    1072             : {
    1073             :   // Overall dimension of the PHOS (min)
    1074             : 
    1075           0 :   AliPHOSGeometry * geom = GetGeometry() ; 
    1076             : 
    1077           0 :   return -geom->GetOuterBoxSize(2)/2.;
    1078             : }
    1079             : 
    1080             : //____________________________________________________________________________
    1081             : Float_t AliPHOSv0::ZMax(void) const
    1082             : {
    1083             :   // Overall dimension of the PHOS (max)
    1084             : 
    1085           0 :   AliPHOSGeometry * geom = GetGeometry() ; 
    1086             : 
    1087           0 :   return  geom->GetOuterBoxSize(2)/2.;
    1088             : }
    1089             : 
    1090             : //____________________________________________________________________________
    1091             : void AliPHOSv0::Init(void)
    1092             : {
    1093             :   // Just prints an information message
    1094             :   
    1095             :   Int_t i;
    1096             : 
    1097           2 :   if(AliLog::GetGlobalDebugLevel()>0) {
    1098           0 :     TString st ; 
    1099           0 :     for(i=0;i<35;i++) 
    1100           0 :       st += "*";
    1101           0 :     Info("Init", "%s", st.Data()) ;  
    1102             :     // Here the PHOS initialisation code (if any!)
    1103             :     
    1104           0 :     AliPHOSGeometry * geom = GetGeometry() ; 
    1105             : 
    1106           0 :     if (geom!=0)  
    1107           0 :       Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
    1108             :     else
    1109           0 :       Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;       
    1110             : 
    1111           0 :     Info("Init", "%s", st.Data()) ;  
    1112           0 :   }
    1113           1 : }

Generated by: LCOV version 1.11