9 #include <top/reconstruction_cpp/TOPTrack.h>
10 #include <top/reconstruction_cpp/TOPRecoManager.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 #include <framework/geometry/BFieldManager.h>
13 #include <framework/logging/Logger.h>
14 #include <mdst/dataobjects/Track.h>
15 #include <mdst/dataobjects/TrackFitResult.h>
16 #include <mdst/dataobjects/HitPatternCDC.h>
17 #include <tracking/dataobjects/ExtHit.h>
18 #include <top/dataobjects/TOPBarHit.h>
19 #include <top/dataobjects/TOPDigit.h>
20 #include <framework/datastore/StoreArray.h>
33 cosTh(dir.Z()), sinTh(sqrt(1 - cosTh * cosTh)), cosFi(dir.X() / sinTh), sinFi(dir.Y() / sinTh)
48 for (
const auto& extHit : extHits) {
49 if (abs(extHit.getPdgCode()) != pdgCode)
continue;
50 if (extHit.getDetectorID() != myDetID)
continue;
51 if (extHit.getCopyID() < 1 or extHit.getCopyID() > numModules)
continue;
52 if (extHit.getTOF() < tmin) {
61 set(track, digitsName, chargedStable);
67 if (not extHit)
return;
72 B2ERROR(
"TOPTrack: no related Track found for valid ExtHit");
78 B2ERROR(
"TOPTrack: extrapolation hypothesis of ExtHit is not ChargedStable");
84 set(*track, digitsName, chargedStable);
92 const auto* fitResult = track.getTrackFitResultWithClosestMass(chargedStable);
94 B2ERROR(
"TOPTrack: no TrackFitResult available for PDGCode = " << chargedStable.
getPDGCode());
97 m_pT = fitResult->getTransverseMomentum();
101 if (fitResult->getHitPatternCDC().getNHits() == 0)
return;
109 for (
const auto& barHit : barHits) {
118 m_charge = fitResult->getChargeSign();
125 unsigned numHitsOtherSlots = 0;
127 for (
const auto& digit : digits) {
128 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
144 double effi = (k < backgroundPDFs.size()) ? backgroundPDFs[k].getEfficiency() : 0;
146 for (
const auto& bkg : backgroundPDFs) effiSum += bkg.getEfficiency();
147 m_bkgRate = (effiSum > effi) ? numHitsOtherSlots * effi / (effiSum - effi) / timeWindow : 0;
153 B2ERROR(
"TOPTrack: YScanner for given module not found (must be a bug!)" <<
LogVar(
"slot",
m_moduleID));
157 unsigned numCols = yScanner->getPixelPositions().getNumPixelColumns();
159 unsigned col = (hit.pixelID - 1) % numCols;
174 const auto& module = geo->getModule(
m_moduleID);
176 auto position = module.pointGlobalToNominal(globalPosition);
189 std::vector<TVector3> points;
190 std::vector<TVector3> normals;
191 points.push_back(rotation * TVector3(0, -bar.
B / 2, 0) + translation);
192 normals.push_back(rotation * TVector3(0, -1, 0));
194 points.push_back(rotation * TVector3(0, bar.
B / 2, 0) + translation);
195 normals.push_back(rotation * TVector3(0, 1, 0));
197 points.push_back(rotation * TVector3(-bar.
A / 2, 0, 0) + translation);
198 normals.push_back(rotation * TVector3(-1, 0, 0));
200 points.push_back(rotation * TVector3(bar.
A / 2, 0, 0) + translation);
201 normals.push_back(rotation * TVector3(1, 0, 0));
205 std::vector<double> lengths;
206 std::vector<TVector3> positions;
207 for (
size_t i = 0; i < 2; i++) {
209 if (isnan(t))
return false;
211 if (abs(r.X()) > bar.
A / 2) {
212 auto k = (r.X() > 0) ? 3 : 2;
214 if (isnan(t))
return false;
216 if (r.Z() >= bar.
zL and abs(r.Y()) > bar.
B / 2)
return false;
218 lengths.push_back(t);
219 positions.push_back(r);
224 if (positions[0].Z() < bar.
zL or positions[1].Z() < bar.
zL) {
226 bool ok =
xsecPrism(lengths, positions, prism, rotation, translation);
227 if (not ok)
return false;
232 std::vector<bool> outOfBar;
233 TVector3 rc(mirror.
xc, mirror.
yc, mirror.
zc);
234 double Rsq = mirror.
R * mirror.
R;
235 for (
const auto& r : positions) {
236 outOfBar.push_back((r - rc).Mag2() > Rsq);
238 if (outOfBar[0] and outOfBar[1])
return false;
240 if (outOfBar[0] or outOfBar[1]) {
241 if (outOfBar[0]) std::reverse(lengths.begin(), lengths.end());
242 double t1 = lengths[0];
243 double t2 = lengths[1];
244 for (
int i = 0; i < 20; i++) {
245 double t = (t1 + t2) / 2;
247 if ((r - rc).Mag2() > Rsq) {
253 lengths[1] = (t1 + t2) / 2;
258 m_length = abs(lengths[1] - lengths[0]);
259 double length = (lengths[0] + lengths[1]) / 2;
272 const TVector3& translation)
274 std::vector<TVector3> points;
275 std::vector<TVector3> normals;
277 points.push_back(rotation * TVector3(0, prism.
yDown, 0) + translation);
278 normals.push_back(rotation * TVector3(0, -1, 0));
280 points.push_back(rotation * TVector3(0, prism.
yUp, 0) + translation);
281 normals.push_back(rotation * TVector3(0, 1, 0));
283 points.push_back(rotation * TVector3(-prism.
A / 2, 0, 0) + translation);
284 normals.push_back(rotation * TVector3(-1, 0, 0));
286 points.push_back(rotation * TVector3(prism.
A / 2, 0, 0) + translation);
287 normals.push_back(rotation * TVector3(1, 0, 0));
289 for (
size_t i = 0; i < 2; i++) {
290 if (positions[i].Z() < prism.
zR) {
292 if (isnan(t))
return false;
294 if (i == 0 and r.Z() > prism.
zFlat) {
295 auto point = rotation * TVector3(0, -prism.
B / 2, 0) + translation;
297 if (isnan(t1))
return false;
299 for (
int iter = 0; iter < 20; iter++) {
303 if (r.Y() < ySlanted) t2 = t;
308 if (abs(r.X()) > prism.
A / 2) {
309 auto k = (r.X() > 0) ? 3 : 2;
311 if (isnan(t))
return false;
313 if (r.Z() < prism.
zR) {
314 if (r.Y() > prism.
yUp or r.Y() < prism.
yDown)
return false;
316 if (r.Y() < ySlanted)
return false;
318 double t1 = lengths[i];
320 for (
int iter = 0; iter < 20; iter++) {
323 if (r.Z() < prism.
zR) t1 = t;
334 if (positions[0].Z() < prism.
zL and positions[1].Z() < prism.
zL)
return false;
336 if (positions[0].Z() < prism.
zL or positions[1].Z() < prism.
zL) {
337 int i0 = (positions[0].Z() < prism.
zL) ? 0 : 1;
338 double t1 = lengths[i0];
339 double t2 = lengths[(i0 + 1) % 2];
340 for (
int iter = 0; iter < 20; iter++) {
341 double t = (t1 + t2) / 2;
343 if (r.Z() < prism.
zL) t1 = t;
346 double t = (t1 + t2) / 2;
360 if (not emissionPoint.isSet) {
363 emissionPoint.isSet =
true;
365 return emissionPoint;
372 for (
auto it = range.first; it != range.second; ++it) {
373 const auto hit = it->second;
374 for (
const auto& gaus : tts.getTTS()) {
375 double sigsq = wid + pow(gaus.sigma, 2) + pow(hit->timeErr, 2);
376 double x = pow(hit->time - time - gaus.position, 2) / sigsq;
377 if (x < 10)
return true;
Provides a type-safe way to pass members of the chargedStableSet set.
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
int getPDGCode() const
PDG code.
static const ParticleSet chargedStableSet
set of charged stable particles
EDetector
Enum for identifying the detector components (detector and subdetector).
static const double speedOfLight
[cm/ns]
static const ParticleType invalidParticle
Invalid particle, used internally.
Store one Ext hit as a ROOT object.
int getPdgCode() const
Get PDG code of this extrapolation's hypothesis.
TVector3 getMomentum() const
Get momentum at this extrapolation hit.
int getCopyID() const
Get detector-element ID of sensitive element within detector.
TVector3 getPosition() const
Get position of this extrapolation hit.
double getTOF() const
Get time of flight from the point of closest approach near the origin to this hit.
A Class to store the Monte Carlo particle information.
Class for type safe access to objects that are referred to in relations.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
RelationVector< T > getRelationsWith(const std::string &name="", const std::string &namedRelation="") const
Get the relations between this object and another store array.
Accessor to arrays stored in the data store.
Class to store track parameters of incoming MC particles relation to MCParticle filled in top/simulat...
unsigned getNumModules() const
Returns number of modules.
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
@ c_syncWindows
number of windows corresponding to syncTimeBase
TVector3 getDirection(double length) const
Returns particle direction at given length.
TVector3 getPosition(double length) const
Returns particle position at given length.
void set(const TVector3 &position, const TVector3 &momentum, double charge, double Bz)
Sets the helix.
void moveReferencePosition(double length)
Moves reference position along helix by length.
double getDistanceToPlane(const TVector3 &point, const TVector3 &normal) const
Returns the distance along helix to the nearest intersection with a plane nearly parallel to z axis.
void setTransformation(const TRotation &rotation, const TVector3 &translation)
Sets transformation from the frame in which helix is constructed to module local frame.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
static const YScanner * getYScanner(int moduleID)
Returns y-scanner of a given module.
static const std::vector< BackgroundPDF > & getBackgroundPDFs()
Returns background PDF's of all modules.
bool setHelix(const TRotation &rotation, const TVector3 &translation)
Sets helix (helix is given in nominal frame)
double m_bkgRate
estimated background hit rate
DBObjPtr< TOPFrontEndSetting > m_feSetting
front-end settings
DBObjPtr< TOPCalModuleAlignment > m_alignment
module alignment constants
bool isScanRequired(unsigned col, double time, double wid) const
Checks if scan method of YScanner is needed to construct PDF for a given pixel column.
const TOPTrack::AssumedEmission & getEmissionPoint(double dL=0) const
Returns assumed photon emission position and track direction.
std::unordered_multimap< unsigned, const SelectedHit * > m_columnHits
selected hits mapped to pixel columns
TOPTrack()
Default constructor.
double m_momentum
track momentum magnitude at TOP
std::map< double, TOPTrack::AssumedEmission > m_emissionPoints
assumed emission points in module local frame
bool m_valid
true for properly defined track
double m_pT
transverse momentum at POCA
double m_trackLength
trajectory length from IP to average photon emission point
double m_charge
track charge in units of elementary charge
std::vector< SelectedHit > m_selectedHits
selected photon hits from TOPDigits belonging to this slot ID
const MCParticle * m_mcParticle
MC particle.
bool xsecPrism(std::vector< double > &lengths, std::vector< TVector3 > &positions, const RaytracerBase::Prism &prism, const TRotation &rotation, const TVector3 &translation)
Calculates intersection of trajectory with prism.
TOP::HelixSwimmer m_helix
trajectory helix in nominal slot frame
double m_length
trajectory length within quartz
void set(const Track &track, const std::string &digitsName, const Const::ChargedStable &chargedStable)
Sets the object (called by constructors)
const ExtHit * m_extHit
extrapolated hit
const Track * m_track
mdst track
double getBeta(const Const::ChargedStable &particle, double overrideMass=0) const
Returns particle beta.
double m_TOFLength
trajectory length corresponding to TOF of extrapolated hit
const TOPBarHit * m_barHit
bar hit
Class that bundles various TrackFitResults.
Class to store variables with their name which were sent to the logging service.
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
const TOPNominalTTS & getTTS(unsigned type) const
Returns time transition spread of a given PMT type.
Abstract base class for different kinds of events.
bar segment data in module local frame.
double A
width (dimension in x)
double B
thickness (dimension in y)
spherical mirror data in module local frame.
double yc
center of curvature in y
double xc
center of curvature in x
double zc
center of curvature in z
prism data in module local frame.
double A
width (dimension in x)
double yDown
minimal y of exit window
double slope
slope of slanted surface (dy/dz)
double yUp
maximal y of exit window
double zFlat
z where flat continues to slanted surface
double zR
maximal z, i.e position of prism-bar joint
double B
thickness at bar (dimension in y)
assumed photon emission point in local frame
selected photon hit from TOPDigits
Sine and cosine of track polar and azimuthal angles at assumed photon emission.
TrackAngles()
Default constructor.