]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCParam.cxx
Fixed problem with z length mismatch (Marian, Marek)
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.cxx
index f484b7f9083c026e3dfd99519b530a527b98960a..ff15faf3143444b283c9ec804a8548999b49fdd9 100644 (file)
@@ -1,3 +1,20 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
 ///////////////////////////////////////////////////////////////////////
 //  Manager and of geomety  classes for set: TPC                     //
 //                                                                   //
 //                                                                   //  
 ///////////////////////////////////////////////////////////////////////
 
+//
 
-#include <iostream.h>
-#include <TMath.h>
-#include <TObject.h>
-#include "AliTPCSecGeo.h"
 #include <AliTPCParam.h>
 
+#include <TGeoManager.h>
+#include <TGeoPhysicalNode.h>
+#include "AliAlignObj.h"
+#include "AliAlignObjParams.h"
+#include "AliLog.h"
 
 ClassImp(AliTPCParam)
 
-const static  Int_t kMaxRows=600;
 
+//___________________________________________
+AliTPCParam::AliTPCParam()
+            :AliDetectorParam(),
+            fbStatus(kFALSE),
+             fInnerRadiusLow(0.),
+             fInnerRadiusUp(0.),
+             fOuterRadiusUp(0.),
+             fOuterRadiusLow(0.),
+            fInnerAngle(0.),
+            fInnerAngleShift(0.),
+            fOuterAngle(0.),
+            fOuterAngleShift(0.),
+            fInnerFrameSpace(0.),
+            fOuterFrameSpace(0.),
+            fInnerWireMount(0.),
+            fOuterWireMount(0.),
+            fNInnerSector(0),
+            fNOuterSector(0),
+            fNSector(0),
+            fZLength(0),
+            fRotAngle(),
+            fGeometryType(0),
+            fTrackingMatrix(0),
+            fClusterMatrix(0), 
+            fGlobalMatrix(0),
+            fNInnerWiresPerPad(0),
+            fInnerWWPitch(0),
+            fInnerDummyWire(0),
+            fInnerOffWire(0.),
+            fRInnerFirstWire(0.),
+            fRInnerLastWire(0.),
+            fLastWireUp1(0.),
+            fNOuter1WiresPerPad(0),
+            fNOuter2WiresPerPad(0),
+            fOuterWWPitch(0.),
+            fOuterDummyWire(0),
+            fOuterOffWire(0.),
+            fROuterFirstWire(0.),
+            fROuterLastWire(0.),
+            fInnerPadPitchLength(0.),
+            fInnerPadPitchWidth(0.),
+            fInnerPadLength(0.),
+            fInnerPadWidth(0.),
+            fOuter1PadPitchLength(0.),
+            fOuter2PadPitchLength(0.),
+            fOuterPadPitchWidth(0.),
+            fOuter1PadLength(0.),
+            fOuter2PadLength(0.),
+            fOuterPadWidth(0.),
+            fBMWPCReadout(kFALSE),
+            fNCrossRows(0),
+            fNRowLow(0),
+            fNRowUp1(0),
+            fNRowUp2(0),
+            fNRowUp(0),
+            fNtRows(0),
+            fDiffT(0.),
+            fDiffL(0.),
+            fGasGain(0.),
+            fDriftV(0.),
+            fOmegaTau(0.),
+            fAttCoef(0.),
+            fOxyCont(0.),
+            fPadCoupling(0.),
+            fZeroSup(0),
+            fNoise(0.),
+            fChipGain(0.),
+            fChipNorm(0.),
+            fTSample(0.),
+            fZWidth(0.),
+            fTSigma(0.),
+            fMaxTBin(0),
+            fADCSat(0),
+            fADCDynRange(0.),
+            fTotalNormFac(0.),
+            fNoiseNormFac(0.),
+            fNResponseMax(0),
+            fResponseThreshold(0.),
+            fCurrentMax(0),
+            fResponseBin(0),
+            fResponseWeight(0),
+            fGateDelay(0.),
+            fL1Delay(0.),
+            fNTBinsBeforeL1(0),
+            fNTBinsL1(0.)   
+{   
+  //
+  //constructor sets the default parameters
+  //
+
+  SetTitle("75x40_100x60_150x60");
+  SetDefault();  
+}
+
+AliTPCParam::~AliTPCParam()
+{
+  //
+  //destructor deletes some dynamicaly alocated variables
+  //
+
+  if (fResponseBin!=0)    delete [] fResponseBin;
+  if (fResponseWeight!=0) delete [] fResponseWeight;
+  if (fRotAngle      !=0) delete [] fRotAngle;
 
-// default values  
-const static   Int_t kMaxTBin =512; 
+  if (fTrackingMatrix) {
+    for(Int_t i = 0; i < fNSector; i++)
+      delete fTrackingMatrix[i];
+    delete [] fTrackingMatrix;
+  }
 
+  if (fClusterMatrix) {
+    for(Int_t i = 0; i < fNSector; i++)
+      delete fClusterMatrix[i];
+    delete [] fClusterMatrix;
+  }
 
-const static  Float_t kInnerRadiusLow = 89.45;
-const static  Float_t kOuterRadiusLow = 143.725;
-const static  Float_t kInnerRadiusUp  = 134.55;
-const static  Float_t kOuterRadiusUp  = 248.275;
+  if (fGlobalMatrix) {
+    for(Int_t i = 0; i < fNSector; i++)
+      delete fGlobalMatrix[i];
+    delete [] fGlobalMatrix;
+  }
 
-const static  Float_t kInnerAngle = 0.523598775; // 30 degrees
-const static  Float_t kInnerAngleShift = 0;
-const static  Float_t kOuterAngle = 0.261799387; //  15 degrees
-const static  Float_t kOuterAngleShift = 0;
+}
 
