10 #include <tracking/trackFindingCDC/processing/AxialTrackUtil.h>
12 #include <tracking/trackFindingCDC/fitting/CDCRiemannFitter.h>
13 #include <tracking/trackFindingCDC/fitting/CDCKarimakiFitter.h>
14 #include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
16 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
17 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
18 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
19 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
21 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
24 using namespace TrackFindingCDC;
27 const std::vector<const CDCWireHit*>& allAxialWireHits,
28 std::vector<CDCTrack>& axialTracks,
29 bool withPostprocessing)
31 if (foundAxialWireHits.empty())
return;
42 for (
const CDCWireHit* wireHit : foundAxialWireHits) {
46 track.push_back(std::move(recoHit3D));
50 track.sortByArcLength2D();
53 bool success = withPostprocessing ?
postprocessTrack(track, allAxialWireHits) :
true;
57 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
true);
59 axialTracks.emplace_back(std::move(track));
63 recoHit3D.getWireHit().getAutomatonCell().setMaskedFlag(
true);
64 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
92 return not(track.size() < 5);
98 if (track.size() < 5)
return;
102 observations2D.
append(item);
120 track.sortByArcLength2D();
123 track.setStartTrajectory3D(trajectory3D);
125 Vector3D backPosition = track.back().getRecoPos3D();
127 track.setEndTrajectory3D(trajectory3D);
135 double arcLength2D = hit.getArcLength2D();
139 hit.setArcLength2D(arcLength2D);
144 const CDCTrajectory2D& trajectory2D = track.getStartTrajectory3D().getTrajectory2D();
145 auto farFromTrajectory = [&trajectory2D, &maximumDistance](
CDCRecoHit3D & recoHit3D) {
146 Vector2D refPos2D = recoHit3D.getRefPos2D();
147 double distance = trajectory2D.
getDist2D(refPos2D) - recoHit3D.getSignedRecoDriftLength();
148 if (std::fabs(distance) > maximumDistance) {
149 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
151 recoHit3D.getWireHit().getAutomatonCell().setMaskedFlag(
true);
156 erase_remove_if(track, farFromTrajectory);
160 double minimal_probability_for_good_fit)
163 const auto lowPValue = [&](
const CDCTrack & track) {
167 if (not(fittedTrajectory.
getPValue() >= minimal_probability_for_good_fit)) {
169 track.forwardTakenFlag(
false);
174 erase_remove_if(axialTracks, lowPValue);
178 const std::vector<const CDCWireHit*>& allAxialWireHits,
179 double minimalDistance)
181 if (track.size() < 10)
return;
183 const CDCTrajectory2D& trackTrajectory2D = track.getStartTrajectory3D().getTrajectory2D();
185 for (
const CDCWireHit* wireHit : allAxialWireHits) {
186 if (wireHit->getAutomatonCell().hasTakenFlag())
continue;
191 if (fabs(trackTrajectory2D.
getDist2D(recoPos2D)) < minimalDistance) {
192 track.push_back(std::move(recoHit3D));
200 const auto isShort = [&](
const CDCTrack & track) {
201 if (track.size() < minimal_size) {
203 track.forwardTakenFlag(
false);
208 erase_remove_if(axialTracks, isShort);
213 std::vector<CDCRecoHit3D> removedHits;
215 if (track.size() < 5)
return removedHits;
218 Vector2D center = track.getStartTrajectory3D().getGlobalCenter();
221 auto isOnMajorArm = [¢er, &majorArmSign](
const CDCRecoHit3D & hit) {
222 return getArmSign(hit, center) == majorArmSign;
225 auto itFirstMinorArmHit = std::stable_partition(track.begin(),
229 for (
const CDCRecoHit3D& recoHit3D : asRange(itFirstMinorArmHit, track.end())) {
230 recoHit3D.getWireHit().getAutomatonCell().setTakenFlag(
false);
231 removedHits.push_back(recoHit3D);
233 track.erase(itFirstMinorArmHit, track.end());
240 Vector2D center = track.getStartTrajectory3D().getGlobalCenter();
242 if (std::abs(armSignVote) <
int(track.size()) and std::fabs(center.
cylindricalR()) > 60.) {
251 if (armSignVote > 0) {
252 return ESign::c_Plus;
254 return ESign::c_Minus;
264 B2WARNING(
"Trajectory is not setted or wrong!");
271 if (armSign == ESign::c_Plus) {
273 }
else if (armSign == ESign::c_Minus) {
276 B2ERROR(
"Strange behaviour of getArmSignVote");
279 int armSignVote = votePos - voteNeg;
290 double apogeeArcLength = fabs(track.getStartTrajectory3D().getGlobalCircle().perimeter()) / 2.;
292 std::array<int, ISuperLayerUtil::c_N> nForwardArmHitsBySLayer = {0};
293 std::array<int, ISuperLayerUtil::c_N> nBackwardArmHitsBySLayer = {0};
297 if ((hit.getArcLength2D() <= apogeeArcLength) and (hit.getArcLength2D() > 0)) {
298 nForwardArmHitsBySLayer[hit.getISuperLayer()]++;
300 nBackwardArmHitsBySLayer[hit.getISuperLayer()]++;
304 std::vector<ISuperLayer> forwardSLayerHoles =
getSLayerHoles(nForwardArmHitsBySLayer);
305 std::vector<ISuperLayer> backwardSLayerHoles =
getSLayerHoles(nBackwardArmHitsBySLayer);
308 if (forwardSLayerHoles.empty() and backwardSLayerHoles.empty())
return;
312 assert(std::is_sorted(forwardSLayerHoles.begin(), forwardSLayerHoles.end()));
313 if (forwardSLayerHoles.empty())
return;
315 const ISuperLayer breakSLayer = forwardSLayerHoles.front();
317 auto isInBackwardArm = [apogeeArcLength](
const CDCRecoHit3D & recoHit3D) {
318 if ((recoHit3D.getArcLength2D() >= apogeeArcLength) or (recoHit3D.getArcLength2D() < 0)) {
319 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
325 erase_remove_if(track, isInBackwardArm);
327 auto isAfterSLayerBreak = [breakSLayer](
const CDCRecoHit3D & recoHit3D) {
328 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
329 if (recoHit3D.getISuperLayer() >= breakSLayer) {
330 recoHit3D.getWireHit().getAutomatonCell().unsetTakenFlag();
336 erase_remove_if(track, isAfterSLayerBreak);
341 std::vector<ISuperLayer> sLayerHoles;
351 for (ISuperLayer iSLayer = firstSlayer; iSLayer <= lastSlayer; iSLayer += 2) {
352 if (nHitsBySLayer[iSLayer] == 0) {
353 sLayerHoles.push_back(iSLayer);
362 if (nHitsBySLayer[iSLayer] > 0)
return iSLayer;
370 if (nHitsBySLayer[iSLayer] > 0)
return iSLayer;