68 #include "PhysicalConstants.h"
70 #include "StFtpcSlowSimField.hh"
71 #include "StFtpcClusterMaker/StFtpcParamReader.hh"
72 #include "StFtpcClusterMaker/StFtpcDbReader.hh"
83 innerRadius = mDb->sensitiveVolumeInnerRadius();
84 outerRadius = mDb->sensitiveVolumeOuterRadius();
85 angleFactor = mParam->lorentzAngleFactor();
87 grid_point =
new grid_data[mParam->numSlowSimGridPoints()];
90 float cathodeVoltage = mParam->chamberCathodeVoltage();
93 del_r = (outerRadius - innerRadius)
94 / (
float) (mParam->numSlowSimGridPoints()-1);
95 inverseDeltaRadius = 1/del_r;
96 twoDeltaRadius = 2*del_r;
98 int num_data = mParam->numberOfFssGasValues();
99 float * in_efield =
new float[num_data];
100 float * in_velocity_z =
new float[num_data];
101 float * in_diffusion_z =
new float[num_data];
102 float * in_diffusion_x =
new float[num_data];
103 float * in_diffusion_y =
new float[num_data];
104 float * in_angle_lorentz =
new float[num_data];
105 for ( i=0; i<num_data; i++) {
106 in_efield[i] = mParam->fssGasEField(i);
107 in_velocity_z[i] = mParam->fssGasVDrift(i);
108 in_diffusion_z[i] = mParam->fssGasDiffusionZ(i);
109 in_diffusion_x[i] = mParam->fssGasDiffusionX(i);
110 in_diffusion_y[i] = mParam->fssGasDiffusionY(i);
111 in_angle_lorentz[i] = mParam->fssGasLorentzAngle(i);
116 for ( i=0; i<mParam->numSlowSimGridPoints(); i++) {
118 grid_point[i].rhit = innerRadius + i * del_r;
120 eff = fabs(cathodeVoltage) / ::log(outerRadius / innerRadius)
121 / grid_point[i].rhit;
122 grid_point[i].ef = eff;
124 int index = Locate(num_data, in_efield, eff);
127 = Interpolate(num_data,in_efield,in_velocity_z,index,eff);
128 float diffusionX=Interpolate(num_data,in_efield,in_diffusion_x,
130 float diffusionY=Interpolate(num_data,in_efield,in_diffusion_y,
132 float diffusionZ=Interpolate(num_data,in_efield,in_diffusion_z,
135 = diffusionZ*diffusionZ;
137 = diffusionX*diffusionY;
142 for (i=mParam->numSlowSimGridPoints()-1; i>0; i--) {
143 grid_point[i].dlnv_dr
144 = ( 1. - grid_point[i-1].vel_z/grid_point[i].vel_z)
147 grid_point[0].dlnv_dr = grid_point[1].dlnv_dr;
149 delete [] in_velocity_z;
150 delete [] in_diffusion_z;
151 delete [] in_diffusion_x;
152 delete [] in_diffusion_y;
153 delete [] in_angle_lorentz;
155 radTimesField = mDb->radiusTimesField();
156 nPadrowPositions = mDb->numberOfPadrowsPerSide();
157 nMagboltzBins = mDb->numberOfMagboltzBins();
158 preciseEField =
new float[nMagboltzBins];
159 inverseDriftVelocityWest =
new float[nMagboltzBins*nPadrowPositions];
160 preciseLorentzAngleWest =
new float[nMagboltzBins*nPadrowPositions];
161 inverseDriftVelocityEast =
new float[nMagboltzBins*nPadrowPositions];
162 preciseLorentzAngleEast =
new float[nMagboltzBins*nPadrowPositions];
170 float deltaP = mParam->adjustedAirPressureWest() - mParam->standardPressure();
172 {
for(
int i=0; i<nMagboltzBins; i++)
174 preciseEField[i] = mDb->magboltzEField(i);
175 for(
int j=0; j<nPadrowPositions; j++)
177 inverseDriftVelocityWest[i+nMagboltzBins*j] =
178 1/ (mDb->magboltzVDrift(i,j)
179 + deltaP * mDb->magboltzdVDriftdP(i,j));
180 preciseLorentzAngleWest[i+nMagboltzBins*j] =
181 mDb->magboltzDeflection(i,j)
182 + deltaP * mDb->magboltzdDeflectiondP(i,j);
187 deltaP = mParam->adjustedAirPressureEast() - mParam->standardPressure();
189 {
for(
int i=0; i<nMagboltzBins; i++)
191 for(
int j=0; j<nPadrowPositions; j++)
193 inverseDriftVelocityEast[i+nMagboltzBins*j] =
194 1/ (mDb->magboltzVDrift(i,j)
195 + deltaP * mDb->magboltzdVDriftdP(i,j));
196 preciseLorentzAngleEast[i+nMagboltzBins*j] =
197 mDb->magboltzDeflection(i,j)
198 + deltaP * mDb->magboltzdDeflectiondP(i,j);
201 EFieldMin=preciseEField[0];
202 EFieldStep=preciseEField[1]-EFieldMin;
203 EFieldStepInverted= 1/EFieldStep;
204 EFieldStepInvConverted= EFieldStepInverted * degree;
205 finalVelocity = grid_point[mParam->numSlowSimGridPoints()-1].vel_z*10.;
208 mOffsetCathodeWest = mDb->offsetCathodeWest();
209 mOffsetCathodeEast = mDb->offsetCathodeEast();
210 mAngleOffsetWest = mDb->angleOffsetWest();
211 mAngleOffsetEast = mDb->angleOffsetEast();
216 StFtpcSlowSimField::~StFtpcSlowSimField() {
217 delete[] preciseEField;
218 delete[] inverseDriftVelocityWest;
219 delete[] preciseLorentzAngleWest;
220 delete[] inverseDriftVelocityEast;
221 delete[] preciseLorentzAngleEast;
225 float StFtpcSlowSimField::Interpolate(
const int npt,
const float* x,
226 const float* y,
const int ich,
238 for ( i=0; i<2; i++) {
242 return InterpValue(2, x1, y1, xx);
244 else if (ich > npt-3) {
245 for ( i=0; i<2; i++) {
246 x1[i] = *(x+npt-1-i) ;
247 y1[i] = *(y+npt-1-i) ;
249 return InterpValue(2, x1, y1, xx);
252 for ( i=0; i<5; i++) {
253 x1[i] = *(x+ich-2+i) ;
254 y1[i] = *(y+ich-2+i) ;
256 return InterpValue(5, x1, y1, xx);
260 float StFtpcSlowSimField::InterpValue(
const int npt,
const float* x,
261 const float* y,
const float xx)
269 for(
register int i=0; i < npt; i++) {
271 for(
register int j=0; j < npt; j++) {
272 if (j != i) term *= (xx-x[j])/(x[i]-x[j]);
281 void StFtpcSlowSimField::GetVelocityZ(
const float inverseRadius,
const int padrow,
const float phi,
float *inverseVelocity,
float *angle)
288 float phis = phi - TMath::Pi()/2;
291 xOff = mOffsetCathodeWest;
292 angleOff = -mAngleOffsetWest;
293 phis -= TMath::Pi()/2;
296 xOff = mOffsetCathodeEast;
297 angleOff = -mAngleOffsetEast;
304 if (phis < 0) phis += 2*TMath::Pi();
305 if (phis > 2*TMath::Pi()) phis -= 2*TMath::Pi();
307 if (phis > TMath::Pi()) phis = 2 * TMath::Pi() - phis;
310 newR = innerRadius + xOff;
311 else if (phis == TMath::Pi())
312 newR = innerRadius - xOff;
314 float asinSum = TMath::ASin(xOff/innerRadius * TMath::Sin(phis));
315 if (asinSum < 0 ) asinSum = asinSum* (-1);
316 newR = innerRadius/TMath::Sin(phis) * TMath::Sin(TMath::Pi() - phis - asinSum);
322 int fieldPadrow = padrow;
323 if (padrow >= 10) fieldPadrow = padrow - 10;
326 float e_now=radTimesField * inverseRadius * (::log(outerRadius / (innerRadius))/::log(outerRadius / newR));
327 int iLower= (int)((e_now-EFieldMin)*EFieldStepInverted);
328 int iUpper= iLower + 1;
329 int padrowIndex= nMagboltzBins*fieldPadrow;
330 float diffUp=preciseEField[iUpper]-e_now;
331 float diffDown=e_now-preciseEField[iLower];
335 *inverseVelocity = EFieldStepInverted*((inverseDriftVelocityWest[iUpper])*diffDown + (inverseDriftVelocityWest[iLower])*diffUp);
336 *angle = EFieldStepInvConverted*((preciseLorentzAngleWest[iUpper])*diffDown + (preciseLorentzAngleWest[iLower])*diffUp);
339 *inverseVelocity = EFieldStepInverted*((inverseDriftVelocityEast[iUpper])*diffDown + (inverseDriftVelocityEast[iLower])*diffUp);
340 *angle = EFieldStepInvConverted*((preciseLorentzAngleEast[iUpper])*diffDown + (preciseLorentzAngleEast[iLower])*diffUp);
346 void StFtpcSlowSimField::Output()
const
348 ofstream fout(
"field.dat");
351 for (
int i=0; i<mParam->numSlowSimGridPoints(); i++) {
352 fout << grid_point[i].rhit << space
353 << grid_point[i].ef << space
354 << grid_point[i].vel_z << space
355 << grid_point[i].diff_z<< space
356 << grid_point[i].diff_x<< space
357 << grid_point[i].lorentz/degree << space
358 << grid_point[i].dlnv_dr
359 *mParam->lorentzAngleFactor()