86 std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>>
caloTSOS;
89 std::unique_ptr<Trk::TrackStateOnSurface> innerTS, middleTS, outerTS;
90 std::unique_ptr<const Trk::TrackParameters> inParams, midParams;
107 bool trackOutwards =
true;
109 if (parameters.associatedSurface().center().perp() > 0.5 * Gaudi::Units::meter) trackOutwards =
false;
110 }
else if (std::abs(parameters.position().z()) > 4.0 * Gaudi::Units::meter ||
111 parameters.position().perp() > 1.2 * Gaudi::Units::meter) {
112 trackOutwards =
false;
119 innerParams = innerTS->trackParameters();
122 middleParams = midParams.get();
128 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *midParams, innerParams, outerParams);
129 if (!middleTS) { middleParams =
nullptr; }
135 std::unique_ptr<const Trk::TrackParameters> params;
136 for (
int iterate = 0; iterate != 2; ++iterate) {
137 if (!middleTS)
break;
142 middleParams = middleTS->trackParameters();
144 double correctedEnergy = innerParams->
momentum().mag() - energyDeposit;
149 ATH_MSG_VERBOSE(
" fail tracking outwards: momentum " << momentum.mag() / Gaudi::Units::GeV
150 <<
" energyDeposit " << energyDeposit / Gaudi::Units::GeV
151 <<
" correctedEnergy "
152 << correctedEnergy / Gaudi::Units::GeV <<
" (GeV units)");
159 momentum *= correctedEnergy / momentum.mag();
166 std::make_unique<Trk::AtaCylinder>(middleParams->
position(), momentum, middleParams->
charge(), *cylinder);
170 params = std::make_unique<Trk::AtaDisc>(middleParams->
position(), momentum, middleParams->
charge(), *disc);
181 middleTS =
m_caloEnergyDeposit->trackStateOnSurface(ctx, *params, innerParams, outerParams);
183 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *params, innerParams, outerParams);
186 if (middleTS) { outerTS =
outerTSOS(ctx, *params); }
188 if (!middleTS) {
ATH_MSG_VERBOSE(
" fail tracking outwards: no intersect at middle surface"); }
191 ATH_MSG_VERBOSE(
" fail tracking ouwards: no intersect at inner surface");
197 outerParams = outerTS->trackParameters();
199 middleParams = midParams.get();
202 innerParams = inParams.get();
206 middleTS =
m_caloEnergyDeposit->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
208 middleTS =
m_caloEnergyParam->trackStateOnSurface(ctx, *middleParams, inParams.get(), outerParams);
215 double correctedEnergy = momentum.mag() + energyDeposit;
218 if (correctedEnergy < 0.5 * Gaudi::Units::GeV) {
220 ATH_MSG_VERBOSE(
" fail tracking inwards: momentum " << momentum.mag() / Gaudi::Units::GeV <<
" energyDeposit "
221 << energyDeposit / Gaudi::Units::GeV
222 <<
" correctedEnergy "
223 << correctedEnergy / Gaudi::Units::GeV <<
" (GeV units)");
225 momentum *= 1. + energyDeposit / momentum.mag();
226 std::unique_ptr<const Trk::TrackParameters> params;
230 middleParams->covariance() ? std::optional<AmgSymMatrix(5)>(*middleParams->covariance()) : std::nullopt;
232 params = std::make_unique<Trk::AtaCylinder>(middleParams->
position(), momentum, middleParams->
charge(),
237 params = std::make_unique<Trk::AtaDisc>(middleParams->
position(), momentum, middleParams->
charge(),
243 if (params && middleTS) { innerTS =
innerTSOS(ctx, *params); }
246 ATH_MSG_VERBOSE(
" fail tracking inwards: no intersect at inner surface");
249 ATH_MSG_VERBOSE(
" fail tracking inwards: no intersect at middle surface");
255 caloTSOS.push_back(std::move(innerTS));
258 if (middleTS)
caloTSOS.push_back(std::move(middleTS));
260 caloTSOS.push_back(std::move(outerTS));
325 double startingPhi = 0.;
328 startingPhi = parameters.momentum().phi();
331 startingPhi = parameters.position().phi();
333 if (parameters.momentum().dot(parameters.position()) < 0.) {
338 if (!surface)
return nullptr;
341 unsigned extrapolations = 0;
344 propDirection = momentumDirection;
346 propDirection = oppositeDirection;
350 std::unique_ptr<const Trk::TrackParameters> extrapolation{
352 if (!extrapolation)
return nullptr;
356 if (std::abs(
deltaPhi) > M_PI_2) {
return nullptr; }
360 double signRZ = (extrapolation->position().
perp() - parameters.position().perp()) *
361 (extrapolation->position().
z() - parameters.position().z());
362 if (signRZ * extrapolation->position().z() < 0.) {
369 bool restart =
false;
375 std::unique_ptr<const Trk::Surface> reset_surface;
376 while (++extrapolations < 5 && extrapolatedSurface != oldSurface) {
380 propDirection = momentumDirection;
382 propDirection = oppositeDirection;
387 std::unique_ptr<const Trk::TrackParameters> oldParameters = std::move(extrapolation);
390 if (!extrapolation) {
393 if ((*oldParameters) == parameters) {
398 ATH_MSG_DEBUG(surf_layer_str <<
" Parameters: oscillating => arbitrary solution chosen");
400 extrapolation = std::move(oldParameters);
401 reset_surface.reset(extrapolation->associatedSurface().clone());
402 extrapolatedSurface = reset_surface.get();
403 surface = extrapolatedSurface;
406 ATH_MSG_VERBOSE(surf_layer_str <<
" Parameters: restart extrap after " << extrapolations <<
" extrapolations");
409 extrapolation = parameters.uniqueClone();
410 surface = oldSurface;
414 ATH_MSG_DEBUG(surf_layer_str <<
" Parameters: Extrapolation succeeded go to next iteration");
415 oldSurface = surface;
416 surface = extrapolatedSurface;
417 extrapolatedSurface =
getCaloSurface(extrapolation->position().eta(), layer);
423 if (std::abs(
deltaPhi) > M_PI_2) {
return nullptr; }
425 ATH_MSG_VERBOSE(surf_layer_str <<
" Parameters: success after " << extrapolations <<
" extrapolation step(s). "
426 << std::setiosflags(std::ios::fixed) <<
" Intersection at: r,phi,z " << std::setw(7)
427 << std::setprecision(1) << extrapolation->position().perp() << std::setw(7) << std::setprecision(3)
428 << extrapolation->position().phi() << std::setw(8) << std::setprecision(1)
429 << extrapolation->position().z() <<
" Direction: eta,phi " << std::setw(7) << std::setprecision(3)
430 << extrapolation->momentum().eta() << std::setw(7) << std::setprecision(3)
431 << extrapolation->momentum().phi());
433 return extrapolation;