17 RawParticle(myPart), rCyl(R), rCyl2(R*R), zCyl(Z),
bField(B), properDecayTime(1E99)
71 double b2 =
rCyl2 * pT2;
72 double ac = fabs (
X()*Py() -
Y()*Px() );
78 if ( ac2 > b2 )
return false;
82 double tplus = -(
X()*Px()+
Y()*Py() ) + delta;
83 double tminus = -(
X()*Px()+
Y()*Py() ) - delta;
88 double solution = tminus < 0 ? tplus/pT2 : tminus/pT2;
89 if ( solution < 0. )
return false;
93 double zProp =
Z() + Pz() * solution;
94 if ( fabs(zProp) >
zCyl ) {
95 tplus = (
zCyl -
Z() ) / Pz();
96 tminus = (-
zCyl -
Z() ) / Pz();
97 solution = tminus < 0 ? tplus : tminus;
98 if ( solution < 0. )
return false;
99 zProp =
Z() + Pz() * solution;
121 double xProp =
X() + Px() * solution * factor;
122 double yProp =
Y() + Py() * solution * factor;
123 zProp =
Z() + Pz() * solution * factor;
124 double tProp =
T() + E() * solution * factor;
130 if (
success == 2 && xProp*xProp+yProp*yProp >
rCyl2 ) {
158 if ( fabs ( fabs(radius) - dist ) >
rCyl )
return false;
163 if (
Z() * Pz() >
zCyl * fabs(Pz()) ) {
169 double phiProp, zProp;
173 double rProp =
std::min(fabs(radius)+dist-0.000001,
rCyl);
177 (rProp*rProp-radius*radius-dist*dist)/( 2.*dist*radius);
183 if ( 1.-fabs(sinPhiProp) < 1E-9 ) {
187 double r0 = (
X()*cphi0 +
Y()*sphi0)/radius;
188 double q0 = (
X()*sphi0 -
Y()*cphi0)/radius;
189 double rcyl2 = (
rCyl2 -
X()*
X() -
Y()*
Y())/(radius*radius);
190 double delta = r0*r0 + rcyl2*(1.-
q0);
194 deltaPhi = radius > 0 ?
201 if ( fabs(deltaPhi) > 1E-3 ) {
205 phiProp = std::asin(sinPhiProp);
217 if ( fabs(phiProp - phi0) > 2.*
M_PI )
218 phiProp += ( phiProp > phi0 ? -2.*
M_PI : +2.*
M_PI );
224 if ( (phiProp-phi0)*radius < 0.0 )
225 radius > 0.0 ? phiProp += 2 *
M_PI : phiProp -= 2 *
M_PI;
237 zProp =
Z() + ( phiProp - phi0 ) * pZ * radius / pT ;
238 if ( fabs(zProp) >
zCyl ) {
240 zProp =
zCyl * fabs(pZ)/pZ;
241 phiProp = phi0 + (zProp -
Z()) / radius * pT / pZ;
250 if ( rProp <
rCyl ) {
252 if (
firstLoop || fabs(pZ)/pT < 1E-10 ) {
258 zProp =
zCyl * fabs(pZ)/pZ;
259 phiProp = phi0 + (zProp -
Z()) / radius * pT / pZ;
278 double delTime =
propDir * (phiProp-phi0)*radius*
mass() / pT;
287 zProp =
Z() + (zProp-
Z())*factor;
289 phiProp = phi0 + (phiProp-phi0)*factor;
293 double xProp = xC + radius * sProp;
294 double yProp = yC - radius * cProp;
295 double tProp =
T() + (phiProp-phi0)*radius*E()/pT;
296 double pxProp = pT * cProp;
297 double pyProp = pT * sProp;
303 if (
success == 2 && xProp*xProp+yProp*yProp >
rCyl2 ) {
311 SetXYZT(pxProp,pyProp,pZ,E());
323 SetXYZT(-Px(),-Py(),-Pz(),E());
327 SetXYZT(-Px(),-Py(),-Pz(),E());
377 rz = fabs ( fabs(radius) - distz ) +
std::sqrt(x0*x0+y0*y0) + 0.0000001;
378 r0 = fabs ( fabs(radius) - dist0 ) + 0.0000001;
380 rz = fabs( Px() * (
Y()-y0) - Py() * (
X()-x0) ) /
Pt();
381 r0 = fabs( Px() *
Y() - Py() *
X() ) /
Pt();
392 if ( !done )
return done;
395 if ( fabs(rz-r0) < 1E-10 )
return done;
396 double dist1 = (
X()-x0)*(
X()-x0) + (
Y()-y0)*(
Y()-y0);
399 if ( dist1 < 1E-10 )
return done;
408 if ( !done )
return done;
414 if ( !done )
return done;
415 double dist2 = (
X()-x0)*(
X()-x0) + (
Y()-y0)*(
Y()-y0);
418 if ( dist2 > dist1 ) {
420 SetXYZT(momentum1.X(),momentum1.Y(),momentum1.Z(),momentum1.E());
459 if ( done && (
R2() > 125.0*125.0 ||
R2() < 45.0*45.0) )
479 if ( done && (
R2() > 125.0*125.0 ||
R2() < 45.0*45.0 ) )
560 if ( done && ( c2teta < 0.99014 || c2teta > 0.9998755 ) )
success = 0;
614 double dx =
X()-v.X();
615 double dy =
Y()-v.Y();
635 return fabs( Px() *
Y() - Py() *
X() ) /
Pt() <
radius;
645 double dx =
X()-v.X();
646 double dy =
Y()-v.Y();
647 double dz =
Z()-v.Z();
648 double Sxy =
X()*v.X() +
Y()*v.Y();
649 double Dxy =
Y()*v.X() -
X()*v.Y();
650 double Dxy2 = Dxy*Dxy;
651 double Sxy2 = Sxy*Sxy;
652 double SDxy = dx*dx + dy*dy;
654 double ATxy = std::atan2(dy,dx);
656 double a = r2 - Dxy2/SDxy;
657 double b = r * (r2 - Sxy);
658 double c = r4 - 2.*Sxy*r2 + Sxy2 + Dxy2;
662 std::vector<double> helixRs(4,static_cast<double>(0.));
663 helixRs[0] = (b -
std::sqrt(b*b - a*c))/(2.*a);
664 helixRs[1] = (b +
std::sqrt(b*b - a*c))/(2.*a);
665 helixRs[2] = -helixRs[0];
666 helixRs[3] = -helixRs[1];
668 std::vector<double> helixPhis(4,static_cast<double>(0.));
669 helixPhis[0] = std::asin ( SSDxy/(2.*helixRs[0]) );
670 helixPhis[1] = std::asin ( SSDxy/(2.*helixRs[1]) );
671 helixPhis[2] = -helixPhis[0];
672 helixPhis[3] = -helixPhis[1];
679 for (
unsigned int i=0;
i<4; ++
i ) {
680 helixPhis[
i] = ATxy + helixPhis[
i];
693 if ( fabs( fabs(fabs(helixRs[i]) - dist) -fabs(radius) ) < 1
e-6 ) {
695 if ( solution1 == 0. ) {
696 solution1 = helixRs[
i];
699 }
else if ( solution2 == 0. ) {
700 if ( helixRs[i] < solution1 ) {
701 solution2 = solution1;
702 solution1 = helixRs[
i];
706 solution2 = helixRs[
i];
711 std::cout <<
"warning !!! More than two solutions for this track !!! " << std::endl;
718 double helixPhi = 0.;
721 if ( solution1*solution2 == 0. ) {
722 std::cout <<
"warning !!! Less than two solution for this track! "
723 << solution1 <<
" " << solution2 << std::endl;
726 }
else if ( solution1*solution2 < 0. ) {
728 double norm = pT/SSDxy;
730 SetXYZT(dx*norm,dy*norm,dz*norm,0.);
744 double norm = pT/SSDxy;
768 ip = distz - fabs(radius);
770 ip = fabs( Px() * (
Y()-y0) - Py() * (
X()-x0) ) / pT;
const double Z[kNumberCalorimeter]
double zCyl
Half-height of the cylinder (centred at 0,0,0) to which propagation is done.
void setCharge(float q)
set the MEASURED charge
double helixRadius() const
The helix Radius.
double helixCentrePhi() const
The azimuth if the vector joining the cylinder and the helix axes.
bool propagateToPreshowerLayer1(bool first=true)
double rCyl
Simulated particle that is to be resp has been propagated.
bool propagateToNominalVertex(const XYZTLorentzVector &hit2=XYZTLorentzVector(0., 0., 0., 0.))
void init()
Initialize internal switches and quantities.
double z() const
z of vertex
bool firstLoop
Do only the first half-loop.
int success
0:propagation still be done, 1:reached 'barrel', 2:reached 'endcaps'
double properTime
The proper time of the particle.
Sin< T >::type sin(const T &t)
BaseParticlePropagator()
Default c'tor.
bool propagateToBeamCylinder(const XYZTLorentzVector &v, double radius=0.)
void setPropagationConditions(double r, double z, bool firstLoop=true)
Set the propagation characteristics (rCyl, zCyl and first loop only)
double mass() const
get the MEASURED mass
double c_light() const
The speed of light in mm/ns (!) without clhep (yeaaahhh!)
double R() const
vertex radius
double R2() const
vertex radius**2
bool propagateToEcal(bool first=true)
bool propagateToClosestApproach(double x0=0., double y0=0, bool first=true)
double helixCentreX() const
The x coordinate of the helix axis.
bool propagateToVFcalEntrance(bool first=true)
const XYZTLorentzVector & momentum() const
the momentum fourvector
double helixCentreDistToAxis() const
The distance between the cylinder and the helix axes.
double r2() const
vertex radius**2
double properDecayTime
The proper decay time of the particle.
bool propagateToHcalExit(bool first=true)
double cos2ThetaV() const
Cos< T >::type cos(const T &t)
double Y() const
y of vertex
double Z() const
z of vertex
double charge() const
get the MEASURED charge
int propDir
The propagation direction.
bool propagateToEcalEntrance(bool first=true)
const XYZTLorentzVector & vertex() const
the vertex fourvector
bool onEndcap() const
Is the vertex already on the cylinder endcap ?
bool decayed
The particle decayed while propagated !
BaseParticlePropagator propagated() const
double helixCentreY() const
The y coordinate of the helix axis.
bool inside() const
Is the vertex inside the cylinder ? (stricly inside : true)
bool onSurface() const
Is the vertex already on the cylinder surface ?
double r() const
vertex radius
double X() const
x of vertex
bool debug
The debug level.
double helixStartPhi() const
The azimuth of the momentum at the vertex.
bool propagateToHcalEntrance(bool first=true)
double bField
Magnetic field in the cylinder, oriented along the Z axis.
double T() const
vertex time
bool propagateToHOLayer(bool first=true)
bool onBarrel() const
Is the vertex already on the cylinder barrel ?
bool propagateToPreshowerLayer2(bool first=true)
void setVertex(const XYZTLorentzVector &vtx)
set the vertex
double xyImpactParameter(double x0=0., double y0=0.) const
Transverse impact parameter.
bool fiducial
The particle traverses some real material.
math::XYZTLorentzVector XYZTLorentzVector