Overlaps and extrrusions in the volume PWTI are fixed
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv0.cxx
index f92eb58..27a2bda 100644 (file)
 /* 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
  *
 #include <TTRD1.h>
 #include <TTree.h>
 #include <TVirtualMC.h>
+#include <TGeoPhysicalNode.h>
 #include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TVector3.h>
 
 // --- Standard library ---
 
 #include "AliPHOSv0.h"
 #include "AliRun.h"
 #include "AliLog.h"
+#include "AliGeomManager.h"
 
 ClassImp(AliPHOSv0)
 
@@ -332,16 +373,21 @@ 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] ;
   Int_t iXYZ,iAngle;
-  for (Int_t iModule = 0; iModule < geom->GetNModules(); iModule++ ) {
-    
+  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++)
@@ -357,7 +403,8 @@ void AliPHOSv0::CreateGeometry()
     gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
               idrotm[iModule], "ONLY") ;
   }
-
+  if(!anyModuleCreated)
+    AliError("No one PHOS module was created") ;
 }
 
 //____________________________________________________________________________
@@ -389,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() ; 
@@ -402,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") ;
       
@@ -419,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 ----
@@ -525,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) ; 
@@ -559,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") ;
 
@@ -883,18 +934,86 @@ void AliPHOSv0::AddAlignableVolumes() const
 
   // 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;
-    gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+    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
@@ -926,8 +1045,105 @@ void AliPHOSv0::AddAlignableVolumes() const
     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
   }
 
-  // Alignable strip units are not implemented yet (27.09.2006)
+  //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]) ;
+*/
+      }
+    }
+  }
 }
 
 //____________________________________________________________________________