]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PHOS/AliPHOSv0.cxx
Number of ALTRO samples is reduced to 100
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv0.cxx
index 51c8906be2e3cecf8ab123d1edadeb5048a04481..27a2bdaeb2058927828c6d1b32389068d4f94765 100644 (file)
  **************************************************************************/
 /* $Id$ */
 
+/* History of cvs commits:
+ *
+ * $Log$
+ * Revision 1.94  2007/10/18 08:40:02  kharlov
+ * Misalignment-related bug fixed
+ *
+ * Revision 1.93  2007/10/06 22:24:40  kharlov
+ * Bug in strip unit geometry is corrected
+ *
+ * Revision 1.92  2007/07/04 16:38:19  policheh
+ * Tracking2LocalCS matrices corrected for CPV.
+ *
+ * Revision 1.91  2007/07/02 14:50:49  policheh
+ * Tracking2LocalCS matrices corrected.
+ *
+ * Revision 1.90  2007/05/24 13:04:05  policheh
+ * AddAlignableVolumes: local to tracking CS transformation matrices creates for each
+ * PHOS supermodule
+ *
+ * Revision 1.89  2007/04/24 14:34:39  hristov
+ * Additional protection: do not search for alignable object if the CPV is not in the geometry
+ *
+ * Revision 1.88  2007/04/19 15:28:30  kharlov
+ * Modify strip unit geometry according to the final drawings (Timur)
+ *
+ * Revision 1.87  2007/04/01 07:37:10  kharlov
+ * TGeo RS to Local RS transf matr added
+ *
+ * Revision 1.86  2007/03/06 06:55:46  kharlov
+ * DP:Misalignment of CPV added
+ *
+ * Revision 1.85  2007/03/01 11:37:37  kharlov
+ * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
+ *
+ * Revision 1.84  2006/12/20 16:56:43  kharlov
+ * Optional geometry without CPV
+ *
+ * Revision 1.83  2006/11/14 17:11:15  hristov
+ * 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
+ *
+ * Revision 1.82  2006/09/27 19:55:57  kharlov
+ * Alignment object with symbolic volume names are introduced
+ *
+ * Revision 1.81  2006/03/04 20:25:56  kharlov
+ * Set geom parameters from CDB
+ *
+ * Revision 1.80  2005/06/17 07:39:07  hristov
+ * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
+ *
+ * Revision 1.79  2005/05/28 14:19:05  schutz
+ * Compilation warnings fixed by T.P.
+ *
+ */
 
 //_________________________________________________________________________
 // Implementation version v0 of PHOS Manager class 
 
 // --- ROOT system ---
 
-#include "TBRIK.h"
-#include "TTRD1.h"
-#include "TNode.h"
-#include "TRandom.h"
-#include "TGeometry.h"
-#include "TFolder.h"
-#include "TROOT.h"
-#include "TTree.h"
-
+#include <TBRIK.h>
+#include <TFolder.h>
+#include <TGeometry.h>
+#include <TNode.h>
+#include <TROOT.h>
+#include <TRandom.h>
+#include <TTRD1.h>
+#include <TTree.h>
+#include <TVirtualMC.h>
+#include <TGeoPhysicalNode.h>
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TVector3.h>
 
 // --- Standard library ---
 
 
 // --- AliRoot header files ---
 
-#include "AliPHOSv0.h"
-#include "AliRun.h"
 #include "AliConst.h"
-#include "AliMC.h"
 #include "AliPHOSGeometry.h"
-#include "AliPHOSGetter.h"
+#include "AliPHOSLoader.h"
+#include "AliPHOSv0.h"
+#include "AliRun.h"
+#include "AliLog.h"
+#include "AliGeomManager.h"
 
 ClassImp(AliPHOSv0)
 
@@ -106,7 +164,7 @@ void AliPHOSv0:: BuildGeometryforEMC(void)
   const Int_t kColorPHOS = kRed ;
   const Int_t kColorXTAL = kBlue ;
   
-  Double_t const kRADDEG = 180.0 / kPI ;
+  Double_t const kRADDEG = 180.0 / TMath::Pi() ;
   
   AliPHOSGeometry * geom = GetGeometry() ; 
   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
@@ -186,7 +244,7 @@ void AliPHOSv0:: BuildGeometryforCPV(void)
   */
   //END_HTML  
 
