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