-const static Float_t kPadPitchLength = 2.05;
-const static Float_t kPadPitchWidth = 0.35;
-const static Float_t kPadLength = 2.05;
-const static Float_t kPadWidth = 0.35;
 
-//  Number of wires per pad and wire-wire pitch
-const static Int_t knWires = 5;
-const static  Float_t  kDiffT = 2.2e-2; 
-const static  Float_t  kDiffL = 2.2e-2; 
-const static  Float_t  kDriftV  =2.85e6;
 
-const static  Float_t  kOmegaTau = 0.145;
-const static  Float_t  kAttCoef = 250.;
-const static  Float_t  kOxyCont = 5.e-6;
 
+Int_t  AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index)  const
+{
+  //
+  // calculates sector number (index[1], undefined on input)
+  // xyz intact
+  //
 
-const static  Float_t  kChipGain = 24;
-const static  Float_t  kGasGain = 1e4;
-const static  Float_t  kTSample = 2.e-7; //TSAMPLE
-const static  Float_t  kTFWHM   = 2.5e-7;  //fwhm of charge distribution
+  Float_t angle,x1;
+  Int_t sector;
+  Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
+  if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
+  else
+    {
+      angle =TMath::ASin(xyz[1]/r);
+      if   (xyz[0]<0)   angle=TMath::Pi()-angle;
+      if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
+    }
+
+  sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));      
  
-const static  Float_t  kNoise = 500;  //default noise = 1000 el 
-const static  Int_t    kZeroSup=5;
-const static  Float_t  kPadCoupling=0.5;
-// 
-const static  Float_t  kEdgeSectorSpace = 1.15;
-const static  Float_t  kDegtoRad = 0.01745329251994;
-const static  Float_t  kRadtoDeg = 57.29577951309;
+  Float_t cos,sin;
+  AdjustCosSin(sector,cos,sin);
+  x1=xyz[0]*cos + xyz[1]*sin;
 
+  if (x1>fOuterRadiusLow)
+    {
+      sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
+      if (xyz[2]<0)    sector+=(fNOuterSector>>1);            
+    }
+    else   
+      if (xyz[2]<0) sector+=(fNInnerSector>>1);    
+  index[1]=sector; // calculated sector number
+  index[0]=1; // indicates system after transformation
+  return sector;
+}
 
+Bool_t  AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
+{
+  //transformation from input coodination system to output coordination system
+  switch (index[0]){
+  case 0:
+    break;
+  };
 
+  return kFALSE;
 
-//___________________________________________
-AliTPCParam::AliTPCParam()
-{   
-  //constructor set the default parameters
-  SetDefault();  
 }
 
+Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const 
+{
+  //
+  //calculates pad row of point xyz - transformation to system 8 (digit system)
+  //
+  Int_t system = index[0];
+  if (0==system) {
+    Transform0to1(xyz,index); 
+    system=1;
+  }
+  if (1==system) {
+    Transform1to2(xyz,index); 
+    system=2;
+  }
+    
+  if (fGeometryType==0){ //straight row    
+    if (2==system) {
+      Transform2to3(xyz,index);       
+      system=3;
+    } 
+    if (3==system) {
+      Transform3to4(xyz,index);
+      system=4; 
+    }
+    if (4==system) {
+      Transform4to8(xyz,index);
+      system=8;     
+    }
+    if (8==system) {
+      index[0]=8;
+      return index[2];
+    } 
+  }
+
+  if (fGeometryType==1){ //cylindrical geometry    
+    if (2==system) {
+      Transform2to5(xyz,index);       
+      system=5;
+    } 
+    if (5==system) {
+      Transform2to3(xyz,index);
+      system=6;
+    }
+    if (6==system) {
+      Transform3to4(xyz,index); 
+      system=7;
+    }
+    if (8==system) {
+      index[0]=8;
+      return index[2];
+    }
+  } 
+  index[0]=system;
+  return -1; //if no reasonable system     
+}
 
 void  AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
-                       Float_t outershift, Bool_t inDegree)
+                       Float_t outershift)
 {
   //
   // set opening angles  
+  static const  Float_t  kDegtoRad = 0.01745329251994;
   fInnerAngle = innerangle;       //opening angle of Inner sector
   fInnerAngleShift = innershift;  //shift of first inner sector center to the 0
   fOuterAngle = outerangle;       //opening angle of outer sector
   fOuterAngleShift = outershift;  //shift of first sector center to the 0  
-  if (inDegree==kTRUE){
-    fInnerAngle *=kDegtoRad;
-    fInnerAngleShift *=kDegtoRad;
-    fOuterAngle *=kDegtoRad;
-    fOuterAngleShift *=kDegtoRad;
-  }    
-}
-
-
-void AliTPCParam::CRXYZtoXYZ(Float_t *xyz,
-              const Int_t &sector, const Int_t & padrow, Int_t option) const  
-{  
-  //transform relative coordinates to absolute
-  Bool_t rel = ( (option&2)!=0);
-  Float_t row_first; 
-  row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0]; 
-  if (rel==kTRUE)  //if the position is relative to pad row  
-    {
-      xyz[0]+=row_first;
-      xyz[0]+=(Int_t) padrow*fPadPitchLength;
-    }  
-
-  xyz[2]=z_end-xyz[2];
-  if (sector<fNInnerSector)
-    if ( sector>=(fNInnerSector>>1))   xyz[2]*=-1.;
-  else 
-    if ( (sector-fNInnerSector) > (fNOuterSector>>1) )    xyz[2]*=-1;       
-  
-  Float_t x1=xyz[0];
-  Float_t y1=xyz[1];
-  Float_t cos,sin;
-  AdjustAngles(sector,cos,sin);
-  xyz[0]= x1*cos - y1*sin;
-  xyz[1]= x1*sin + y1*cos;
+  fInnerAngle *=kDegtoRad;
+  fInnerAngleShift *=kDegtoRad;
+  fOuterAngle *=kDegtoRad;
+  fOuterAngleShift *=kDegtoRad;
 }
 
