File indexing completed on 2024-06-26 07:05:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "eicsmear/smear/RadialTracker.h"
0011
0012 #include <algorithm>
0013 #include <cmath>
0014 #include <limits>
0015 #include <list>
0016
0017 #include <TMath.h>
0018
0019 namespace {
0020
0021
0022 struct NoIntersection {
0023 bool operator()(const TVector3& v) const {
0024 return TMath::IsNaN(v.z());
0025 }
0026 };
0027
0028 }
0029
0030 namespace Smear {
0031
0032 RadialTracker::RadialTracker()
0033 : Tracker(2., 0.03, 0.001)
0034 , mNFitPoints(25.)
0035 , mInnerRadius(0.1)
0036 , mOuterRadius(1.)
0037 , mZMin(-1.5)
0038 , mZMax(1.5) {
0039 }
0040
0041 RadialTracker::RadialTracker(double inner, double outer,
0042 double zmin, double zmax,
0043 double Bb, double nrl,
0044 double sigmaRPhi, double N)
0045 : Tracker(Bb, nrl, sigmaRPhi)
0046 , mNFitPoints(N)
0047 , mInnerRadius(inner)
0048 , mOuterRadius(outer)
0049
0050 , mZMin(std::min(zmin, zmax))
0051 , mZMax(std::max(zmin, zmax)) {
0052 }
0053
0054 RadialTracker::~RadialTracker() {
0055 }
0056
0057 void RadialTracker::Print(Option_t* ) const {
0058 std::cout << ClassName() << " with:" << std::endl <<
0059 "\tinner radius " << mInnerRadius << " m\n" <<
0060 "\touter radius " << mOuterRadius << " m\n" <<
0061 "\tlength " << mZMin << " to " << mZMax <<
0062 " (= " << mZMax - mZMin << ") m\n" <<
0063 "\tmagnetic field " << mMagField << " Tesla\n" <<
0064 "\t" << mNRadLengths << " radiation lengths\n" <<
0065 "\tpoint resolution " << mSigmaRPhi * 1.e6 << " microns\n" <<
0066 "\t" << mNFitPoints << " fit points" << std::endl;
0067 }
0068
0069 TVector3 RadialTracker::ComputeIntersectionWithRadius(
0070 const erhic::VirtualParticle& p, double radius) const {
0071
0072
0073 const double z = radius / tan(p.GetTheta()) + p.GetVertex().z();
0074 TVector3 intersection(0., 0., std::numeric_limits<double>::quiet_NaN());
0075 if (z > mZMin && z < mZMax) {
0076
0077 intersection.SetXYZ(radius, 0., z);
0078 }
0079 return intersection;
0080 }
0081
0082 TVector3 RadialTracker::ComputeIntersectionWithPlane(
0083 const erhic::VirtualParticle& p, double z) const {
0084
0085
0086 const double r = (z - p.GetVertex().z()) * tan(p.GetTheta());
0087 TVector3 intersection(0., 0., std::numeric_limits<double>::quiet_NaN());
0088 if (r > mInnerRadius && r < mOuterRadius) {
0089
0090 intersection.SetXYZ(r, 0., z);
0091 }
0092 return intersection;
0093 }
0094
0095 TVector3 RadialTracker::ComputePath(const erhic::VirtualParticle& p) const {
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 std::list<TVector3> xyz;
0106 xyz.push_back(ComputeIntersectionWithRadius(p, mInnerRadius));
0107 xyz.push_back(ComputeIntersectionWithRadius(p, mOuterRadius));
0108 xyz.push_back(ComputeIntersectionWithPlane(p, mZMin));
0109 xyz.push_back(ComputeIntersectionWithPlane(p, mZMax));
0110
0111 xyz.erase(std::remove_if(xyz.begin(), xyz.end(), NoIntersection()),
0112 xyz.end());
0113
0114
0115
0116
0117 TVector3 path(0., 0., 0.);
0118 if (2 == xyz.size()) {
0119
0120
0121 if (xyz.front().Mag() > xyz.back().Mag()) {
0122 path = xyz.front() - xyz.back();
0123 } else {
0124 path = xyz.back() - xyz.front();
0125 }
0126 }
0127 return path;
0128 }
0129
0130 double RadialTracker::L(const erhic::VirtualParticle& p) const {
0131 double Length = ComputePath(p).Mag();
0132 return Length;
0133 }
0134
0135 double RadialTracker::LPrime(const erhic::VirtualParticle& p) const {
0136 return ComputePath(p).Perp();
0137 }
0138
0139 int RadialTracker::NPoints(const erhic::VirtualParticle& p) const {
0140 int n;
0141 float n_float;
0142 if (LPrime(p) == (mOuterRadius - mInnerRadius)) {
0143 n = mNFitPoints;
0144 } else {
0145 n_float = mNFitPoints * ComputePath(p).Perp() /
0146 (mOuterRadius - mInnerRadius);
0147 n = floor(n_float + 0.5);
0148 }
0149 return n;
0150 }
0151
0152 bool RadialTracker::Accepts(const erhic::VirtualParticle& p) const {
0153
0154
0155
0156 if (NPoints(p) > 2) {
0157 return true;
0158 }
0159 return false;
0160 }
0161
0162 double RadialTracker::GetThetaMin() const {
0163 if (mZMax > 0.) {
0164 return atan2(mInnerRadius, mZMax);
0165 } else {
0166 return atan2(mOuterRadius, mZMax);
0167 }
0168 }
0169
0170 double RadialTracker::GetThetaMax() const {
0171 if (mZMin > 0.) {
0172 return atan2(mOuterRadius, mZMin);
0173 } else {
0174 return atan2(mInnerRadius, mZMin);
0175 }
0176 }
0177
0178 }