-  const Double_t kRADDEG         = 180.0 / kPI ;
+  const Double_t kRADDEG         = 180.0 / TMath::Pi() ;
   const Int_t    kColorCPV       = kGreen ;
   const Int_t    kColorFrame     = kYellow ;
   const Int_t    kColorGassiplex = kRed;
@@ -315,30 +373,38 @@ void AliPHOSv0::CreateGeometry()
   
   this->CreateGeometryforEMC() ; 
 
-  this->CreateGeometryforCPV() ;
+  if (strstr(fTitle.Data(),"noCPV") == 0) 
+    this->CreateGeometryforCPV() ;
   
   this->CreateGeometryforSupport() ; 
   
   // --- Position  PHOS mdules in ALICE setup ---
-  
   Int_t idrotm[99] ;
-  Double_t const kRADDEG = 180.0 / kPI ;
-  Float_t * phosParams = geom->GetPHOSParams() ;
-
-  Float_t r = geom->GetIPtoOuterCoverDistance() + phosParams[3] - geom->GetCPVBoxSize(1) ;
-  Int_t i;
-  for( i = 1; i <= geom->GetNModules()  ; i++ ) {
-    
-    Float_t angle = geom->GetPHOSAngle(i) ;
-    AliMatrix(idrotm[i-1], 90.,angle, 0., 0., 90., 270. +angle) ;
-    
-    Float_t xP1 =  r * TMath::Sin( angle / kRADDEG ) ;
-    Float_t yP1 = -r * TMath::Cos( angle / kRADDEG ) ;
-    
-    gMC->Gspos("PHOS", i, "ALIC", xP1, yP1, 0.0, idrotm[i-1], "ONLY") ;
+  Int_t iXYZ,iAngle;
+  char im[5] ;
+  Bool_t anyModuleCreated=0 ;
+  for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
+    sprintf(im,"%d",iModule+1) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+    anyModuleCreated=1 ;
+    Float_t angle[3][2];
+    for (iXYZ=0; iXYZ<3; iXYZ++)
+      for (iAngle=0; iAngle<2; iAngle++)
+       angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
+    AliMatrix(idrotm[iModule],
+             angle[0][0],angle[0][1],
+             angle[1][0],angle[1][1],
+             angle[2][0],angle[2][1]) ;
     
-  } 
-
+    Float_t pos[3];
+    for (iXYZ=0; iXYZ<3; iXYZ++)
+      pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
+    gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
+              idrotm[iModule], "ONLY") ;
+  }
+  if(!anyModuleCreated)
+    AliError("No one PHOS module was created") ;
 }
 
 //____________________________________________________________________________
@@ -370,12 +436,13 @@ void AliPHOSv0::CreateGeometryforEMC()
 
   // ======= Define the strip ===============
 
-  gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ;  //Made of stell
+  gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ;  //Made of steel
    
-      // --- define air volume (cell of the honeycomb)
+      // --- define steel volume (cell of the strip unit)
+//       gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetSteelCellHalfSize(), 3);
       gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
 
-      // --- define wrapped crystal and put it into AirCell
+      // --- define wrapped crystal and put it into steel cell
 
       gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
       Float_t * pin = emcg->GetAPDHalfSize() ; 
@@ -383,7 +450,7 @@ void AliPHOSv0::CreateGeometryforEMC()
       Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
       gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
     
-      // --- Define crystall and put it into wrapped crystall ---
+      // --- Define crystal and put it into wrapped crystall ---
       gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
       gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
       
@@ -400,15 +467,18 @@ void AliPHOSv0::CreateGeometryforEMC()
       gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;                    // to ceramics?
    
 
-      // --- Fill strip with wrapped cristalls in Air Cells
+      // --- Fill strip with wrapped cristals in steel cells
 
       Float_t* splate = emcg->GetSupportPlateHalfSize();  
       y = -splate[1] ;
+//       Float_t* acel = emcg->GetSteelCellHalfSize() ;
       Float_t* acel = emcg->GetAirCellHalfSize() ;
-      Int_t icel ;
-      for(icel = 1; icel <= emcg->GetNCellsInStrip(); icel++){
-       Float_t x = (2*icel - 1 - emcg->GetNCellsInStrip())* acel[0] ;
-       gMC->Gspos("PCEL", icel, "PSTR", x, y, 0.0, 0, "ONLY") ;
+
+      for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
+         Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
+         Float_t z = acel[2];
+         gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
+         gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
       }
 
       // --- define the support plate, hole in it and position it in strip ----