-void AliTPCParam::XYZtoCRXYZ(Float_t *xyz,
-                            Int_t &sector, Int_t & padrow, Int_t option)
+Float_t  AliTPCParam::GetInnerAngle() const
 {
-   //transform global position to the position relative to the sector padrow
-  //if option=0  X calculate absolute            calculate sector
-  //if option=1  X           absolute            use input sector
-  //if option=2  X           relative to pad row calculate sector
-  //if option=3  X           relative            use input sector
-  //!!!!!!!!! WE start to calculate rows from row = 0
-  
-  Bool_t rel = ( (option&2)!=0);  
-  //option 0 and 2  means that we don't have information about sector
-  //we calculate sector
-  if ((option&1)==0){
-    Float_t angle;
-    Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
-    if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0;
-    else
-      {
-       angle =TMath::ASin(xyz[1]/r);
-       if   (xyz[0]<0)   angle=TMath::Pi()-angle;
-       if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
-      }
-    //transform global position to the position relative to the sector padrow
-    //fistly calculate xyz[0] radius  for lover sector
-    //bacause in this moment we dont know in which sector we are
-    sector=Int_t((angle-fInnerAngleShift)/fInnerAngle);      
-    Float_t x1;
-    Float_t y1;
-    //firstly we suppose that we are in inner sector
-    Float_t cos,sin;
-    AdjustAngles(sector,cos,sin);
-
-    x1=xyz[0]*cos + xyz[1]*sin;
-    y1=-xyz[0]*sin + xyz[1]*cos;
-    if (x1>fOuterRadiusLow)
-      {
-       sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
-       AdjustAngles(sector,cos,sin);        
-       x1=xyz[0]*cos + xyz[1]*sin;
-       y1=-xyz[0]*sin + xyz[1]*cos;      
-       if (xyz[2]<0)   sector+=(fNOuterSector>>1);            
-      }
-    else   
-      if (xyz[2]<0) sector+=(fNInnerSector>>1);    
+  //return angle 
+  return fInnerAngle;
 
-  if  (x1<fOuterRadiusLow)   
-    padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+0.5);
-  else
-    padrow = Int_t( (x1-fPadRowUp[0])/fPadPitchLength+0.5);
-  if (rel==kTRUE)
-      if (x1<fOuterRadiusLow)   x1-=padrow*fPadPitchLength+fPadRowLow[0];
-      else
-       x1-=padrow*fPadPitchLength+fPadRowUp[0];  
-   xyz[0]=x1;
-   xyz[1]=y1;    
-   xyz[2]=z_end-TMath::Abs(xyz[2]);  
-  }   //endif we don't have information about sector
-  else{
-    //if we have information about sector
-    Float_t cos,sin;
-    AdjustAngles(sector,cos,sin);   
-    Float_t x1;
-    Float_t y1;
-    //rotate to given sector
-    x1=xyz[0]*cos + xyz[1]*sin;
-    y1=-xyz[0]*sin + xyz[1]*cos; 
-    //calculate pad row number
-    if (sector<fNInnerSector) {
-      padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
-    }
-    else {
-      padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
-    }
-    //if we store relative position calculate position relative to pad row
-    if (rel==kTRUE){
-      if (sector<fNInnerSector)
-       x1-=padrow*fPadPitchLength+fPadRowLow[0];
-      else 
-       x1-=padrow*fPadPitchLength+fPadRowUp[0];
-    }      
-    xyz[0]=x1;
-    xyz[1]=y1;
-    xyz[2]=z_end-TMath::Abs(xyz[2]);  
-  }
 }
 
