+/**************************************************************************
+ * 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 //
// //
+// !sectors are numbered from 0 //
+// !pad rows are numbered from 0 //
+//
+// 12.6. changed z relative
// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
// //
///////////////////////////////////////////////////////////////////////
-// MI change global variables for geometry
-// declaration of the global static variable
-// of AliTPCParam objects
+//
-#include <iostream.h>
-#include <TMath.h>
-//#include <TObject.h>
-#include "AliTPCParam.h"
-//some old TPC parameters in AliTPCSecGeo.h
-#include "AliTPCSecGeo.h"
+#include <AliTPCParam.h>
+#include <TGeoManager.h>
+#include <TGeoPhysicalNode.h>
+#include <TString.h>
+#include "AliAlignObj.h"
+#include "AliAlignObjParams.h"
+#include "AliLog.h"
ClassImp(AliTPCParam)
-// default values
-const Float_t kInnerRadiusLow = 89.45;
-const Float_t kOuterRadiusLow = 143.725;
-const Float_t kInnerRadiusUp = 134.55;
-const Float_t kOuterRadiusUp = 248.275;
+//___________________________________________
+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.),
+ fNominalVoltage(),
+ fNResponseMax(0),
+ fResponseThreshold(0.),
+ fCurrentMax(0),
+ fResponseBin(0),
+ fResponseWeight(0),
+ fGateDelay(0.),
+ fL1Delay(0.),
+ fNTBinsBeforeL1(0),
+ fNTBinsL1(0.)
+{
+ //
+ //constructor sets the default parameters
+ //
-const Float_t kPadPitchLength = 2.05;
-const Float_t kPadPitchWidth = 0.35;
-const Float_t kPadLength = 2.05;
-const Float_t kPadWidth = 0.35;
-// Number of wires per pad and wire-wire pitch
-const Int_t knWires = 5;
-const Float_t kDiffT = 2.2e-2;
-const Float_t kDiffL = 2.2e-2;
-const Float_t kDriftV =2.85e6;
+ SetTitle("75x40_100x60_150x60");
+ SetDefault();
+}
-const Float_t kOmegaTau = 0.145;
-const Float_t kAttCoef = 250.;
-const Float_t kOxyCont = 5.e-6;
+AliTPCParam::~AliTPCParam()
+{
+ //
+ //destructor deletes some dynamicaly alocated variables
+ //
+ if (fResponseBin!=0) delete [] fResponseBin;
+ if (fResponseWeight!=0) delete [] fResponseWeight;
+ if (fRotAngle !=0) delete [] fRotAngle;
+ CleanGeoMatrices();
-const Float_t kChipGain = 24;
-const Float_t kGasGain = 1e4;
-const Float_t kTSample = 2.e-7; //TSAMPLE
-const Float_t kTFWHM = 2.5e-7; //fwhm of charge distribution
-
-const Float_t kNoise = 500; //default noise = 1000 el
-const Int_t kZeroSup=5;
-const Float_t kPadCoupling=0.5;
-//
-const Float_t kEdgeSectorSpace = 5.26;
+}
+Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const
+{
+ //
+ // calculates sector number (index[1], undefined on input)
+ // xyz intact
+ //
+ 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));
+
+ Float_t cos,sin;
+ AdjustCosSin(sector,cos,sin);
+ x1=xyz[0]*cos + xyz[1]*sin;
-//___________________________________________
-AliTPCParam::AliTPCParam()
-{
- //constructor set the default parameters
- SetDefault();
+ 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);
+ if (sector<0 || sector>=fNSector) AliError(Form("Wrong sector %d",sector));
+ 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;
-void AliTPCParam::CRXYZtoXYZ(Float_t *xyz,
- const Int_t §or, 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<25) ? fPadRowLow[0] : fPadRowUp[0];
- if (rel==kTRUE) //if we have
- {
- xyz[0]+=row_first;
- xyz[0]+=(Int_t) padrow*fPadPitchLength;
- }
- if (sector<25)
- if ( sector>12) xyz[2]*=-1.;
- else
- if (sector>48) 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;
}
-void AliTPCParam::XYZtoCRXYZ(Float_t *xyz,
- Int_t §or, Int_t & padrow, Int_t option)
+Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) 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] "polomer for lover sector
- sector=Int_t(angle/alpha_low)+1;
- 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/alpha_up)+25;
- AdjustAngles(sector,cos,sin);
- x1=xyz[0]*cos + xyz[1]*sin;
- y1=-xyz[0]*sin + xyz[1]*cos;
- if (xyz[2]<0) sector+=24;
- }
- else
- if (xyz[2]<0) sector+=12;
- if (xyz[2]<0) xyz[2]=-xyz[2];
- 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;
+ //
+ //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;
}
- 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<25) {
- padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
- if ( sector>12) xyz[2]=-xyz[2];
+ 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;
}
- else {
- padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
- if (sector>48) xyz[2]=-xyz[2];
+ if (4==system) {
+ Transform4to8(xyz,index);
+ system=8;
}
- //if we store relative position calculate position relative to pad row
- if (rel==kTRUE){
- if (sector<25)
- x1-=padrow*fPadPitchLength+fPadRowLow[0];
- else
- x1-=padrow*fPadPitchLength+fPadRowUp[0];
- }
- xyz[0]=x1;
- xyz[1]=y1;
+ 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::CRYZtoTimePad(const Float_t &y, const Float_t &z,
- Float_t &time, Float_t &pad,
- Int_t sector, Int_t padrow)
+void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
+ Float_t outershift)
{
- //transform position in cm to position in time slices and pads
- Float_t nofpads = (sector < 25) ? fnPadsLow[padrow] : fnPadsUp[padrow];
- Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
- pad = y/(fPadPitchWidth)+padc;
- time=(z_end-z)/(fDriftV*fTSample);
- // cout<<y<<" "<<z<<" "<<time<<" "<<pad<<" "<<
- // sector<<" "<<padrow<<"\n";
+ //
+ // 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
+ fInnerAngle *=kDegtoRad;
+ fInnerAngleShift *=kDegtoRad;
+ fOuterAngle *=kDegtoRad;
+ fOuterAngleShift *=kDegtoRad;
}
-void AliTPCParam::CRTimePadtoYZ(Float_t &y, Float_t &z,
- const Float_t &time, const Float_t &pad,
- Int_t sector, Int_t padrow)
+
+Float_t AliTPCParam::GetInnerAngle() const
{
- //transform position in time slices and pads to cm
- Float_t nofpads = (sector < 25) ? fnPadsLow[padrow] : fnPadsUp[padrow];
- Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
- y=(pad-padc)*fPadPitchWidth;
- z=z_end-time*(fDriftV*fTSample);
- // cout<<y<<" "<<z<<" "<<time<<" "<<pad<<" "<<
- // sector<<" "<<padrow<<"\n";
+ //return angle
+ return fInnerAngle;
+
}
-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;
+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::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<25) return (sector-1)*fnRowLow+row;
- return (24*fnRowLow)+(sector-25)*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 = 24*fnRowLow;
+ Int_t outindex = fNInnerSector*fNRowLow;
if (index<outindex) {
- sector = index/fnRowLow;
- row = index - sector*fnRowLow;
- sector++;
+ sector = index/fNRowLow;
+ row = index - sector*fNRowLow;
return kTRUE;
}
index-= outindex;
- sector = index/fnRowUp;
- row = index - sector*fnRowUp;
- sector++;
+ 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 radius parameters
- fInnerRadiusLow = kInnerRadiusLow;
- fOuterRadiusLow = kOuterRadiusLow;
- fInnerRadiusUp = kInnerRadiusUp;
- fOuterRadiusUp = kOuterRadiusUp;
- // 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;
- //calculate sin and cosine of rotations angle
- for (Int_t i=1; i<80; i++)
- {
- Float_t angle;
- if(i < 25){
- angle = (i < 13) ? (i-1)*alpha_low : (i-13)*alpha_low;
- }
- else {
- angle = (i < 49) ? (i-25)*alpha_up : (i-49)*alpha_up;
- }
- fRotAngle[i]=TMath::Cos(angle);
- fRotAngle[100+i]=TMath::Sin(angle);
- }
- fbStatus = Update();
+ //
+ //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);
+ for (UInt_t i=0; i<36; i++)
+ {
+ SetNominalVoltage(1196.0, i);
+ }
+ for (UInt_t i=36; i<72; i++)
+ {
+ SetNominalVoltage(1417.0, i);
+ }
+// //set magnetic field
+// SetBField(kBField);
+// SetNPrimLoss(kNPrimLoss);
+// SetNTotalLoss(kNTotalLoss);
+ //
+ //set response parameters
+ //
+ SetNResponseMax(kNResponseMax);
+ SetResponseThreshold(static_cast<int>(kResponseThreshold));
+ //L1 data
+ SetGateDelay(kGateDelay);
+ SetL1Delay(kL1Delay);
+ SetNTBinsBeforeL1(kNTBinsBeforeL1);
}
-void AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
-{
- //set cosinus and sinus of rotation angles for sector isec
- cos=fRotAngle[isec];
- sin=fRotAngle[100+isec];
-}
Bool_t AliTPCParam::Update()
{
+ //
+ // update some calculated parameter which must be updated after changing "base"
+ // parameters
+ // 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;
- //recalculate and check some geometric parameters
- if (0.001>fPadPitchLength){
- cout<<"ERROR !!! Small pad pitch length \n"<<flush;
- return 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
+ 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*2;
+ Float_t angle = fInnerAngleShift;
+ 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)*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;
}
- if (fPadPitchLength<fPadLength) {
- cout<<"ERROR !!! Pitch length smaller then length of pad \n"<<flush;
- return kFALSE;
- }
+ 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);
+ */
+
+ //
+ //response data
+ //
+ if (fResponseBin) delete [] fResponseBin;
+ if (fResponseWeight) delete [] fResponseWeight;
+ fResponseBin = new Int_t[3*fNResponseMax];
+ fResponseWeight = new Float_t[fNResponseMax];
- fnRowUp = Int_t((0.01+fOuterRadiusUp-fOuterRadiusLow)/fPadPitchLength)+1;
- if ( kMaxRows<fnRowUp) fnRowUp = kMaxRows;
- if (1>fnRowUp) return kFALSE;
+ //L1 data
+ fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
+ fbStatus = kTRUE;
+ return kTRUE;
+}
- 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-0.5*fPadPitchLength)*2.*tan(alpha_up/2)-kEdgeSectorSpace;
- fPadRowUp[i] = x;
- fnPadsUp[i] = (Int_t)(y/fPadPitchWidth) ;
- if ((fnPadsUp[i]%2) == 0) fnPadsUp[i]-=1;
+void AliTPCParam::CleanGeoMatrices(){
+ //
+ // clean geo matrices
+ //
+
+ 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;
+ }
+
+ if (fGlobalMatrix) {
+ for(Int_t i = 0; i < fNSector; i++)
+ delete fGlobalMatrix[i];
+ delete [] fGlobalMatrix;
+ }
+
+ return;
+}
+
+Bool_t AliTPCParam::ReadGeoMatrices(){
+ //
+ // read geo matrixes
+ //
+ if (!gGeoManager){
+ AliFatal("Geo manager not initialized\n");
+ }
+ AliAlignObjParams o;
+ //
+
+ // clean geo matrices
+ CleanGeoMatrices();
+
+ // create new geo matrices
+ fTrackingMatrix = new TGeoHMatrix*[fNSector];
+ fClusterMatrix = new TGeoHMatrix*[fNSector];
+ fGlobalMatrix = new TGeoHMatrix*[fNSector];
+ for (Int_t isec=0; isec<fNSector; isec++) {
+ fGlobalMatrix[isec] = 0;
+ fClusterMatrix[isec]= 0;
+ fTrackingMatrix[isec]=0;
+ }
+ //
+ 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;
+ }
+ else {
+ iLayer = AliGeomManager::kTPC2;
+ iModule = isec - fNInnerSector;
}
- // adjust lower sectors pad row positions and pad numbers
- for (i = 0;i<fnRowLow;i++)
+
+ UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
+ TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(volid);
+ if(!pne)
{
- Float_t x = fInnerRadiusLow +fPadPitchLength*(Float_t)i;
- Float_t y = (x-0.5*fPadPitchLength)*2.*tan(alpha_low/2)-kEdgeSectorSpace;
- fPadRowLow[i] = x;
- fnPadsLow[i] = (Int_t)(y/fPadPitchWidth) ;
- if ((fnPadsLow[i]%2) == 0) fnPadsLow[i]-=1;
+ AliError(Form("Alignable entry for volume ID %d not in geometry. Exiting!",volid));
+ return kFALSE;
+ }
+ const char *path = pne->GetTitle();
+ if (!gGeoManager->cd(path)) return kFALSE;
+ TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
+ // Since GEANT4 does not allow reflections, in this case the reflection
+ // component if the matrix is embedded by TGeo inside TGeoScaledShape
+ if (gGeoManager->GetCurrentVolume()->GetShape()->IsReflected())
+ m->ReflectZ(kFALSE, kTRUE);
+ //
+ 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(¢er);
+ //
+ // 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;
+}
- //that variable are not writen to the file there are calculated
+TGeoHMatrix * AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
//
- fWWPitch= fPadPitchLength/Float_t(fnWires);
- fZWidth = fTSample*fDriftV;
- fNtRows = 24*fnRowLow+48*fnRowUp;
-
- fbStatus = kTRUE;
- return kTRUE;
+ // 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;
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;
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;
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;
}
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;
-
- R__b >> fInnerRadiusLow;
- R__b >> fInnerRadiusUp;
- R__b >> fOuterRadiusLow;
- R__b >> fOuterRadiusUp;
-
- 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;
- //
- fWWPitch= fPadPitchLength/Float_t(fnWires);
- fZWidth = fTSample*fDriftV;
- fNtRows = 24*fnRowLow+48*fnRowUp;
- 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 << 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;
+ }
}