11 #include <tracking/trackFindingCDC/sim/CDCSimpleSimulation.h>
13 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
15 #include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit3D.h>
16 #include <tracking/trackFindingCDC/eventdata/hits/CDCRLWireHit.h>
17 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
19 #include <tracking/trackFindingCDC/topology/CDCWire.h>
20 #include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
21 #include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
23 #include <tracking/trackFindingCDC/utilities/VectorRange.h>
25 #include <framework/gearbox/Const.h>
26 #include <framework/logging/Logger.h>
33 using namespace TrackFindingCDC;
46 return std::move(
simulate(std::vector<CDCTrajectory3D>(1, trajectory3D)).front());
52 std::vector<SimpleSimHit> simpleSimHits;
53 const size_t nMCTracks = trajectories3D.size();
55 for (
size_t iMCTrack = 0; iMCTrack < nMCTracks; ++iMCTrack) {
61 Helix globalHelix = localHelix;
62 const double arcLength2DOffset = globalHelix.
passiveMoveBy(-localOrigin);
63 std::vector<SimpleSimHit> simpleSimHitsForTrajectory =
createHits(globalHelix, arcLength2DOffset);
65 for (
SimpleSimHit& simpleSimHit : simpleSimHitsForTrajectory) {
66 simpleSimHit.m_iMCTrack = iMCTrack;
67 simpleSimHits.push_back(simpleSimHit);
71 std::vector<CDCTrack> mcTracks =
constructMCTracks(nMCTracks, std::move(simpleSimHits));
74 for (
size_t iMCTrack = 0; iMCTrack < nMCTracks; ++iMCTrack) {
75 CDCTrack& mcTrack = mcTracks[iMCTrack];
77 if (not mcTrack.empty()) {
95 std::stable_sort(simpleSimHits.begin(), simpleSimHits.end(),
97 return lhs.m_wireHit < rhs.m_wireHit;
102 const CDCWire* lastWire =
nullptr;
103 size_t nSameWire = 0;
106 auto exceedsMaxNHitOnWire =
107 [&lastWire, &nSameWire, maxNHitOnWire](
const SimpleSimHit & simpleSimHit) ->
bool {
109 if (&(simpleSimHit.m_wireHit.getWire()) == lastWire)
114 lastWire = &(simpleSimHit.m_wireHit.getWire());
116 return nSameWire > maxNHitOnWire ? true :
false;
119 auto itLast = std::remove_if(simpleSimHits.begin(), simpleSimHits.end(), exceedsMaxNHitOnWire);
120 simpleSimHits.erase(itLast, simpleSimHits.end());
125 std::vector<CDCWireHit> wireHits;
126 wireHits.reserve(simpleSimHits.size());
128 wireHits.push_back(simpleSimHit.m_wireHit);
131 B2ASSERT(
"WireHits should be sorted as a result from sorting the SimpleSimHits. "
132 "Algorithms may relay on the sorting o the WireHits",
133 std::is_sorted(wireHits.begin(), wireHits.end()));
135 m_sharedWireHits.reset(
new const std::vector<CDCWireHit>(std::move(wireHits)));
141 std::vector<CDCTrack> mcTracks;
142 mcTracks.resize(nMCTracks);
144 const size_t nWireHits = wireHits.
size();
146 for (
size_t iWireHit = 0; iWireHit < nWireHits; ++iWireHit) {
147 const CDCWireHit& wireHit = wireHits[iWireHit];
148 const SimpleSimHit& simpleSimHit = simpleSimHits[iWireHit];
154 mcTrack.push_back(recoHit3D);
158 for (
CDCTrack& mcTrack : mcTracks) {
167 std::vector<CDCSimpleSimulation::SimpleSimHit>
169 double arcLength2DOffset)
const
172 std::vector<SimpleSimHit> simpleSimHits;
181 const double localArcLength2DToOuterWall = arcLength2DOffset + globalArcLength2DToOuterWall;
183 if (localArcLength2DToOuterWall < 0) {
186 B2WARNING(
"Simple simulation got trajectory outside CDC that moves away from the detector.");
187 return simpleSimHits;
193 const bool isCurler = std::isnan(localArcLength2DToOuterWall);
194 const double perimeterXY = globalHelix.
perimeterXY();
195 const double maxArcLength2D = isCurler ? fabs(perimeterXY) : localArcLength2DToOuterWall;
198 B2INFO(
"Simulating curler");
202 double outerR = wireLayer.getOuterCylindricalR();
203 double innerR = wireLayer.getInnerCylindricalR();
205 if ((maxR < innerR) or (outerR < minR)) {
210 double centerR = (std::min(outerR, maxR) + std::max(innerR, minR)) / 2;
213 double localArcLength2D = arcLength2DOffset + globalArcLength2D;
216 std::vector<SimpleSimHit> simpleSimHitsInLayer;
217 if (localArcLength2D > 0 and localArcLength2D < maxArcLength2D) {
220 const CDCWire& closestWire = wireLayer.getClosestWire(pos3DAtLayer);
222 simpleSimHitsInLayer =
createHitsForLayer(closestWire, globalHelix, arcLength2DOffset);
224 for (
SimpleSimHit& simpleSimHit : simpleSimHitsInLayer) {
225 if (simpleSimHit.m_arcLength2D < maxArcLength2D) {
226 simpleSimHits.push_back(simpleSimHit);
230 B2INFO(
"Arc length to long");
233 bool oneSegment = outerR > maxR or innerR < minR;
234 if (not oneSegment) {
237 double secondGlobalArcLength2D = -globalArcLength2D;
238 double secondArcLength2DOffset = arcLength2DOffset;
239 double secondLocalArcLength2D = secondArcLength2DOffset + secondGlobalArcLength2D;
241 if (isCurler and secondLocalArcLength2D < 0) {
242 secondLocalArcLength2D += perimeterXY;
243 secondArcLength2DOffset += perimeterXY;
244 secondGlobalArcLength2D += perimeterXY;
247 if (secondLocalArcLength2D > 0 and secondLocalArcLength2D < maxArcLength2D) {
249 const CDCWire& closestWire = wireLayer.getClosestWire(pos3DAtLayer);
252 bool wireAlreadyHit =
false;
253 for (
const SimpleSimHit& simpleSimHit : simpleSimHits) {
254 if (simpleSimHit.m_wireHit.isOnWire(closestWire)) {
255 wireAlreadyHit =
true;
258 if (not wireAlreadyHit) {
259 std::vector<SimpleSimHit> secondSimpleSimHitsInLayer =
262 for (
SimpleSimHit& simpleSimHit : secondSimpleSimHitsInLayer) {
263 if (simpleSimHit.m_arcLength2D < maxArcLength2D) {
264 simpleSimHits.push_back(simpleSimHit);
272 return simpleSimHits;
275 std::vector<CDCSimpleSimulation::SimpleSimHit>
277 const Helix& globalHelix,
278 double arcLength2DOffset)
const
280 std::vector<SimpleSimHit> result;
284 result.push_back(simpleSimHit);
295 result.push_back(simpleSimHitForWire);
307 result.push_back(simpleSimHitForWire);
317 const Helix& globalHelix,
318 double arcLength2DOffset)
const
321 if ((arcLength2D + arcLength2DOffset) < 0) {
329 double correctedArcLength2D = arcLength2D;
331 for (
int c_Iter = 0; c_Iter < 2; c_Iter++) {
336 if ((correctedArcLength2D + arcLength2DOffset) < 0) {
339 correctedPos3D = globalHelix.
atArcLength2D(correctedArcLength2D);
342 const double trueDriftLength = wire.
getDriftLength(correctedPos3D);
343 const double smearedDriftLength = trueDriftLength + gRandom->Gaus(0,
m_driftLengthSigma);
347 double arcLength3D = hypot2(1, globalHelix.
tanLambda()) * (correctedArcLength2D + arcLength2DOffset);
355 double distanceToBack = (wirePos.
z() - backwardZ) * hypot2(1, wire.
getTanStereoAngle());
360 double measuredDriftLength = smearedDriftLength + delayTime *
m_driftSpeed;
377 correctedArcLength2D,
383 std::vector<CDCTrack>
386 const size_t nMCTracks = 2;
387 std::vector<SimpleSimHit> simpleSimHits;
388 simpleSimHits.reserve(128 + 64);
612 std::vector<CDCTrack> mcTracks =
constructMCTracks(nMCTracks, std::move(simpleSimHits));