-void AliTPCParam::CRYZtoTimePad(const Float_t &y, const Float_t &z,
-                               Float_t &time, Float_t &pad,
-                               Int_t sector, Int_t padrow)
-{
-  //transform position in cm to position in time slices and pads
-  Float_t  nofpads = GetNPads(sector,padrow);
-  Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
-  pad = y/(fPadPitchWidth)+padc;
-  time=z/fZWidth;  
-}
-void AliTPCParam::CRTimePadtoYZ(Float_t &y, Float_t &z,
-                               const Float_t &time, const Float_t &pad,
-                               Int_t sector, Int_t padrow)
-{
-  //transform position in time slices and pads  to cm 
-   Float_t  nofpads = GetNPads(sector,padrow);
-   Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
-   y=(pad-padc)*fPadPitchWidth;
-   z=time*fZWidth;
+Float_t  AliTPCParam::GetInnerAngleShift() const
+{  
+  //return angle   
+  return fInnerAngleShift;  
 }
+Float_t  AliTPCParam::GetOuterAngle() const
+{ 
+  //return angle 
+  return fOuterAngle;
+} 
+Float_t  AliTPCParam::GetOuterAngleShift() const
+{ 
+  //return angle 
+
+     return fOuterAngleShift;
+} 
 
-Int_t AliTPCParam::GetWire(Float_t & x)
-{
-  //
-  //return wire number of pad for electron at relative position x
-  //to the center of the pad
-  //and adjust x to the wire position
-  //we suppose that if the wire number is even the center wire
-  //is at center of pad
-  //
-  Float_t xrel= x/fWWPitch;
-  if ((fnWires>>1)==0) xrel+=1;
-  else  xrel+=0.5;
-  Int_t nw=Int_t(xrel);
-  if (xrel<0) nw-=1;
-  
-  x=(nw*fWWPitch);
-  if ((fnWires>>1)==0) x-=fWWPitch/2.;
-  return nw;
-}
 
-Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
+Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
 {
   //
   //give index of the given sector and pad row 
   //no control if the sectors and rows  are reasonable !!!
   //
-  if (sector<fNInnerSector) return sector*fnRowLow+row;
-  return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;  
+  if (sector<fNInnerSector) return sector*fNRowLow+row;
+  return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;  
 }
 
-Bool_t   AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row)
+Bool_t   AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
 {
   //
   //return sector and padrow for given index
-  //if index is reasonable return true else return false
+  //if index is reasonable returns true else return false
   //
   if ( (index<0) || (index>fNtRows))  return kFALSE;
-  Int_t outindex = fNInnerSector*fnRowLow;
+  Int_t outindex = fNInnerSector*fNRowLow;
   if (index<outindex) {
-    sector = index/fnRowLow;
-    row    = index - sector*fnRowLow;
+    sector = index/fNRowLow;
+    row    = index - sector*fNRowLow;
     return kTRUE;
   }
   index-= outindex;
-  sector = index/fnRowUp;
-  row    = index - sector*fnRowUp;
+  sector = index/fNRowUp;
+  row    = index - sector*fNRowUp;
+  sector += fNInnerSector;
   return kTRUE;         
 } 
 
