00001 #include <assert.h>
00002 #include "TMath.h"
00003 #include "TString.h"
00004 #include "Stiostream.h"
00005 #include "St_svtHybridDriftVelocityC.h"
00006 ClassImp(St_svtHybridDriftVelocityC);
00007 St_svtHybridDriftVelocityC *St_svtHybridDriftVelocityC::fgsvtHybridDriftVelocityC = 0;
00008 Double_t St_svtHybridDriftVelocityC::mAnodePitch = 0.0250;
00009 Double_t St_svtHybridDriftVelocityC::mWaferLength = 2.9928;
00010 Double_t St_svtHybridDriftVelocityC::mWaferWidth = 3.0000;
00011 Double_t St_svtHybridDriftVelocityC::mNoAnodes = 2*St_svtHybridDriftVelocityC::mWaferWidth/St_svtHybridDriftVelocityC::mAnodePitch;
00012 Double_t St_svtHybridDriftVelocityC::mSamplingFrequency = 25000000.0;
00013 static const Int_t NB = 3;
00014 static const Int_t NL = 16;
00015 static const Int_t NW = 7;
00016 static const Int_t NH = 2;
00017 static svtHybridDriftVelocity_st *pointers[3][16][7][2];
00018 static svtHybridDriftVelocity_st *DataOld = 0;
00019
00020 Double_t St_svtHybridDriftVelocityC::STcheb(Int_t N, Double_t *par, Double_t x) {
00021 if (N < 0 || N > 12) return 0;
00022 Double_t T0 = 1;
00023 Double_t T1 = 2*x - 1;
00024 Double_t T2;
00025 Double_t Sum = par[0]*T0;
00026 if (N >= 1) {
00027 T1 = 2*x - 1;
00028 Sum += par[1]*T1;
00029 for (int n = 2; n <= N; n++) {
00030 T2 = 2*(2*x - 1)*T1 - T0;
00031 Sum += par[n]*T2;
00032 T0 = T1;
00033 T1 = T2;
00034 }
00035 }
00036 return Sum;
00037 }
00038
00039 St_svtHybridDriftVelocityC::St_svtHybridDriftVelocityC (St_svtHybridDriftVelocity *table) : TChair(table) {
00040 if (fgsvtHybridDriftVelocityC) delete fgsvtHybridDriftVelocityC; fgsvtHybridDriftVelocityC = this;
00041 Init();
00042 }
00043
00044 void St_svtHybridDriftVelocityC::Init() {
00045 memset (&pointers[0][0][0][0], 0, NB*NL*NW*NH*sizeof(svtHybridDriftVelocity_st *));
00046 St_svtHybridDriftVelocity *Table = (St_svtHybridDriftVelocity *) GetThisTable();
00047 if (Table) {
00048 svtHybridDriftVelocity_st *Data = Table->GetTable();
00049 DataOld = Data;
00050 Int_t N = Table->GetNRows();
00051 for (Int_t j = 0; j < N; j++, Data++) {
00052 if (Data->barrel < 1 || Data->barrel > NB ||
00053 Data->ladder < 1 || Data->ladder > NL ||
00054 Data->wafer < 1 || Data->wafer > NW ||
00055 Data->hybrid < 1 || Data->hybrid > NH) continue;
00056 pointers[Data->barrel-1][Data->ladder-1][Data->wafer-1][Data->hybrid-1] = Data;
00057 }
00058 }
00059 }
00060
00061 svtHybridDriftVelocity_st *St_svtHybridDriftVelocityC::p(Int_t barrel, Int_t ladder, Int_t wafer, Int_t hybrid) {
00062 svtHybridDriftVelocity_st *p = 0;
00063 if (! GetThisTable()) return p;
00064 if (((St_svtHybridDriftVelocity *)GetThisTable())->GetTable() != DataOld) Init();
00065 if (barrel >= 1 && barrel <= NB &&
00066 ladder >= 1 && ladder <= NL &&
00067 wafer >= 1 && wafer <= NW &&
00068 hybrid >= 1 && hybrid <= NH) p = pointers[barrel-1][ladder-1][wafer-1][hybrid-1];
00069 return p;
00070 }
00071
00072 Double_t St_svtHybridDriftVelocityC::uHat(svtHybridDriftVelocity_st *p, Double_t timeBin) {
00073 if (! p) return -99;
00074 Double_t u = 1 - (timeBin - p->tmin)/(p->tmax - p->tmin);
00075 if (p->hybrid == 1) u = -u;
00076 return u;
00077 }
00078
00079 Double_t St_svtHybridDriftVelocityC::vHat(svtHybridDriftVelocity_st *p, Double_t anode) {
00080 if (! p) return -99;
00081 Double_t v = 1 - anode/mNoAnodes;
00082 if (p->hybrid == 1) v = -v;
00083 return v;
00084 }
00085
00086 Double_t St_svtHybridDriftVelocityC::CalcDriftLength(svtHybridDriftVelocity_st *p, Double_t timeBin, Double_t anode) {
00087 if (! p) return -99;
00088 Double_t u = uHat(p,timeBin);
00089 Double_t uD = mWaferLength*u;
00090 Double_t *coef = &p->v0;
00091 Int_t nu = p->npar%10;
00092 if (nu > 0) uD -= STcheb(nu-1, coef, TMath::Abs(u));
00093 Int_t nv = (p->npar/10)%10;
00094 if (nv > 0) {
00095 Double_t v = vHat(p,anode);
00096 uD -= STcheb(nv-1, &coef[nu], TMath::Abs(v));
00097 }
00098 return uD;
00099 }
00100
00101 Double_t St_svtHybridDriftVelocityC::UnCalcDriftLength(svtHybridDriftVelocity_st *p, Double_t x) {
00102 if (! p) return -99;
00103 Double_t d = TMath::Min(mWaferLength,TMath::Max(0.,x));
00104 return p->tmin + (p->tmax - p->tmin)*d/mWaferLength;
00105 }
00106
00107 Double_t St_svtHybridDriftVelocityC::DriftVelocity(svtHybridDriftVelocity_st *p) {
00108 return p ? mSamplingFrequency*mWaferLength/(p->tmax - p->tmin): -1;
00109 }
00110
00111 Double_t St_svtHybridDriftVelocityC::CalcU(Int_t barrel, Int_t ladder, Int_t wafer, Int_t hybrid, Double_t timeBin, Double_t anode) {
00112 return CalcDriftLength(barrel, ladder, wafer, hybrid, timeBin, anode);
00113 }
00114
00115 Double_t St_svtHybridDriftVelocityC::CalcV(Int_t hybrid, Double_t x) {
00116 Double_t vd = CalcTransLength(x);
00117 if (hybrid == 1) vd = vd - WaferWidth();
00118 else vd = WaferWidth() - vd;
00119 return vd;
00120 }
00121
00122 Double_t St_svtHybridDriftVelocityC::UnCalcU(Int_t barrel, Int_t ladder, Int_t wafer, Int_t hybrid, Double_t ud) {
00123 if (hybrid == 1) ud = ud + WaferLength();
00124 else ud = WaferLength() - ud;
00125 return UnCalcDriftLength(barrel, ladder, wafer, hybrid, ud);
00126 }
00127
00128 Double_t St_svtHybridDriftVelocityC::UnCalcV(Int_t hybrid, Double_t vd) {
00129 if (hybrid == 1) vd = vd + WaferWidth();
00130 else vd = WaferWidth() - vd;
00131 return UnCalcTransLength(vd);
00132 }
00133
00134 Bool_t St_svtHybridDriftVelocityC::IsValidDriftRegion(Int_t barrel, Int_t ladder, Int_t wafer, Int_t hybrid, Double_t timeBin) {
00135 svtHybridDriftVelocity_st *pp = p(barrel, ladder, wafer, hybrid);
00136 if (! pp) return kFALSE;
00137 Int_t I = (pp->npar/100)%10;
00138 if (! I) return kTRUE;
00139 Double_t u = TMath::Abs(uHat(pp,timeBin));
00140 if (u >= pp->dtmin && u <= pp->dtmax) return kTRUE;
00141 return kFALSE;
00142 }