@@ -506,7 +576,7 @@ void AliPHOSv0::CreateGeometryforEMC()
        gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
       }
 
-      z = -warmthermo[2] + cbox[2] ;
+      z = -warmthermo[2] + cbox[2];
       gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
 
       gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ; 
@@ -540,7 +610,7 @@ void AliPHOSv0::CreateGeometryforEMC()
       gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
 
       gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ; 
-      posit = emcg->GetFGupZPosition() ;
+      posit = emcg->GetFGupZPosition();
       gMC->Gspos("PFG2", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
       gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
 
@@ -815,7 +885,7 @@ void AliPHOSv0::CreateGeometryforSupport()
   par[4] =  geom->GetCradleWall(4) ;
   gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
 
-  par[0] -=  geom->GetCradleWallThickness() ;
+  par[0] +=  geom->GetCradleWallThickness() ;
   par[1] -=  geom->GetCradleWallThickness() ;
   par[2] -=  geom->GetCradleWallThickness() ;
   gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
@@ -847,6 +917,235 @@ void AliPHOSv0::CreateGeometryforSupport()
 
 }
 
+//_____________________________________________________________________________
+void AliPHOSv0::AddAlignableVolumes() const
+{
+  //
+  // Create entries for alignable volumes associating the symbolic volume
+  // name with the corresponding volume path. Needs to be syncronized with
+  // eventual changes in the geometry
+  // Alignable volumes are:
+  // 1) PHOS modules as a whole
+  // 2) Cradle
+  // 3) Cradle wheels
+  // 4) Strip units (group of 2x8 crystals)
+
+  TString volpath, symname;
+
+  // Alignable modules
+  // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
+  
+  AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
+  AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
+  Int_t modUID, modnum = 0;
+  TString physModulePath="/ALIC_1/PHOS_";
+  TString symbModuleName="PHOS/Module";
+  Int_t nModules = GetGeometry()->GetNModules();
+  
+  char im[5] ;
+  for(Int_t iModule=1; iModule<=nModules; iModule++){
+    sprintf(im,"%d",iModule) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+    modUID = AliGeomManager::LayerToVolUID(idPHOS1,modnum++);
+    volpath = physModulePath;
+    volpath += iModule;
+    //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
+   // Check the volume path if not all 5 modules exist
+    if (!gGeoManager->CheckPath(volpath.Data())) {                                                                                         
+      AliError(Form("Volume path %s not valid!",volpath.Data()));                                                                          
+      continue;                                                                                                                            
+    }                                                                                                                                      
+    symname = symbModuleName;
+    symname += iModule;
+    if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
+      continue ;
+//      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
+
+    // Creates the Tracking to Local transformation matrix for PHOS modules
+    TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
+
+    Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
+    TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
+
+    TGeoHMatrix *matTtoL = new TGeoHMatrix;
+    matTtoL->RotateZ(-90.+angle);
+    matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+    alignableEntry->SetMatrix(matTtoL);
+  }
+
+  //Aligning of CPV should be done for volume PCPV_1
+  symbModuleName="PHOS/Module";
+  modnum=0;
+  for(Int_t iModule=1; iModule<=nModules; iModule++){
+    if(strstr(GetTitle(),"noCPV"))
+      continue ;
+    sprintf(im,"%d",iModule) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0)
+      continue ;
+    modUID = AliGeomManager::LayerToVolUID(idPHOS2,modnum++);
+    volpath = physModulePath;
+    volpath += iModule;
+    volpath += "/PCPV_1";
+    // Check the volume path
+    if (!gGeoManager->CheckPath(volpath.Data())) {
+      AliError(Form("Volume path %s not valid!",volpath.Data()));
+      continue;
+    }
+
+    symname = symbModuleName;
+    symname += iModule;
+    symname += "/CPV";
+    if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
+      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
+          
+    // Creates the TGeo Local to Tracking transformation matrix ...
+    TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
+
+    Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
+    TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
+
+    TGeoHMatrix *matTtoL = new TGeoHMatrix;
+    matTtoL->RotateZ(-90.+angle);
+    matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+    alignableEntry->SetMatrix(matTtoL);
+    
+  }
+
+  // Alignable cradle walls
+  // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
+
+  TString physCradlePath="/ALIC_1/PCRA_";
+  TString symbCradleName="PHOS/Cradle";
+  Int_t nCradles = 2;
+
+  for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
+    volpath = physCradlePath;
+    volpath += iCradle;
+    symname = symbCradleName;
+    symname += iCradle;
+    gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+  }
+
+  // Alignable wheels
+  // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
+
+  TString physWheelPath="/ALIC_1/PWHE_";
+  TString symbWheelName="PHOS/Wheel";
+  Int_t nWheels = 4;
+
+  for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
+    volpath = physWheelPath;
+    volpath += iWheel;
+    symname = symbWheelName;
+    symname += iWheel;
+    gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+  }
+
+  //Physical strip path is a combination of: physModulePath + module number + 
+  //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
+  const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
+  const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
+  TString partialPhysStripName(100);
+  TString fullPhysStripName(100);
+  TString partialSymbStripName(100);
+  TString fullSymbStripName(100);
+
+  for(Int_t module = 1; module <= nModules; ++module){
+
+    sprintf(im,"%d",module) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+
+    volpath = physModulePath;
+    volpath += module;
+    // Check the volume path if not all 5 modules exist
+    if (!gGeoManager->CheckPath(volpath.Data())) {
+      AliError(Form("Volume path %s does not exist",volpath.Data())) ;
+      continue;
+    }
+
+    partialPhysStripName  = physModulePath;
+    partialPhysStripName += module;
+    partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
+
+    partialSymbStripName  = symbModuleName;
+    partialSymbStripName += module;
+    partialSymbStripName += "/Strip_";
+
+    for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
+      for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
+         fullPhysStripName = partialPhysStripName;
+         fullPhysStripName += ind1D;
+         
+         fullSymbStripName  = partialSymbStripName;
+         fullSymbStripName += i;//ind1D;
+         fullSymbStripName += '_';
+         fullSymbStripName += j;
+
+         gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
+
+         // Creates the TGeo Local to Tracking transformation matrix ...
+         TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
+         const char *path = alignableEntry->GetTitle();
+         if (!gGeoManager->cd(path))
+           AliFatal(Form("Volume path %s not valid!",path));
+         TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
+         Double_t refl[3]={-1.,-1.,-1.} ;
+         matLtoT.SetScale(refl) ;
+         TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
+         char phosPath[50] ;
+         sprintf(phosPath,"/ALIC_1/PHOS_%d",module) ;
+         if (!gGeoManager->cd(phosPath)){
+            AliFatal("Geo manager can not find path \n");
+         }
+         TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+         if (mPHOS) 
+           matTtoL->Multiply(mPHOS);
+         else{
+           AliFatal("Geo matrixes are not loaded \n") ;
+         }
+         //Switch y<->z
+         Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
+         matTtoL->SetRotation(rot) ;
+         alignableEntry->SetMatrix(matTtoL);
+
+/*
+  //Check poisition of corner cell of the strip
+  AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
+  Int_t relid[4] ; 
+  relid[0] = module ;
+  relid[1] = 0 ;
+  Int_t iStrip=ind1D ;
+  Int_t icell=1 ;
+  Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
+                1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
+  Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
+                (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
+  if(col==0) col=geom->GetNZ() ;
+  relid[2] = raw ;
+  relid[3] = col ;
+  Float_t xG,zG ; 
+  geom->RelPosInModule(relid, xG, zG) ;
+printf("============\n") ;
+printf("Geometry: x=%f, z=%f \n",xG,zG) ;
+  Int_t absid ; 
+  geom->RelToAbsNumbering(relid,absid) ;
+  Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
+  Double_t posC[3]={0.0,0.0,0.}; //Global position
+  matTtoL->MasterToLocal(pos,posC);
+printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
+*/
+      }
+    }
+  }
+}
+
 //____________________________________________________________________________
 Float_t AliPHOSv0::ZMin(void) const
 {
@@ -874,7 +1173,7 @@ void AliPHOSv0::Init(void)
   
   Int_t i;
 
-  if(fDebug) {
+  if(AliLog::GetGlobalDebugLevel()>0) {
     TString st ; 
     for(i=0;i<35;i++) 
       st += "*";