-
-
-Int_t AliTPCParam::GetPadRow(Int_t isec, Float_t  &x)
+void AliTPCParam::SetDefault()
 {
   //
-  //return the pad row for given x (transformed) 
+  //set default parameters
   //
-  Float_t row_first=GetPadRowRadii(isec,0);
-  Int_t row = Int_t(( x-row_first+1.5*fPadPitchLength)/fPadPitchLength)-1;
-  //Int_t will make from -0.5 0 but we want to make -1 so we add and after substract 1
-  x -=row* fPadPitchLength+row_first;
-  if (  (row<0)||(row>=GetNRow(isec))) return -1;
-  else return row;  
-}
-
-void AliTPCParam::SetDefault()
-{
-  //set default TPC param   
+  //const static  Int_t kMaxRows=600; 
+  //
+  //sector default parameters
+  //
+  static const  Float_t kInnerRadiusLow = 83.65;
+  static const  Float_t kInnerRadiusUp  = 133.3;
+  static const  Float_t kOuterRadiusLow = 133.5;
+  static const  Float_t kOuterRadiusUp  = 247.7;
+  static const  Float_t kInnerAngle = 20; // 20 degrees
+  static const  Float_t kInnerAngleShift = 10;
+  static const  Float_t kOuterAngle = 20; //  20 degrees
+  static const  Float_t kOuterAngleShift = 10;
+  static const  Float_t kInnerFrameSpace = 1.5;
+  static const  Float_t kOuterFrameSpace = 1.5;
+  static const  Float_t kInnerWireMount = 1.2;
+  static const  Float_t kOuterWireMount = 1.4;
+  static const  Float_t kZLength =250.;
+  static const  Int_t   kGeometryType = 0; //straight rows 
+  static const Int_t kNRowLow = 63;
+  static const Int_t kNRowUp1 = 64;
+  static const Int_t kNRowUp2 = 32;
+  static const Int_t  kNRowUp = 96;
+  //
+  //wires default parameters
+  //
+  static const Int_t    kNInnerWiresPerPad = 3;
+  static const Int_t    kInnerDummyWire = 2;
+  static const Float_t  kInnerWWPitch = 0.25;
+  static const Float_t  kRInnerFirstWire = 84.475;
+  static const Float_t  kRInnerLastWire = 132.475;
+  static const Float_t  kInnerOffWire = 0.5;
+  static const Int_t    kNOuter1WiresPerPad = 4;
+  static const Int_t    kNOuter2WiresPerPad = 6;
+  static const Float_t  kOuterWWPitch = 0.25;  
+  static const Float_t  kROuterFirstWire = 134.225;
+  static const Float_t  kROuterLastWire = 246.975;
+  static const Int_t    kOuterDummyWire = 2;
+  static const Float_t  kOuterOffWire = 0.5;
+  //
+  //pad default parameters
+  // 
+  static const Float_t  kInnerPadPitchLength = 0.75;
+  static const Float_t  kInnerPadPitchWidth = 0.40;
+  static const Float_t  kInnerPadLength = 0.75;
+  static const Float_t  kInnerPadWidth = 0.40;
+  static const Float_t  kOuter1PadPitchLength = 1.0;
+  static const Float_t  kOuterPadPitchWidth = 0.6;
+  static const Float_t  kOuter1PadLength = 1.0;
+  static const Float_t  kOuterPadWidth = 0.6;
+  static const Float_t  kOuter2PadPitchLength = 1.5;
+  static const Float_t  kOuter2PadLength = 1.5;
+
+  static const Bool_t   kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM 
+  static const Int_t    kNCrossRows = 1; //number of rows to cross-talk
+  
+  //
+  //gas default parameters
+  //
+  static const  Float_t  kDiffT = 2.2e-2; 
+  static const  Float_t  kDiffL = 2.2e-2;
+  static const  Float_t  kGasGain = 2.e4;
+  static const  Float_t  kDriftV  =2.83e6;
+  static const  Float_t  kOmegaTau = 0.145;
+  static const  Float_t  kAttCoef = 250.;
+  static const  Float_t  kOxyCont = 5.e-6;
+  //
+  //electronic default parameters
+  //
+  static const  Float_t  kPadCoupling=0.5;
+  static const  Int_t    kZeroSup=2;
+  static const  Float_t  kNoise = 1000;                            
+  static const  Float_t  kChipGain = 12;
+  static const  Float_t  kChipNorm = 0.4;
+  static const  Float_t  kTSample = 2.e-7; 
+  static const  Float_t  kTFWHM   = 1.9e-7;  //fwhm of charge distribution
+  static const  Int_t    kMaxTBin =445;  
+  static const  Int_t    kADCSat  =1024;  
+  static const  Float_t  kADCDynRange =2000.;  
+  // 
+  //response constants
+  //
+  static const Int_t     kNResponseMax=100;
+  static const Float_t   kResponseThreshold=0.01;     
+  //L1 constants
+  //  static const Float_t   kGateDelay=6.1e-6; //In s
+  static const Float_t   kGateDelay=0.; //For the moment no gating
+  //  static const Float_t   kL1Delay=6.5e-6; //In s
+  static const Float_t   kL1Delay=0.; //For the moment no delay
+  //  static const UShort_t  kNTBinsBeforeL1=14;
+  static const UShort_t  kNTBinsBeforeL1=0; //For the moment no shift
   fbStatus = kFALSE;
-  //set sector  parameters
-  fInnerRadiusLow = kInnerRadiusLow;
-  fOuterRadiusLow = kOuterRadiusLow;
-  fInnerRadiusUp  = kInnerRadiusUp;
-  fOuterRadiusUp  = kOuterRadiusUp;   
-  SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift); 
-  // set default pad size and shape
-  fPadPitchLength  = kPadPitchLength;
-  fPadPitchWidth   = kPadPitchWidth;
-  fPadLength  = kPadLength;
-  fPadWidth   = kPadWidth;   
-  //
-  fnWires = knWires;
-  fWWPitch= kPadPitchLength/Float_t(knWires);
-  fDiffT  = kDiffT;
-  fDiffL  = kDiffL;
-  fOmegaTau = kOmegaTau;
-  fOxyCont  = kOxyCont;
-  fAttCoef  = kAttCoef;
-  fNoise  = kNoise;
-  fChipGain = kChipGain;
-  fGasGain = kGasGain;
-  fZeroSup= kZeroSup;
-  fPadCoupling= kPadCoupling;
-  fTSample =kTSample;
-  fTSigma  =kTFWHM/2.35; 
-  fDriftV=kDriftV;  
-  fMaxTBin = kMaxTBin;
-  fbStatus = Update();
-}
-
-void  AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
-{
   //
-  //set cosinus and sinus of rotation angles for sector isec
+  //set sector parameters
+  //
+  SetInnerRadiusLow(kInnerRadiusLow);
+  SetOuterRadiusLow(kOuterRadiusLow);
+  SetInnerRadiusUp(kInnerRadiusUp);
+  SetOuterRadiusUp(kOuterRadiusUp);
+  SetInnerFrameSpace(kInnerFrameSpace);
+  SetOuterFrameSpace(kOuterFrameSpace);
+  SetInnerWireMount(kInnerWireMount);
+  SetOuterWireMount(kOuterWireMount);
+  SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
+  SetZLength(kZLength);
+  SetGeometryType(kGeometryType);
+  SetRowNLow(kNRowLow);
+  SetRowNUp1 (kNRowUp1);
+  SetRowNUp2(kNRowUp2);
+  SetRowNUp(kNRowUp);
+  //
+  //set wire parameters
+  //
+  SetInnerNWires(kNInnerWiresPerPad);
+  SetInnerDummyWire(kInnerDummyWire);
+  SetInnerOffWire(kInnerOffWire);
+  SetOuter1NWires(kNOuter1WiresPerPad);
+  SetOuter2NWire(kNOuter2WiresPerPad);
+  SetOuterDummyWire(kOuterDummyWire);
+  SetOuterOffWire(kOuterOffWire);
+  SetInnerWWPitch(kInnerWWPitch);
+  SetRInnerFirstWire(kRInnerFirstWire);
+  SetRInnerLastWire(kRInnerLastWire);
+  SetOuterWWPitch(kOuterWWPitch);
+  SetROuterFirstWire(kROuterFirstWire);
+  SetROuterLastWire(kROuterLastWire);  
+  //
+  //set pad parameter
+  //
+  SetInnerPadPitchLength(kInnerPadPitchLength);
+  SetInnerPadPitchWidth(kInnerPadPitchWidth);
+  SetInnerPadLength(kInnerPadLength);
+  SetInnerPadWidth(kInnerPadWidth);
+  SetOuter1PadPitchLength(kOuter1PadPitchLength); 
+  SetOuter2PadPitchLength(kOuter2PadPitchLength);
+  SetOuterPadPitchWidth(kOuterPadPitchWidth);
+  SetOuter1PadLength(kOuter1PadLength);
+  SetOuter2PadLength(kOuter2PadLength);
+  SetOuterPadWidth(kOuterPadWidth); 
+  SetMWPCReadout(kBMWPCReadout);
+  SetNCrossRows(kNCrossRows);
+  //
+  //set gas paremeters
+  //
+  SetDiffT(kDiffT);
+  SetDiffL(kDiffL);
+  SetGasGain(kGasGain);
+  SetDriftV(kDriftV);
+  SetOmegaTau(kOmegaTau);
+  SetAttCoef(kAttCoef);
+  SetOxyCont(kOxyCont);
+  //
+  //set electronivc parameters  
+  //
+  SetPadCoupling(kPadCoupling);
+  SetZeroSup(kZeroSup);
+  SetNoise(kNoise);
+  SetChipGain(kChipGain);
+  SetChipNorm(kChipNorm);   
+  SetTSample(kTSample);
+  SetTFWHM(kTFWHM);
+  SetMaxTBin(kMaxTBin);
+  SetADCSat(kADCSat);
+  SetADCDynRange(kADCDynRange);
+//   //set magnetic field
+//   SetBField(kBField);
+//   SetNPrimLoss(kNPrimLoss);
+//   SetNTotalLoss(kNTotalLoss);
   //
-  cos=fRotAngle[isec*2];
-  sin=fRotAngle[isec*2+1];
+  //set response  parameters  
+  //
+  SetNResponseMax(kNResponseMax); 
+  SetResponseThreshold(static_cast<int>(kResponseThreshold));
+  //L1 data
+  SetGateDelay(kGateDelay);
+  SetL1Delay(kL1Delay);
+  SetNTBinsBeforeL1(kNTBinsBeforeL1);
 }
