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