8#include <tracking/trackFindingCDC/processing/AxialTrackUtil.h>
10#include <tracking/trackFindingCDC/fitting/CDCRiemannFitter.h>
11#include <tracking/trackFindingCDC/fitting/CDCKarimakiFitter.h>
12#include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
14#include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
15#include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
16#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
17#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
19#include <tracking/trackFindingCDC/utilities/Algorithms.h>
22using namespace TrackFindingCDC;
25 const std::vector<const CDCWireHit*>& allAxialWireHits,
26 std::vector<CDCTrack>& axialTracks,
27 bool withPostprocessing)
29 if (foundAxialWireHits.empty())
return;
40 for (
const CDCWireHit* wireHit : foundAxialWireHits) {
44 track.push_back(std::move(recoHit3D));
48 track.sortByArcLength2D();
51 bool success = withPostprocessing ?
postprocessTrack(track, allAxialWireHits) :
true;
55 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
true);
57 axialTracks.emplace_back(std::move(track));
61 recoHit3D.getWireHit().getAutomatonCell().setMaskedFlag(
true);
62 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
90 return not(track.size() < 5);
96 if (track.size() < 5)
return;
100 observations2D.
append(item);
118 track.sortByArcLength2D();
121 track.setStartTrajectory3D(trajectory3D);
123 Vector3D backPosition = track.back().getRecoPos3D();
125 track.setEndTrajectory3D(trajectory3D);
133 double arcLength2D = hit.getArcLength2D();
137 hit.setArcLength2D(arcLength2D);
142 const CDCTrajectory2D& trajectory2D = track.getStartTrajectory3D().getTrajectory2D();
143 auto farFromTrajectory = [&trajectory2D, &maximumDistance](
CDCRecoHit3D & recoHit3D) {
144 Vector2D refPos2D = recoHit3D.getRefPos2D();
145 double distance = trajectory2D.
getDist2D(refPos2D) - recoHit3D.getSignedRecoDriftLength();
146 if (std::fabs(distance) > maximumDistance) {
147 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
149 recoHit3D.getWireHit().getAutomatonCell().setMaskedFlag(
true);
154 erase_remove_if(track, farFromTrajectory);
158 double minimal_probability_for_good_fit)
161 const auto lowPValue = [&](
const CDCTrack & track) {
165 if (not(fittedTrajectory.
getPValue() >= minimal_probability_for_good_fit)) {
167 track.forwardTakenFlag(
false);
172 erase_remove_if(axialTracks, lowPValue);
176 const std::vector<const CDCWireHit*>& allAxialWireHits,
177 double minimalDistance)
179 if (track.size() < 10)
return;
181 const CDCTrajectory2D& trackTrajectory2D = track.getStartTrajectory3D().getTrajectory2D();
183 for (
const CDCWireHit* wireHit : allAxialWireHits) {
184 if (wireHit->getAutomatonCell().hasTakenFlag())
continue;
189 if (fabs(trackTrajectory2D.
getDist2D(recoPos2D)) < minimalDistance) {
190 track.push_back(std::move(recoHit3D));
198 const auto isShort = [&](
const CDCTrack & track) {
199 if (track.size() < minimal_size) {
201 track.forwardTakenFlag(
false);
206 erase_remove_if(axialTracks, isShort);
211 std::vector<CDCRecoHit3D> removedHits;
213 if (track.size() < 5)
return removedHits;
216 Vector2D center = track.getStartTrajectory3D().getGlobalCenter();
219 auto isOnMajorArm = [¢er, &majorArmSign](
const CDCRecoHit3D & hit) {
220 return getArmSign(hit, center) == majorArmSign;
223 auto itFirstMinorArmHit = std::stable_partition(track.begin(),
227 for (
const CDCRecoHit3D& recoHit3D : asRange(itFirstMinorArmHit, track.end())) {
228 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
229 removedHits.push_back(recoHit3D);
231 track.erase(itFirstMinorArmHit, track.end());
238 Vector2D center = track.getStartTrajectory3D().getGlobalCenter();
240 if (std::abs(armSignVote) <
int(track.size()) and std::fabs(center.
cylindricalR()) > 60.) {
249 if (armSignVote > 0) {
250 return ESign::c_Plus;
252 return ESign::c_Minus;
262 B2WARNING(
"Trajectory is not set or wrong!");
269 if (armSign == ESign::c_Plus) {
271 }
else if (armSign == ESign::c_Minus) {
274 B2ERROR(
"Strange behaviour of getArmSignVote");
277 int armSignVote = votePos - voteNeg;
288 double apogeeArcLength = fabs(track.getStartTrajectory3D().getGlobalCircle().perimeter()) / 2.;
290 std::array<int, ISuperLayerUtil::c_N> nForwardArmHitsBySLayer = {0};
291 std::array<int, ISuperLayerUtil::c_N> nBackwardArmHitsBySLayer = {0};
295 if ((hit.getArcLength2D() <= apogeeArcLength) and (hit.getArcLength2D() > 0)) {
296 nForwardArmHitsBySLayer[hit.getISuperLayer()]++;
298 nBackwardArmHitsBySLayer[hit.getISuperLayer()]++;
302 std::vector<ISuperLayer> forwardSLayerHoles =
getSLayerHoles(nForwardArmHitsBySLayer);
303 std::vector<ISuperLayer> backwardSLayerHoles =
getSLayerHoles(nBackwardArmHitsBySLayer);
306 if (forwardSLayerHoles.empty() and backwardSLayerHoles.empty())
return;
310 assert(std::is_sorted(forwardSLayerHoles.begin(), forwardSLayerHoles.end()));
311 if (forwardSLayerHoles.empty())
return;
313 const ISuperLayer breakSLayer = forwardSLayerHoles.front();
315 auto isInBackwardArm = [apogeeArcLength](
const CDCRecoHit3D & recoHit3D) {
316 if ((recoHit3D.getArcLength2D() >= apogeeArcLength) or (recoHit3D.getArcLength2D() < 0)) {
317 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
323 erase_remove_if(track, isInBackwardArm);
325 auto isAfterSLayerBreak = [breakSLayer](
const CDCRecoHit3D & recoHit3D) {
326 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
327 if (recoHit3D.getISuperLayer() >= breakSLayer) {
328 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
334 erase_remove_if(track, isAfterSLayerBreak);
339 std::vector<ISuperLayer> sLayerHoles;
349 for (ISuperLayer iSLayer = firstSlayer; iSLayer <= lastSlayer; iSLayer += 2) {
350 if (nHitsBySLayer[iSLayer] == 0) {
351 sLayerHoles.push_back(iSLayer);
360 if (nHitsBySLayer[iSLayer] > 0)
return iSLayer;
368 if (nHitsBySLayer[iSLayer] > 0)
return iSLayer;
Cell used by the cellular automata.
void setTakenFlag(bool setTo=true)
Sets the taken flag to the given value. Default value true.
bool hasTakenFlag() const
Gets the current state of the taken marker flag.
CDCTrajectory2D fit(const CDCObservations2D &observations2D) const
Fits a collection of observation drift circles.
Class implementing the fitter using Karimakis method.
static const CDCKarimakiFitter & getNoDriftVarianceFitter()
Static getter for a general fitter that does not use the drift length variances.
Class serving as a storage of observed drift circles to present to the Riemann fitter.
std::size_t append(const CDCWireHit &wireHit, ERightLeft rlInfo=ERightLeft::c_Unknown)
Appends the hit circle at wire reference position without a right left passage hypotheses.
Class representing a three dimensional reconstructed hit.
const CDCWireHit & getWireHit() const
Getter for the wire hit.
const Vector2D & getRecoPos2D() const
Getter for the 2d position of the hit.
static CDCRecoHit3D reconstructNearest(const CDCWireHit *axialWireHit, const CDCTrajectory2D &trajectory2D)
Reconstruct a three dimensional hit from a wire hit (as in reconstruct(rlWireHit, trajectory2D)),...
Class implementing the Riemann fit for two dimensional trajectory circle.
static const CDCRiemannFitter & getFitter()
Static getter for a general Riemann fitter.
Class representing a sequence of three dimensional reconstructed hits.
Particle trajectory as it is seen in xy projection represented as a circle.
void reverse()
Reverses the trajectory in place.
double setLocalOrigin(const Vector2D &localOrigin)
Setter for the origin of the local coordinate system.
ESign getChargeSign() const
Gets the charge sign of the trajectory.
double getPValue() const
Getter for p-value.
double getArcLength2DPeriod() const
Getter for the arc length for one round trip around the trajectory.
Vector2D getGlobalCenter() const
Getter for the center of the trajectory in global coordinates.
Vector2D getGlobalPerigee() const
Getter for the closest approach on the trajectory to the global origin.
double getDist2D(const Vector2D &point) const
Calculates the distance from the point to the trajectory as seen from the xy projection.
Particle full three dimensional trajectory.
double setLocalOrigin(const Vector3D &localOrigin)
Setter for the origin of the local coordinate system.
static CDCTrajectorySZ basicAssumption()
Constructs a basic assumption, what the z0 start position and the sz slope are, including some broad ...
Class representing a hit wire in the central drift chamber.
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
double cylindricalR() const
Gives the cylindrical radius of the vector. Same as norm()
ERightLeft isRightOrLeftOf(const Vector2D &rhs) const
Indicates if the given vector is more left or more right if you looked in the direction of this vecto...
bool hasNAN() const
Checks if one of the coordinates is NAN.
A three dimensional vector.
ESign
Enumeration for the distinct sign values of floating point variables.
Abstract base class for different kinds of events.
static void deleteShortTracks(std::vector< CDCTrack > &axialTracks, double minimal_size=5)
Remove tracks that are shorter than the given number of hits.
static void assignNewHitsToTrack(CDCTrack &track, const std::vector< const CDCWireHit * > &allAxialWireHits, double minimalDistance=0.2)
Assign new hits to the track basing on the distance from the hit to the track.
static void normalizeTrack(CDCTrack &track)
Refit and resort the track. Unmask all hits.
static ESign getArmSign(const CDCRecoHit3D &hit, const Vector2D ¢er)
Calculate whether the hits is to the right or to the left relative to the line from origin to the giv...
static std::vector< ISuperLayer > getSLayerHoles(const std::array< int, ISuperLayerUtil::c_N > &nHitsBySLayer)
Helper function getting the empty axial! super layers that appear in the chain of super layers that i...
static bool checkTrackQuality(const CDCTrack &track)
Check track quality – currently based on number of hits only.
static void updateRecoHit3D(const CDCTrajectory2D &trajectory2D, CDCRecoHit3D &hit)
update given CDCRecoHit3D with given trajectory
static void removeHitsAfterSuperLayerBreak(CDCTrack &track)
Searches for a break in the super layer chain and remove all hits that come after that.
static void addCandidateFromHits(const std::vector< const CDCWireHit * > &foundAxialWireHits, const std::vector< const CDCWireHit * > &allAxialWireHits, std::vector< CDCTrack > &axialTracks, bool withPostprocessing=true)
Create CDCTrack using CDCWireHit hits and store it in the list. Then call the postprocessing on it.
static void deleteHitsFarAwayFromTrajectory(CDCTrack &track, double maximumDistance=0.2)
Postprocessing: Delete axial hits that do not "match" to the given track.
static int getArmSignVote(const CDCTrack &track, const Vector2D ¢er)
Calculate the sum of right and left votes for the hits relative to the center.
static ISuperLayer getFirstOccupiedISuperLayer(const std::array< int, ISuperLayerUtil::c_N > &nHitsBySLayer)
Helper function to extract the first filled entry in the array of super layers ( = the start superlay...
static bool isBack2BackTrack(CDCTrack &track)
Checks whether the track has hits on both arms as seen from the origin.
static bool postprocessTrack(CDCTrack &track, const std::vector< const CDCWireHit * > &allAxialWireHits)
Perform all track postprocessing - return whether the track is considered good after the postprocessi...
static ISuperLayer getLastOccupiedISuperLayer(const std::array< int, ISuperLayerUtil::c_N > &nHitsBySLayer)
Helper function to extract the last filled entry in the array of super layers ( = the final superlaye...
static std::vector< CDCRecoHit3D > splitBack2BackTrack(CDCTrack &track)
Tries to split back-to-back tracks into two different tracks.
static ESign getMajorArmSign(const CDCTrack &track, const Vector2D ¢er)
Calculate whether the majority of hits is to the right or to the left relative to the line from origi...
static void deleteTracksWithLowFitProbability(std::vector< CDCTrack > &axialTracks, double minimal_probability_for_good_fit=0.4)
Check an (improper) p-values of the tracks. If they are below the given value, delete the track from ...
static const ISuperLayer c_Invalid
Constant making an invalid superlayer id.
static const ISuperLayer c_N
Constant representing the total number of cdc superlayers.
static bool isInvalid(ISuperLayer iSuperLayer)
Indicates if the given number corresponds to a true cdc superlayer - excludes the logic ids for inner...