+
           
 Bool_t AliTPCParam::Update()
 {
@@ -345,89 +533,171 @@ Bool_t AliTPCParam::Update()
   // for example we can change size of pads and according this recalculate number
   // of pad rows, number of of pads in given row ....
   //
+  const Float_t kQel = 1.602e-19; // elementary charge
   fbStatus = kFALSE;
 
   Int_t i,j;  //loop variables because HP 
   //-----------------Sector section------------------------------------------
   //calclulate number of sectors
-  fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); // number of inner sectors - factor 0.2 to don't
-  //be influnced by inprecision
+  fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); 
+       // number of inner sectors - factor 0.2 to don't be influnced by inprecision
   if (fNInnerSector%2) return kFALSE;
   fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2); 
   if (fNOuterSector%2) return kFALSE;
   fNSector  = fNInnerSector+fNOuterSector;
+
+  if (fRotAngle!=0) delete [] fRotAngle;
+  fRotAngle = new Float_t[4*fNSector];
   //calculate sin and cosine of rotations angle     
   //sectors angles numbering from 0
-  j=fNInnerSector;
+
+  j=fNInnerSector*2;
   Float_t angle = fInnerAngleShift; 
-  for (i=0; i<fNInnerSector*2; i+=2, j+=2 , angle +=fInnerAngle){
+  for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
     fRotAngle[i]=TMath::Cos(angle);
     fRotAngle[i+1]=TMath::Sin(angle);
     fRotAngle[j] =  fRotAngle[i];
     fRotAngle[j+1] =  fRotAngle[i+1];
+    fRotAngle[i+2] =angle;
+    fRotAngle[j+2] =angle;    
   }
   angle = fOuterAngleShift; 
-  j=(fNInnerSector+fNOuterSector/2)*2;
-  for (i=fNInnerSector*2; i<fNSector*2; i+=2,j+=2, angle +=fOuterAngle){
+  j=(fNInnerSector+fNOuterSector/2)*4;
+  for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
     fRotAngle[i]=TMath::Cos(angle);
     fRotAngle[i+1]=TMath::Sin(angle);
     fRotAngle[j] =  fRotAngle[i];
     fRotAngle[j+1] =  fRotAngle[i+1];
+    fRotAngle[i+2] =angle;
+    fRotAngle[j+2] =angle;    
   }
 
+  fZWidth = fTSample*fDriftV;  
+  fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
+  fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
+  //wire section 
+  /*  Int_t nwire;
+  Float_t wspace; //available space for wire
+  Float_t dummyspace; //dummyspace for wire
+  wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
+  nwire = Int_t(wspace/fInnerWWPitch);
+  wspace = Float_t(nwire)*fInnerWWPitch;
+  dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;  
+  wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
+  nwire = Int_t(wspace/fOuterWWPitch);
+  wspace = Float_t(nwire)*fOuterWWPitch;
+  dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.; 
+  fROuterFirstWire = fOuterRadiusLow+dummyspace;
+  fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
+  */
   
