00001 #include "Helper.h"
00002 #include <math.h>
00003
00004
00005
00006 #include "TRandom.h"
00007
00008
00009
00010
00011 static Double_t sectorX[] = {
00012 0, 0,
00013 0.866025403784439, -0.5,
00014 0.5, -0.866025403784439,
00015 0, -1,
00016 -0.5, -0.866025403784439,
00017 -0.866025403784439, -0.5,
00018 -1, 0,
00019 -0.866025403784439, 0.5,
00020 -0.5, 0.866025403784438,
00021 0, 1,
00022 0.5, 0.866025403784439,
00023 0.866025403784438, 0.5,
00024 1, 0,
00025 0.866025403784439, 0.5,
00026 0.5, 0.866025403784438,
00027 0, 1,
00028 -0.5, 0.866025403784439,
00029 -0.866025403784439, 0.5,
00030 -1, 0,
00031 -0.866025403784439, -0.5,
00032 -0.5, -0.866025403784439,
00033 0, -1,
00034 0.5, -0.866025403784439,
00035 0.866025403784438, -0.5,
00036 1, 0
00037 };
00038
00039
00040
00041 static Double_t sectorY[] = {
00042 0,0,
00043 0.5, 0.866025403784439,
00044 0.866025403784439, 0.5,
00045 1, 0,
00046 0.866025403784439, -0.5,
00047 0.5, -0.866025403784439,
00048 0, -1,
00049 -0.5, -0.866025403784439,
00050 -0.866025403784439, -0.5,
00051 -1, 0,
00052 -0.866025403784439, 0.5,
00053 -0.5, 0.866025403784438,
00054 0, 1,
00055 -0.5, 0.866025403784439,
00056 -0.866025403784439, 0.5,
00057 -1, 0,
00058 -0.866025403784439, -0.5,
00059 -0.5, -0.866025403784439,
00060 0, -1,
00061 0.5, -0.866025403784439,
00062 0.866025403784438, -0.5,
00063 1, 0,
00064 0.866025403784438, 0.5,
00065 0.5, 0.866025403784439,
00066 0, 1
00067 };
00068
00069
00070
00071
00072
00073
00074 double distance(double a1, double b1, double a2, double b2){
00075 return sqrt( (a1-b1)*(a1-b1) + (a2-b2)*(a2-b2) );
00076 }
00077
00078
00079
00080
00081 double distance(const StThreeVectorF& point1,
00082 const StThreeVectorF& point2)
00083 {
00084 return (point1-point2).mag();
00085 }
00086
00087
00088 double dca3d(const StPhysicalHelixD& helix, const StThreeVectorF& point)
00089 {
00090 return helix.distance(point);
00091
00092 }
00093
00094 double dca2d(const StPhysicalHelixD& helix, const StThreeVectorF& point,
00095 const StThreeVectorF* origin)
00096 {
00097 if(fabs(helix.curvature())<=static_cast<double>(0)){
00098 return lineDca2D(helix,point,*origin);
00099 }
00100 else{
00101 return helixDca2D(helix,point);
00102 }
00103 }
00104
00105
00106 double dcaz(const StPhysicalHelixD& helix, const StThreeVectorF& point)
00107 {
00108 pairD path = helix.pathLength(point.perp());
00109
00110 const StThreeVectorD& pos1 = helix.at(path.first);
00111 const StThreeVectorD& pos2 = helix.at(path.second);
00112 const StThreeVectorD dis1 = point - pos1;
00113 const StThreeVectorD dis2 = point - pos2;
00114
00115 double dcaZ = (dis1.mag() < dis2.mag()) ? dis1.z() : dis2.z();
00116 if(isnan(dcaZ)) return 999;
00117 return dcaZ;
00118 }
00119
00120
00121 double crossingAngle(const StPhysicalHelixD& helix,
00122 const StTpcHit* hit, float bField)
00123 {
00124 if(fabs(helix.curvature())<=static_cast<double>(0)){
00125 return lineCrossingAngle(helix,hit);
00126 }
00127 else{
00128 return helixCrossingAngle(helix,hit,bField);
00129 }
00130 }
00131
00132 double padrowDca(const StPhysicalHelixD& helix,
00133 const StTpcHit* hit)
00134 {
00135 if(fabs(helix.curvature())<=static_cast<double>(0)){
00136 return linePadrowDca(helix,hit);
00137 }
00138 else{
00139 return helixPadrowDca(helix,hit);
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148 double
00149 propagateToPadrow(const StPhysicalHelixD& helix,
00150 const StTpcHit* hit)
00151 {
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 double R = 1./helix.curvature();
00172 double dX = hit->position().x() - helix.xcenter();
00173 double dY = hit->position().y() - helix.ycenter();
00174
00175
00176
00177
00178
00179
00180
00181 double d = TMath::Sqrt(dX*dX + dY*dY);
00182 double dPerp = dX*sectorY[2*hit->sector()] +
00183 dY*sectorY[2*hit->sector() + 1];
00184
00185 double x;
00186 if(dPerp >= R){
00187
00188
00189
00190
00191 x = - dX*sectorY[2*hit->sector() + 1] +
00192 dY*sectorY[2*hit->sector()];
00193 }else{
00194
00195 double cosTheta = (dX*sectorX[2*hit->sector()] +
00196 dY*sectorX[2*hit->sector() + 1])/d;
00197
00198 x = -d*cosTheta + (cosTheta<0 ? -1. : 1.) *
00199 TMath::Sqrt(R*R - d*d*(1 - cosTheta*cosTheta));
00200 }
00201
00202
00203
00204 dX = hit->position().x() + x*sectorX[2*hit->sector()];
00205 dY = hit->position().y() + x*sectorX[2*hit->sector() + 1];
00206
00207
00208
00209
00210
00211
00212
00213
00214 double s = helix.pathLength(dX, dY);
00215
00216
00217
00218
00219
00220
00221
00222 return s;
00223
00224 }
00225
00226
00227
00228 double
00229 helixPadrowDca(const StPhysicalHelixD& helix,
00230 const StTpcHit* hit)
00231 {
00232
00233
00234 double s = propagateToPadrow(helix, hit);
00235 double dX = hit->position().x() - helix.x(s);
00236 double dY = hit->position().y() - helix.y(s);
00237 double dca = TMath::Sqrt(dX*dX + dY*dY);
00238
00239
00240 if (helixDca2D(helix, hit->position()) < 0) dca *= -1.;
00241
00242
00243
00244
00245
00246
00247
00248 return dca;
00249 }
00250
00251 double helixCrossingAngle(float pt,float phi,int sector)
00252 {
00253 double px=pt*cos(phi);
00254 double py=pt*sin(phi);
00255 double cosTheta = (px*sectorY[2*sector] +
00256 py*sectorY[2*sector + 1])/pt;
00257
00258 if (cosTheta < 0){
00259 cosTheta *= -1.;
00260 px *= -1; py *= -1;
00261 }
00262
00263 double theta = TMath::ACos(cosTheta);
00264 if (px*sectorY[2*sector + 1] -
00265 py*sectorY[2*sector] > 0) theta *= -1.;
00266
00267
00268
00269 return theta;
00270 }
00271
00272
00273 double
00274 helixCrossingAngle(const StPhysicalHelixD& helix,
00275 const StTpcHit* hit,
00276 float bField){
00277
00278
00279 double s = propagateToPadrow(helix, hit);
00280
00281
00282
00283
00284 StThreeVectorD p(helix.momentumAt(s, bField));
00285
00286
00287
00288 double cosTheta = (p.x()*sectorY[2*hit->sector()] +
00289 p.y()*sectorY[2*hit->sector() + 1])/p.perp();
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 if (cosTheta < 0){
00300 cosTheta *= -1.;
00301 p.setX(-p.x());
00302 p.setY(-p.y());
00303 }
00304
00305
00306
00307
00308
00309
00310 double theta = TMath::ACos(cosTheta);
00311 if (p.x()*sectorY[2*hit->sector() + 1] -
00312 p.y()*sectorY[2*hit->sector()] > 0) theta *= -1.;
00313
00314
00315
00316 return theta;
00317 }
00318
00319 double helixDca2D(const StPhysicalHelixD &helix, const StThreeVectorF& point)
00320 {
00321 return (distance(helix.xcenter(),point.x(),helix.ycenter(),point.y())
00322 -(1./helix.curvature()));
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 StThreeVectorF
00332 lineAt2d(const StPhysicalHelixD& helix,
00333 const StThreeVectorF& point)
00334 {
00335
00336
00337
00338
00339
00340 const StThreeVectorD& origin = helix.origin();
00341 double cosPhase = cos(helix.phase());
00342 double sinPhase = sin(helix.phase());
00343
00344 double px = point.x();
00345 double py = point.y();
00346 double dx = px-origin.x();
00347 double dy = py-origin.y();
00348
00349 double s = cosPhase*dy-sinPhase*dx;
00350
00351
00352 double xDca = origin.x() - s*sinPhase;
00353 double yDca = origin.y() + s*cosPhase;
00354
00355 StThreeVectorF vec(xDca,yDca,0);
00356 return vec;
00357 }
00358
00359
00360
00361
00362 double
00363 linePadrowDca(const StPhysicalHelixD& helix,
00364 const StTpcHit* hit)
00365 {
00366
00367
00368
00369
00370
00371
00372
00373 StThreeVectorF at = lineAt2d(helix,hit->position());
00374
00375
00376 StThreeVectorF perp = (hit->position() - at);
00377
00378
00379 double cosTheta =
00380 (perp.x()*sectorX[2*hit->sector()] +
00381 perp.y()*sectorX[2*hit->sector()+1])/perp.perp();
00382
00383 double padrowDca = perp.perp()/fabs(cosTheta);
00384
00385
00386 StThreeVectorF origin(0,0,0);
00387 double sign = lineDca2D(helix,hit->position(),origin);
00388
00389 return (sign>=0) ? padrowDca : -padrowDca;
00390 }
00391
00392 double
00393 lineCrossingAngle(const StPhysicalHelixD& helix,
00394 const StTpcHit* hit)
00395 {
00396
00397 double psi = helix.phase() + TMath::Pi()/2.;
00398 double psiX = cos(psi);
00399 double psiY = sin(psi);
00400
00401 double cosTheta =
00402 psiX*sectorY[2*hit->sector()] + psiY*sectorY[2*hit->sector()+1];
00403
00404
00405 if(cosTheta<0){
00406 cout << "%%% line crossing angle negative? "
00407 << cosTheta << endl;
00408 return 99;
00409 }
00410
00411
00412 double sign = psiX*sectorY[2*hit->sector()+1]-psiY*sectorY[2*hit->sector()];
00413
00414 return (sign>0) ? acos(cosTheta) : -acos(cosTheta);
00415 }
00416
00417 double
00418 lineCrossingAngle(const StPhysicalHelixD& helix,
00419 const int sector)
00420 {
00421
00422 double psi = helix.phase() + TMath::Pi()/2.;
00423 double psiX = cos(psi);
00424 double psiY = sin(psi);
00425
00426 double cosTheta =
00427 psiX*sectorY[2*sector] + psiY*sectorY[2*sector+1];
00428
00429
00430 if(cosTheta<0){
00431 cout << "%%% line crossing angle negative? "
00432 << cosTheta << endl;
00433 return 99;
00434 }
00435
00436
00437 double sign = psiX*sectorY[2*sector+1]-psiY*sectorY[2*sector];
00438
00439 return (sign>0) ? acos(cosTheta) : -acos(cosTheta);
00440 }
00441
00442 double
00443 lineDca2D(const StPhysicalHelixD& helix,
00444 const StThreeVectorF& hit,
00445 const StThreeVectorF& origin)
00446 {
00447
00448 StThreeVectorF atHit = lineAt2d(helix,hit);
00449
00450
00451 StThreeVectorF atOrigin = lineAt2d(helix,origin);
00452
00453
00454 StThreeVectorF origin2atHit = (atHit-atOrigin);
00455
00456
00457 StThreeVectorF origin2hit = (hit-atOrigin);
00458
00459
00460 StThreeVectorF dca = (hit-atHit);
00461
00462
00463 double cross = origin2atHit.x()*origin2hit.y()
00464 - origin2atHit.y()*origin2hit.x();
00465
00466 return (cross>=0) ? dca.perp() : - dca.perp();
00467
00468 }