-  //----------------PAD section------------------------------------
-  //recalculate and check some geometric parameters 
-  if (0.001>fPadPitchLength){
-    cout<<"ERROR !!! Small pad pitch length \n"<<flush;
-    return kFALSE;
+  //
+  //response data
+  //
+  if (fResponseBin) delete [] fResponseBin;
+  if (fResponseWeight) delete [] fResponseWeight;
+  fResponseBin    = new Int_t[3*fNResponseMax];
+  fResponseWeight = new Float_t[fNResponseMax];
+
+  //L1 data
+  fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
+  fbStatus = kTRUE;
+  return kTRUE;
+}
+
+
+
+Bool_t AliTPCParam::ReadGeoMatrices(){
+  //
+  // read geo matrixes
+  //
+  if (!gGeoManager){
+    AliFatal("Geo manager not initialized\n");
   }
-  if (fPadPitchLength<fPadLength) {
-    cout<<"ERROR !!! Pitch length  smaller then length of pad \n"<<flush;
-    return kFALSE;
-  } 
-  fnRowUp   = Int_t((0.01+fOuterRadiusUp-fOuterRadiusLow)/fPadPitchLength)+1; 
-  if ( kMaxRows<fnRowUp) fnRowUp = kMaxRows;
-  if (1>fnRowUp) return kFALSE;
-
-  fnRowLow   = Int_t((0.01+fInnerRadiusUp-fInnerRadiusLow)/fPadPitchLength)+1;
-  if ( kMaxRows<fnRowLow) fnRowUp = kMaxRows;
-  if (1>fnRowLow) return kFALSE;
-  // adjust upper sectors pad row positions and pad numbers
-  for (i = 0;i<fnRowUp;i++) 
-    {
-       Float_t x  = fOuterRadiusLow +fPadPitchLength*(Float_t)i;
-       //Float_t y =  x*2*tan(alpha_up/2)-kEdgeSectorSpace;
-       Float_t y = (x-0.5*fPadPitchLength)*tan(fOuterAngle/2)-kEdgeSectorSpace
-       -fPadPitchWidth/2.;
-       fPadRowUp[i] = x;
-       fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;        
-       
+  AliAlignObjParams o;
+  //
+  if (fTrackingMatrix) delete [] fTrackingMatrix;
+  fTrackingMatrix = new TGeoHMatrix*[fNSector];
+  if (fClusterMatrix) delete [] fClusterMatrix;
+  fClusterMatrix = new TGeoHMatrix*[fNSector];
+  if (fGlobalMatrix) delete [] fGlobalMatrix;
+  fGlobalMatrix = new TGeoHMatrix*[fNSector];
+  //
+  for (Int_t isec=0; isec<fNSector; isec++) {
+    fGlobalMatrix[isec] = 0;
+    fClusterMatrix[isec]= 0;
+    fTrackingMatrix[isec]=0;   
+    AliGeomManager::ELayerID iLayer;
+    Int_t iModule;
+
+    if(isec<fNInnerSector) {
+      iLayer = AliGeomManager::kTPC1;
+      iModule = isec;
     }
-  // adjust lower sectors pad row positions and pad numbers 
-  for (i = 0;i<fnRowLow;i++) 
-    {
-       Float_t x  = fInnerRadiusLow +fPadPitchLength*(Float_t)i;
-       //  Float_t y =  x*2*tan(alpha_low/2)-kEdgeSectorSpace;
-       Float_t y = (x-0.5*fPadPitchLength)*tan(fInnerAngle/2)-kEdgeSectorSpace
-       -fPadPitchWidth/2.;
-       fPadRowLow[i] = x;
-       fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
-         
+    else {
+      iLayer = AliGeomManager::kTPC2;
+      iModule = isec - fNInnerSector;
     }
 
-  //that variable are not writen to the file there are calculated
-  //
-  fWWPitch= fPadPitchLength/Float_t(fnWires);
-  fZWidth = fTSample*fDriftV;  
-  fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
-  fbStatus = kTRUE;
+    UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
+    const char *symname = AliGeomManager::SymName(volid);
+    TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
+    const char *path = symname;
+    if(pne) path=pne->GetTitle();
+    if (!gGeoManager->cd(path)) return kFALSE;      
+    TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+    //
+    TGeoRotation mchange; 
+    mchange.RotateY(90); mchange.RotateX(90);
+    Float_t ROCcenter[3]; 
+    GetChamberCenter(isec,ROCcenter);
+    //
+    // Convert to global coordinate system
+    //
+    fGlobalMatrix[isec] = new TGeoHMatrix(*m);
+    fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
+    TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
+    fGlobalMatrix[isec]->Multiply(&center);
+    //
+    //  cluster correction matrix
+    //
+    fClusterMatrix[isec] = new TGeoHMatrix;
+    Double_t sectorAngle = 20.*(isec%18)+10;
+    TGeoHMatrix  rotMatrix;
+    rotMatrix.RotateZ(sectorAngle);
+    if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
+      //
+      // mirrored system 
+      //
+      TGeoRotation mirrorZ;
+      mirrorZ.SetAngles(90,0,90,90,180,0);
+      fClusterMatrix[isec]->Multiply(&mirrorZ);
+    }
+    TGeoTranslation trans(0,0,GetZLength(isec));
+    fClusterMatrix[isec]->MultiplyLeft(&trans);
+    fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));       
+    fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
+  }
   return kTRUE;
 }
 
+TGeoHMatrix *  AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
+  //
+  // make local to tracking matrix
+  //
+  Double_t sectorAngle = 20.*(sector%18)+10;
+  TGeoHMatrix *newMatrix = new TGeoHMatrix();
+  newMatrix->RotateZ(sectorAngle);
+  newMatrix->MultiplyLeft(&(geoMatrix->Inverse()));
+  return newMatrix;
+}
+
 
 
-Bool_t AliTPCParam::GetStatus()
+
+Bool_t AliTPCParam::GetStatus() const
 {
   //get information about object consistency
   return fbStatus;
@@ -436,17 +706,27 @@ Bool_t AliTPCParam::GetStatus()
 Int_t AliTPCParam::GetNRowLow() const
 {
   //get the number of pad rows in low sector
-  return fnRowLow;
+  return fNRowLow;
 }
 Int_t AliTPCParam::GetNRowUp() const
 {
   //get the number of pad rows in up sector
-  return fnRowUp;
+  return fNRowUp;
+}
+Int_t AliTPCParam::GetNRowUp1() const
+{
+  //get the number of pad rows in up1 sector
+  return fNRowUp1;
+}
+Int_t AliTPCParam::GetNRowUp2() const
+{
+  //get the number of pad rows in up2 sector
+  return fNRowUp2;
 }
 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
 {
   //get the pad row (irow) radii
-  if ( !(irow<0) && (irow<fnRowLow) ) 
+  if ( !(irow<0) && (irow<fNRowLow) ) 
     return  fPadRowLow[irow];
   else
     return 0;
@@ -455,7 +735,7 @@ Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
 {
   //get the pad row (irow) radii
- if ( !(irow<0) && (irow<fnRowUp) ) 
+ if ( !(irow<0) && (irow<fNRowUp) ) 
     return  fPadRowUp[irow];
   else
     return 0;
@@ -464,8 +744,8 @@ Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
 {
   //get the number of pads in row irow
-  if ( !(irow<0) && (irow<fnRowLow) ) 
-    return  fnPadsLow[irow];
+  if ( !(irow<0) && (irow<fNRowLow) ) 
+    return  fNPadsLow[irow];
   else
     return 0;
 }
@@ -474,90 +754,69 @@ Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
 {
   //get the number of pads in row irow
-  if ( !(irow<0) && (irow<fnRowUp) ) 
-    return  fnPadsUp[irow];
+  if ( !(irow<0) && (irow<fNRowUp) ) 
+    return  fNPadsUp[irow];
   else
     return 0;
 }
+Float_t AliTPCParam::GetYInner(Int_t irow) const
+{
+  return fYInner[irow];
+}
 
 
-void AliTPCParam::Streamer(TBuffer &R__b)
+Float_t AliTPCParam::GetYOuter(Int_t irow) const
 {
-   // Stream an object of class AliTPC.
-
-   if (R__b.IsReading()) {
-      Version_t R__v = R__b.ReadVersion(); if (R__v) { }
-      TObject::Streamer(R__b);
-      if (R__v < 2) return;
-      //sector parameters      
-      R__b >> fInnerRadiusLow;
-      R__b >> fInnerRadiusUp;
-      R__b >> fOuterRadiusLow;
-      R__b >> fOuterRadiusUp;
-      R__b >> fInnerAngle;
-      R__b >> fInnerAngleShift;
-      R__b >> fOuterAngle;
-      R__b >> fOuterAngleShift;
-      //pad parameters
-      R__b >> fPadPitchLength;
-      R__b >> fPadPitchWidth;
-      R__b >> fPadLength;
-      R__b >> fPadWidth;
-
-      R__b >> fnWires;
-      //gas parameters
-      R__b >>fDiffT;
-      R__b >>fDiffL;
-      R__b >>fGasGain;
-      R__b >>fDriftV;
-      R__b >>fOmegaTau;
-      R__b >>fOxyCont;
-      R__b >>fAttCoef;
-      
-      R__b >>fPadCoupling;
-      R__b >>fZeroSup;
-      R__b >>fNoise;
-      R__b >>fChipGain;
-      
-      R__b >>fTSample;
-      R__b >>fTSigma;     
-      //
-      Update();
-   } else {
-      R__b.WriteVersion(AliTPCParam::IsA());
-      TObject::Streamer(R__b);      
-      R__b << fInnerRadiusLow;
-      R__b << fInnerRadiusUp;
-      R__b << fOuterRadiusLow;
-      R__b << fOuterRadiusUp;
-      R__b << fInnerAngle;
-      R__b << fInnerAngleShift;
-      R__b << fOuterAngle;
-      R__b << fOuterAngleShift;
-
-      R__b << fPadPitchLength;
-      R__b << fPadPitchWidth;
-      R__b << fPadLength;
-      R__b << fPadWidth;
-
-      R__b << fnWires;
-      
-      R__b <<fDiffT;
-      R__b <<fDiffL;
-      R__b <<fGasGain;
-      R__b <<fDriftV;
-      R__b <<fOmegaTau;
-      R__b <<fOxyCont;
-      R__b <<fAttCoef;
-
-
-      R__b <<fPadCoupling;
-      R__b <<fZeroSup;
-      R__b <<fNoise;
-      R__b <<fChipGain;
-      
-      R__b <<fTSample;
-      R__b <<fTSigma;                              
-   }
+  return fYOuter[irow];
 }
 
+Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
+{
+  // returns the sector index
+  // takes as input the angle, index of the pad row and z position
+  if(row<0) return -1;
+
+  if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
+  if (angle < 0.            ) angle += 2.*TMath::Pi();
+  Int_t sector;
+  if(row<fNRowLow) {
+    sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
+    if (z<0) sector += (fNInnerSector>>1);
+  }
+  else {
+    sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
+    if (z<0) sector += (fNOuterSector>>1);
+  }    
+  
+  return sector;
+}
+
+Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
+{
+  // returns the default radial position
+  // of the readout chambers
+
+  const Float_t kROCcenterIn = 110.2;
+  const Float_t kROCcenterOut = 188.45;
+
+  if (isec<fNInnerSector){
+    if (center){
+      center[0] = kROCcenterIn;
+      center[1] = 0; 
+      center[2] = -5.51-0.08; 
+    }
+    return kROCcenterIn;
+  }
+  else{
+    if (center){
+      center[0] = kROCcenterOut;
+      center[1] = 0; 
+      center[2] = -5.61-0.08; 
+    }
+    return kROCcenterOut;
+  }
+}
+
+
+