ATLAS Offline Software
Loading...
Searching...
No Matches
Trk::MaterialAllocator Class Reference

Main Fitter tool providing the implementation for the different fitting, extension and refitting use cases. More...

#include <MaterialAllocator.h>

Inheritance diagram for Trk::MaterialAllocator:
Collaboration diagram for Trk::MaterialAllocator:

Classes

class  compareByDistance

Public Types

typedef std::vector< std::unique_ptr< const TrackStateOnSurface > > Garbage_t

Public Member Functions

 MaterialAllocator (const std::string &type, const std::string &name, const IInterface *parent)
virtual ~MaterialAllocator ()=default
virtual StatusCode initialize () override
virtual StatusCode finalize () override
virtual void addLeadingMaterial (std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, Garbage_t &garbage) const override
 IMaterialAllocator interface: add leading material effects to fit measurements and parameters.
virtual void allocateMaterial (std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, const TrackParameters &startParameters, Garbage_t &garbage) const override
 IMaterialAllocator interface: allocate material.
virtual void initializeScattering (std::vector< FitMeasurement * > &measurements) const override
 IMaterialAllocator interface: initialize scattering (needs to know X0 integral)
virtual std::vector< const TrackStateOnSurface * > * leadingSpectrometerTSOS (const TrackParameters &spectrometerParameters, Garbage_t &garbage) const override
 IMaterialAllocator interface: material TSOS between spectrometer entrance surface and parameters given in spectrometer.
virtual void orderMeasurements (std::vector< FitMeasurement * > &measurements, Amg::Vector3D startDirection, Amg::Vector3D startPosition) const override
 IMaterialAllocator interface: clear temporary TSOS.
virtual bool reallocateMaterial (std::vector< FitMeasurement * > &measurements, FitParameters &fitParameters, Garbage_t &garbage) const override
 IMaterialAllocator interface: has material been reallocated?
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const InterfaceID & interfaceID ()
 AlgTool and IAlgTool interface methods.

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

void addSpectrometerDelimiters (std::vector< FitMeasurement * > &measurements) const
const std::vector< const TrackStateOnSurface * > * extrapolatedMaterial (const ToolHandle< IExtrapolator > &extrapolator, const TrackParameters &parameters, const Surface &surface, PropDirection dir, const BoundaryCheck &boundsCheck, ParticleHypothesis particleHypothesis, Garbage_t &garbage) const
void indetMaterial (std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, const TrackParameters &startParameters, Garbage_t &garbage) const
std::pair< FitMeasurement *, FitMeasurement * > materialAggregation (const std::vector< const TrackStateOnSurface * > &material, std::vector< FitMeasurement * > &measurements, double particleMass) const
void materialAggregation (std::vector< FitMeasurement * > &measurements, double particleMass) const
void printMeasurements (std::vector< FitMeasurement * > &measurements) const
void spectrometerMaterial (std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, const TrackParameters &startParameters, Garbage_t &garbage) const
const Trk::TrackingVolumegetSpectrometerEntrance () const
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Static Private Member Functions

static void deleteMaterial (const std::vector< const TrackStateOnSurface * > *material, Garbage_t &garbage)
static FitMeasurementmeasurementFromTSOS (const TrackStateOnSurface &tsos, double outwardsEnergy, double particleMass)

Private Attributes

ToolHandle< IExtrapolatorm_extrapolator
ToolHandle< IIntersectorm_intersector
ServiceHandle< ITrackingGeometrySvcm_trackingGeometrySvc
ServiceHandle< ITrackingVolumesSvcm_trackingVolumesSvc
ToolHandle< IPropagatorm_stepPropagator
SG::ReadCondHandleKey< TrackingGeometrym_trackingGeometryReadKey
bool m_aggregateMaterial
bool m_allowReordering
int m_useStepPropagator
unsigned m_maxWarnings
double m_orderingTolerance
double m_scattererMinGap
double m_scatteringConstant
double m_scatteringLogCoeff
double m_sectorMaxPhi
double m_stationMaxGap
const Trk::Volumem_calorimeterVolume
const Trk::Volumem_indetVolume
Trk::MagneticFieldProperties m_stepField
std::unique_ptr< MessageHelperm_messageHelper
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default)
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default)
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Main Fitter tool providing the implementation for the different fitting, extension and refitting use cases.

Definition at line 50 of file MaterialAllocator.h.

Member Typedef Documentation

◆ Garbage_t

typedef std::vector<std::unique_ptr<const TrackStateOnSurface> > Trk::IMaterialAllocator::Garbage_t
inherited

Definition at line 40 of file IMaterialAllocator.h.

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ MaterialAllocator()

Trk::MaterialAllocator::MaterialAllocator ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 35 of file MaterialAllocator.cxx.

38 : AthAlgTool(type, name, parent),
40 m_allowReordering(false),
42 m_maxWarnings(10),
43 m_orderingTolerance(1. * Gaudi::Units::mm),
44 m_scattererMinGap(100. * Gaudi::Units::mm),
46 Gaudi::Units::MeV), // Coulomb scattering constant
47 m_scatteringLogCoeff(0.038), // Coulomb scattering constant
48 m_sectorMaxPhi(0.28),
49 m_stationMaxGap(0.6 * Gaudi::Units::meter),
50 m_calorimeterVolume(nullptr),
51 m_indetVolume(nullptr),
52 m_messageHelper(nullptr) {
53 m_messageHelper = std::make_unique<MessageHelper>(*this, 6);
54 declareInterface<IMaterialAllocator>(this);
55
56 declareProperty("AggregateMaterial", m_aggregateMaterial);
57 declareProperty("AllowReordering", m_allowReordering);
58
59 // m_useStepPropagator 0 means not used (so Intersector used)
60 // 1 Intersector not used and StepPropagator used with FullField
61 // 2 StepPropagator with FastField propagation
62 // 99 debug mode where both are ran with FullField
63
64 declareProperty("UseStepPropagator", m_useStepPropagator);
65 declareProperty("OrderingTolerance", m_orderingTolerance);
67 "MaxNumberOfWarnings", m_maxWarnings,
68 "Maximum number of permitted WARNING messages per message type.");
69}
AthAlgTool()
Default constructor:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const Trk::Volume * m_calorimeterVolume
const Trk::Volume * m_indetVolume
std::unique_ptr< MessageHelper > m_messageHelper

◆ ~MaterialAllocator()

virtual Trk::MaterialAllocator::~MaterialAllocator ( )
virtualdefault

Member Function Documentation

◆ addLeadingMaterial()

void Trk::MaterialAllocator::addLeadingMaterial ( std::vector< FitMeasurement * > & measurements,
ParticleHypothesis particleHypothesis,
FitParameters & fitParameters,
Garbage_t & garbage ) const
overridevirtual

IMaterialAllocator interface: add leading material effects to fit measurements and parameters.

Implements Trk::IMaterialAllocator.

Definition at line 130 of file MaterialAllocator.cxx.

133 {
134 const EventContext& ctx = Gaudi::Hive::currentContext();
135 // nothing to do if starting with vertex measurement
136 if (measurements.front()->isVertex()) {
137 return;
138 }
139
140 if (msgLvl(MSG::DEBUG)) {
141 ATH_MSG_DEBUG(" start of addLeadingMaterial: ");
142 printMeasurements(measurements);
143 }
144
145 // fitted momentum at perigee - ignoring leading material effects
146 double charge = 1.;
147 double qOverP = fitParameters.qOverP();
148 double p = 1. / qOverP;
149 if (p < 0.) {
150 charge = -1.;
151 p = -p;
152 }
153
154 // check if leading scatterer(s) already present or need to be added (up to
155 // delimiter)
156 bool energyGain = false;
157 bool haveDelimiter = false;
158 std::optional<TrackSurfaceIntersection> intersection = std::nullopt;
159 int leadingScatterers = 0;
160 Trk::FitMeasurement* leadingScatterer = nullptr;
161 for (auto* measurement : measurements) {
162 if ((*measurement).isMaterialDelimiter()) {
163 haveDelimiter = true;
164 } else if ((*measurement).isScatterer()) {
165 // count unfitted scatterers
166 if (!(*measurement).numberDoF()) {
167 ++leadingScatterers;
168 leadingScatterer = measurement;
169 } else {
170 if (std::abs(1. / (*measurement).qOverP()) > p)
171 energyGain = true;
172 break;
173 }
174 }
175 }
176
177 // need to allocate leading scatterers
178 if (haveDelimiter && !leadingScatterers) {
179 // find first measurement after delimiter
180 haveDelimiter = false;
181 Amg::Vector3D endPosition = fitParameters.vertex();
182 const Surface* firstMeasurementSurface = nullptr;
183 Trk::FitMeasurement* leadingOutlier = nullptr;
184 std::vector<Trk::FitMeasurement*> leadingOutliers;
185 const Surface* surface = nullptr;
186 for (auto* measurement : measurements) {
187 if ((*measurement).isMaterialDelimiter()) {
188 haveDelimiter = true;
189 endPosition = (*measurement).position();
190 surface = (*measurement).surface();
191 } else if ((*measurement).isPositionMeasurement()) {
192 if ((*measurement).isOutlier()) {
193 if (!firstMeasurementSurface)
194 leadingOutliers.push_back(measurement);
195 } else {
196 if (!firstMeasurementSurface && !intersection) {
197 firstMeasurementSurface = (*measurement).surface();
198 intersection = TrackSurfaceIntersection(
199 (*measurement).intersection(FittedTrajectory));
200 }
201 if (!haveDelimiter)
202 continue;
203 // surface = (**m).surface();
204 }
205 } else if ((*measurement).isScatterer()) {
206 if (!surface)
207 continue;
208 // FIXME: update p for Perigee in case of gain??
209 if (std::abs(1. / (*measurement).qOverP()) > p)
210 energyGain = true;
211 break;
212 }
213 }
214
215 // leading material identified by outwards extrapolateM from perigee to
216 // delimiter
217 // FIXME: currently only for indet
218 // first create the fitted perigee (ignoring the leading material)
219 const Perigee perigee(fitParameters.position(), p * fitParameters.direction(),
220 charge, fitParameters.vertex());
221 bool haveMaterial = false;
222 const std::vector<const TrackStateOnSurface*>* indetMaterial = nullptr;
223 if (haveDelimiter && intersection && surface &&
224 m_indetVolume->inside(endPosition)) {
225 // debug
226 if (msgLvl(MSG::VERBOSE)) {
227 const Amg::Vector3D& direction = intersection->direction();
228 const Amg::Vector3D& startPosition = intersection->position();
230 " addLeadingMaterial: using extrapolateM from distance "
231 << direction.dot(fitParameters.position() - startPosition));
232 }
233
234 // extrapolateM from perigee to get leading material
236 alongMomentum, false,
237 particleHypothesis, garbage);
238
239 // check material found (expected at least for leading measurement)
240 if (indetMaterial && !indetMaterial->empty()) {
241 std::vector<const TrackStateOnSurface*>::const_reverse_iterator r =
242 indetMaterial->rbegin();
243 for (; r != indetMaterial->rend(); ++r) {
244 // ignore trailing material
245 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
246 intersection->direction().dot(
247 (**r).trackParameters()->position() - endPosition) > 0.)
248 continue;
249
250 haveMaterial = true;
251 }
252 }
253 } else {
254 haveDelimiter = false;
255 }
256
257 // try again with back extrapolation if no leading material found
258 if (haveDelimiter && !haveMaterial) {
259 // debug
261 " no leading material found with forward extrapolation"
262 << ", try again with back extrapolation ");
263
264 // clean up after previous attempt
266 indetMaterial = nullptr;
267
268 std::vector<const TrackStateOnSurface*>* indetMaterialF = nullptr;
269 const std::vector<const TrackStateOnSurface*>* indetMaterialR = nullptr;
270 const CurvilinearUVT uvt(intersection->direction());
271 Amg::Vector2D localPos;
272 const PlaneSurface plane(intersection->position(), uvt);
273 if (plane.globalToLocal(intersection->position(),
274 intersection->direction(), localPos)) {
275 const AtaPlane parameters(localPos[locR], localPos[locZ],
276 intersection->direction().phi(),
277 intersection->direction().theta(), qOverP, plane);
278
279 indetMaterialR = extrapolatedMaterial(
280 m_extrapolator, parameters, perigee.associatedSurface(),
281 oppositeMomentum, false, particleHypothesis, garbage);
282
283 if (indetMaterialR && !indetMaterialR->empty()) {
284 indetMaterialF = new std::vector<const TrackStateOnSurface*>;
285 indetMaterialF->reserve(indetMaterialR->size());
286
287 std::vector<const TrackStateOnSurface*>::const_reverse_iterator r =
288 indetMaterialR->rbegin();
289 for (; r != indetMaterialR->rend(); ++r) {
290 indetMaterialF->push_back(*r);
291 }
292
293 for (r = indetMaterialF->rbegin(); r != indetMaterialF->rend(); ++r) {
294 // ignore trailing material
295 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
296 intersection->direction().dot(
297 (**r).trackParameters()->position() - endPosition) > 0.)
298 continue;
299
300 haveMaterial = true;
301 }
302 indetMaterial = indetMaterialF;
303 indetMaterialF = nullptr;
304 }
305 }
306 delete indetMaterialR;
307 }
308
309 // create scatterer FitMeasurement's corresponding to leading material
310 // (intersector running inwards to give parameters with qOverP update)
311 FitMeasurement* leadingMeas = nullptr;
312 if (indetMaterial && !indetMaterial->empty()) {
313 std::vector<const TrackStateOnSurface*>::const_reverse_iterator r =
314 indetMaterial->rbegin();
315 for (; r != indetMaterial->rend(); ++r) {
316 // ignore trailing material
317 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
318 intersection->direction().dot((**r).trackParameters()->position() -
319 endPosition) > 0.)
320 continue;
321
322 // intersect material surface
323 double eLoss = 0.;
324 const MaterialEffectsOnTrack* materialEffects =
325 dynamic_cast<const MaterialEffectsOnTrack*>(
326 (**r).materialEffectsOnTrack());
327 if (materialEffects) {
328 eLoss = std::abs(materialEffects->energyLoss()->deltaE());
329 if (energyGain)
330 eLoss = -eLoss;
331 }
332
333 if (leadingScatterers++ || !firstMeasurementSurface) {
334 if (m_useStepPropagator == 99) {
335 std::optional<TrackSurfaceIntersection> const newIntersectionSTEP =
336 m_stepPropagator->intersectSurface(
337 ctx, (**r).trackParameters()->associatedSurface(),
339 Trk::MagneticFieldProperties(Trk::FullField), Trk::muon);
340 intersection = m_intersector->intersectSurface(
341 (**r).trackParameters()->associatedSurface(), *intersection,
342 qOverP);
343 } else {
346 ? m_stepPropagator->intersectSurface(
347 ctx, (**r).trackParameters()->associatedSurface(),
349 : m_intersector->intersectSurface(
350 (**r).trackParameters()->associatedSurface(),
352 }
353
354 // quit if tracking problem
355 if (!intersection) {
357 measurements.front()->intersection(FittedTrajectory);
358 break;
359 }
360 leadingMeas =
361 new FitMeasurement((**r).materialEffectsOnTrack(),
362 Trk::ParticleMasses::mass[particleHypothesis],
363 intersection->position());
364 } else {
365 // remove leadingOutliers - they will be reinserted wrt the
366 // leadingScatterers
367 for (std::vector<Trk::FitMeasurement*>::const_iterator l =
368 leadingOutliers.begin();
369 l != leadingOutliers.end(); ++l) {
370 leadingOutlier = leadingOutliers.back();
371 measurements.erase(
372 std::remove(measurements.begin(), measurements.end(), *l),
373 measurements.end());
374 }
375 leadingMeas = new FitMeasurement(
376 (**r).materialEffectsOnTrack()->thicknessInX0(), -eLoss,
377 Trk::ParticleMasses::mass[particleHypothesis],
378 intersection->position(), intersection->direction(), qOverP,
379 firstMeasurementSurface);
380 leadingScatterer = leadingMeas;
381 }
382 leadingMeas->intersection(FittedTrajectory, intersection);
383 leadingMeas->qOverP(qOverP);
384
385 // put corresponding scatterer FitMeasurement at front of list,
386 // after re-inserting any intermediate leadingOutliers
387 if (leadingOutlier) {
388 const double radius =
389 leadingMeas->intersection(FittedTrajectory).position().perp();
390 while (
391 leadingOutlier &&
392 leadingOutlier->intersection(FittedTrajectory).position().perp() >
393 radius) {
394 leadingOutliers.pop_back();
395 measurements.insert(measurements.begin(), leadingOutlier);
396 if (!leadingOutliers.empty()) {
397 leadingOutlier = leadingOutliers.back();
398 } else {
399 leadingOutlier = nullptr;
400 }
401 }
402 }
403
404 ATH_MSG_DEBUG(" push_front(leadingMeas) ");
405
406 measurements.insert(measurements.begin(), leadingMeas);
407
408 // update momentum for energy loss
409 if (materialEffects) {
410 if (charge > 0.) {
411 qOverP = 1. / (1. / qOverP + eLoss);
412 } else {
413 qOverP = 1. / (1. / qOverP - eLoss);
414 }
415 }
416 }
417 }
418
419 // final step to give intersection at perigee surface plus memory management
420 if (leadingMeas) {
421 if (m_useStepPropagator == 99) {
422 std::optional<TrackSurfaceIntersection> const newIntersectionSTEP =
423 m_stepPropagator->intersectSurface(
424 ctx, perigee.associatedSurface(), *intersection, qOverP,
425 Trk::MagneticFieldProperties(Trk::FullField), Trk::muon);
426 intersection = m_intersector->intersectSurface(
427 perigee.associatedSurface(), *intersection, qOverP);
428 } else {
431 ? m_stepPropagator->intersectSurface(
432 ctx, perigee.associatedSurface(), *intersection, qOverP,
434 : m_intersector->intersectSurface(perigee.associatedSurface(),
436 }
437 } else {
438 intersection = std::nullopt;
439 }
441 indetMaterial = nullptr;
442 }
443
444 // integrate X0, energy loss and contribution to covariance (from leading
445 // scatterer towards perigee)
446 AmgSymMatrix(5) leadingCovariance;
447 leadingCovariance.setZero();
448 if (leadingScatterers) {
449 double leadingScattering = 0.;
450 double previousScattering = 0.;
451 double leadingX0Integral = 0.;
452 std::vector<Trk::FitMeasurement*>::reverse_iterator m =
453 measurements.rbegin();
454 while (*m != leadingScatterer)
455 ++m;
456 for (; m != measurements.rend(); ++m) {
457 if (!(**m).isScatterer())
458 continue;
459 const MaterialEffectsOnTrack* materialEffects =
460 dynamic_cast<const MaterialEffectsOnTrack*>((**m).materialEffects());
461 if (!materialEffects)
462 continue;
463
464 // set the scattering angle and X0Integral
465 leadingX0Integral += (**m).materialEffects()->thicknessInX0();
466 const double logTerm = 1.0 + m_scatteringLogCoeff * std::log(leadingX0Integral);
467 leadingScattering = leadingX0Integral * logTerm * logTerm;
468 const double scatteringAngle =
470 std::sqrt(leadingScattering - previousScattering);
471 previousScattering = leadingScattering;
472 (**m).scatteringAngle(scatteringAngle, leadingX0Integral);
473
474 // the scattering contribution to the covariance at perigee
475 double angleSquared = 1. / (**m).weight();
476 const double deltaR = ((**m).intersection(FittedTrajectory).position() -
477 fitParameters.vertex())
478 .perp();
479 const double sinThetaSquared =
480 (**m).intersection(FittedTrajectory).direction().perp2();
481 angleSquared *= angleSquared / sinThetaSquared;
482
483 // transverse projection
484 leadingCovariance(0, 0) += deltaR * deltaR * angleSquared;
485 leadingCovariance(0, 2) -= deltaR * angleSquared;
486 leadingCovariance(2, 0) = leadingCovariance(0, 2);
487 leadingCovariance(2, 2) += angleSquared;
488
489 // longitudinal projection (to get z: remember dcotTh/dTh = -1/sin*sin)
490 leadingCovariance(1, 1) +=
491 deltaR * deltaR * angleSquared / sinThetaSquared;
492 leadingCovariance(1, 3) += deltaR * angleSquared;
493 leadingCovariance(3, 1) = leadingCovariance(1, 3);
494 leadingCovariance(3, 3) += angleSquared * sinThetaSquared;
495 }
496 }
497
498 // if leading material has just been added
499 if (intersection) {
500 fitParameters.update(intersection->position(), intersection->direction(),
501 qOverP, leadingCovariance);
502 }
503 // or pre-existing leading material
504 else {
505 fitParameters.update(fitParameters.position(), fitParameters.direction(),
506 qOverP, leadingCovariance);
507 }
508
509 // debug
510 if (msgLvl(MSG::DEBUG)) {
511 if (!haveDelimiter)
512 ATH_MSG_VERBOSE(" addLeadingMaterial: ");
513 printMeasurements(measurements);
514 }
515}
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
#define AmgSymMatrix(dim)
if(febId1==febId2)
bool msgLvl(const MSG::Level lvl) const
const TrackSurfaceIntersection & intersection(ExtrapolationType type) const
ToolHandle< IPropagator > m_stepPropagator
ToolHandle< IIntersector > m_intersector
Trk::MagneticFieldProperties m_stepField
void printMeasurements(std::vector< FitMeasurement * > &measurements) const
const std::vector< const TrackStateOnSurface * > * extrapolatedMaterial(const ToolHandle< IExtrapolator > &extrapolator, const TrackParameters &parameters, const Surface &surface, PropDirection dir, const BoundaryCheck &boundsCheck, ParticleHypothesis particleHypothesis, Garbage_t &garbage) const
void indetMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, const TrackParameters &startParameters, Garbage_t &garbage) const
static void deleteMaterial(const std::vector< const TrackStateOnSurface * > *material, Garbage_t &garbage)
ToolHandle< IExtrapolator > m_extrapolator
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
int r
Definition globals.cxx:22
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
@ oppositeMomentum
@ alongMomentum
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ FullField
Field is set to be realistic, but within a given Volume.
@ locR
Definition ParamDefs.h:44
@ qOverP
perigee
Definition ParamDefs.h:67
@ locZ
local cylindrical
Definition ParamDefs.h:42
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane
@ FittedTrajectory
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.

◆ addSpectrometerDelimiters()

void Trk::MaterialAllocator::addSpectrometerDelimiters ( std::vector< FitMeasurement * > & measurements) const
private

Definition at line 874 of file MaterialAllocator.cxx.

875 {
876 // insert delimiters representing station limits for later material
877 // aggregation
878 // preBreak: put delimiter upstream of measurement
879 // postBreak: put delimiter downstream of previous measurement
880 // FIXME: modify aggregation function: no aggregation in EC toroid region
881 // (~11m)
882 // FIXME: single scatterer in outer delimited pair
883 // printMeasurements(measurements);
884 FitMeasurement* previous = nullptr;
885 double previousDistance = 0.;
886
887 Amg::Vector3D startDirection;
888 Amg::Vector3D startPosition;
889 Amg::Vector3D referenceDirection;
890 Amg::Vector3D referencePosition;
891 double referencePhi = 0.;
892 for (std::vector<FitMeasurement*>::iterator m = measurements.begin();
893 m != measurements.end(); ++m) {
894 // skip 'non'-measurements
895 if (!(**m).isPositionMeasurement() || (**m).isPseudo())
896 continue;
897
898 // material delimiters in MS follow the entrance break which should be
899 // already present
900 const Amg::Vector3D position = (**m).position();
901 if (m_calorimeterVolume->inside(position))
902 continue;
903
904 // break can be before measurement or after previous measurement
905 bool preBreak = false;
906 bool postBreak = false;
907 double distance = 0.;
908 if (!previous) {
909 // preBreak at first measurement in MS
910 preBreak = true;
911 referenceDirection = (**m).intersection(FittedTrajectory).direction();
912 referencePosition = (**m).intersection(FittedTrajectory).position();
913 referencePhi = position.phi();
914 startDirection = referenceDirection;
915 startPosition = referencePosition;
916 } else {
917 // post and pre breaks for cluster/drift transition,
918 // large gap between measurements,
919 // sector overlap
920 distance = referenceDirection.dot(
921 (**m).intersection(FittedTrajectory).position() - referencePosition);
922 if (((**m).isDrift() && !previous->isDrift()) ||
923 (!(**m).isDrift() && previous->isDrift()) ||
924 distance > m_stationMaxGap ||
925 ((**m).isDrift() &&
926 std::abs(position.phi() - referencePhi) > m_sectorMaxPhi)) {
927 preBreak = true;
928 if (distance > previousDistance + m_scattererMinGap)
929 postBreak = true;
930 }
931 }
932
933 if (!(preBreak || postBreak)) {
934 previous = *m;
935 previousDistance = distance;
936 continue;
937 }
938
939 if (postBreak && previous) {
940 // if (distance < offset) offset = 0.5*distance;
941 FitMeasurement* current = *m;
942 while (*m != previous)
943 --m;
944 FitMeasurement* delimiter = new FitMeasurement(
945 (**m).intersection(FittedTrajectory), 0.5 * m_scattererMinGap);
946 m = measurements.insert(++m, delimiter);
947 while (*m != current)
948 ++m;
949 }
950 if (preBreak) {
951 double offset = -0.5 * m_scattererMinGap;
952 if (distance - previousDistance < m_scattererMinGap)
953 offset = 0.5 * (previousDistance - distance);
954
955 FitMeasurement* delimiter =
956 new FitMeasurement((**m).intersection(FittedTrajectory), offset);
957 m = measurements.insert(m, delimiter);
958 ++m;
959 }
960 previous = *m;
961 previousDistance = 0.;
962 referenceDirection = (**m).intersection(FittedTrajectory).direction();
963 referencePosition = (**m).intersection(FittedTrajectory).position();
964 referencePhi = position.phi();
965 }
966 // orderMeasurements(measurements,startDirection,startPosition);
967 // printMeasurements(measurements);
968}
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
@ previous
Definition BinningData.h:32

◆ allocateMaterial()

void Trk::MaterialAllocator::allocateMaterial ( std::vector< FitMeasurement * > & measurements,
ParticleHypothesis particleHypothesis,
FitParameters & fitParameters,
const TrackParameters & startParameters,
Garbage_t & garbage ) const
overridevirtual

IMaterialAllocator interface: allocate material.

Implements Trk::IMaterialAllocator.

Definition at line 517 of file MaterialAllocator.cxx.

520 {
521 // different strategies used for indet and muon spectrometer
522 indetMaterial(measurements, particleHypothesis, startParameters, garbage);
523 if (!m_extrapolator.empty())
524 spectrometerMaterial(measurements, particleHypothesis, fitParameters,
525 startParameters, garbage);
526
527 // debug
528 if (msgLvl(MSG::VERBOSE)) {
529 ATH_MSG_VERBOSE(" allocateMaterial: ");
530 printMeasurements(measurements);
531 }
532}
void spectrometerMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, const TrackParameters &startParameters, Garbage_t &garbage) const

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ deleteMaterial()

void Trk::MaterialAllocator::deleteMaterial ( const std::vector< const TrackStateOnSurface * > * material,
Garbage_t & garbage )
staticprivate

Definition at line 970 of file MaterialAllocator.cxx.

972 {
973 if (material) {
974 for (const TrackStateOnSurface* m : *material) {
975 garbage.push_back(std::unique_ptr<const TrackStateOnSurface>(m));
976 }
977 delete material;
978 }
979}

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ extrapolatedMaterial()

const std::vector< const TrackStateOnSurface * > * Trk::MaterialAllocator::extrapolatedMaterial ( const ToolHandle< IExtrapolator > & extrapolator,
const TrackParameters & parameters,
const Surface & surface,
PropDirection dir,
const BoundaryCheck & boundsCheck,
ParticleHypothesis particleHypothesis,
Garbage_t & garbage ) const
private

Definition at line 982 of file MaterialAllocator.cxx.

986 {
987 const EventContext& ctx = Gaudi::Hive::currentContext();
988 // fix up material duplication appearing after recent TrackingGeometry
989 // speed-up
990 const std::vector<const TrackStateOnSurface*>* TGMaterial =
991 extrapolator->extrapolateM(ctx, parameters, surface, dir, boundsCheck,
992 particleHypothesis);
993
994 if (!TGMaterial || TGMaterial->empty())
995 return TGMaterial;
996
997 std::vector<const TrackStateOnSurface*>* duplicates = nullptr;
998 std::vector<const TrackStateOnSurface*>* material =
999 new std::vector<const TrackStateOnSurface*>;
1000 material->reserve(TGMaterial->size());
1001 std::vector<const TrackStateOnSurface*>::const_iterator tg =
1002 TGMaterial->begin();
1003 material->push_back(*tg);
1004 ++tg;
1005 for (; tg != TGMaterial->end(); ++tg) {
1006 const TrackStateOnSurface* TSOS = material->back();
1007 double separation = 0.;
1008 if (TSOS->trackParameters())
1009 separation = (TSOS->trackParameters()->position() -
1010 (**tg).trackParameters()->position())
1011 .mag();
1012
1013 if (separation > 0.001 * Gaudi::Units::mm) {
1014 material->push_back(*tg);
1015 } else {
1017 std::setiosflags(std::ios::fixed)
1018 << " duplicate: RZ" << std::setw(9) << std::setprecision(3)
1019 << (**tg).trackParameters()->position().perp() << std::setw(10)
1020 << std::setprecision(3) << (**tg).trackParameters()->position().z());
1021 if (!duplicates)
1022 duplicates = new std::vector<const TrackStateOnSurface*>;
1023 duplicates->push_back(*tg);
1024 }
1025 }
1026
1027 delete TGMaterial;
1028 if (duplicates)
1029 deleteMaterial(duplicates, garbage);
1030 return material;
1031}

◆ finalize()

StatusCode Trk::MaterialAllocator::finalize ( )
overridevirtual

Definition at line 124 of file MaterialAllocator.cxx.

124 {
125 // summarize WARNINGs
126 m_messageHelper->printSummary();
127 return StatusCode::SUCCESS;
128}

◆ getSpectrometerEntrance()

const Trk::TrackingVolume * Trk::MaterialAllocator::getSpectrometerEntrance ( ) const
inlineprivate

Good old way of retrieving the volume via the geometry service

Definition at line 158 of file MaterialAllocator.h.

158 {
159 static const std::string vol_name = "MuonSpectrometerEntrance";
161 if (m_trackingGeometryReadKey.empty()) {
162 return m_trackingGeometrySvc->trackingGeometry()->trackingVolume(
163 vol_name);
164 }
165 SG::ReadCondHandle<Trk::TrackingGeometry> handle(
166 m_trackingGeometryReadKey, Gaudi::Hive::currentContext());
167 if (!handle.isValid()) {
168 ATH_MSG_WARNING("Could not retrieve a valid tracking geometry");
169 return nullptr;
170 }
171 return handle.cptr()->trackingVolume(vol_name);
172 }
#define ATH_MSG_WARNING(x)
SG::ReadCondHandleKey< TrackingGeometry > m_trackingGeometryReadKey
ServiceHandle< ITrackingGeometrySvc > m_trackingGeometrySvc

◆ indetMaterial()

void Trk::MaterialAllocator::indetMaterial ( std::vector< FitMeasurement * > & measurements,
ParticleHypothesis particleHypothesis,
const TrackParameters & startParameters,
Garbage_t & garbage ) const
private

Definition at line 1033 of file MaterialAllocator.cxx.

1036 {
1037 const EventContext& ctx = Gaudi::Hive::currentContext();
1038 // gather material between first and last measurements inside indet volume
1039 // allow a few mm radial tolerance around first&last measurements for their
1040 // associated material
1041 const double tolerance =
1042 10. * Gaudi::Units::mm / startParameters.momentum().unit().perp();
1043
1044 // loop over measurements to define portions of track needing indet material
1045 double endIndetDistance = 0.;
1046 FitMeasurement* endIndetMeasurement = nullptr;
1047 const double qOverP = startParameters.charge() / startParameters.momentum().mag();
1048
1049 Amg::Vector3D startDirection = startParameters.momentum().unit();
1050 Amg::Vector3D startPosition = startParameters.position();
1051 const TrackParameters* parameters = &startParameters;
1052 std::unique_ptr<AtaPlane> newParameters;
1053
1054 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1055 if ((**m).isVertex())
1056 ++m;
1057 for (; m != measurements.end(); ++m) {
1058 if ((**m).isOutlier())
1059 continue;
1060 if (m_indetVolume->inside((**m).position())) {
1061 // quit if pre-existing indet material
1062 if ((**m).isScatterer()) {
1063 return;
1064 }
1065
1066 // use first measurement at a plane surface to create starting parameters
1067 if (!(**m).isPositionMeasurement())
1068 continue;
1069 if (!endIndetMeasurement && (**m).hasIntersection(FittedTrajectory) &&
1070 ((**m).surface()->type() == Trk::SurfaceType::Plane ||
1071 (**m).surface()->type() == Trk::SurfaceType::Disc)) {
1072 std::optional<TrackSurfaceIntersection> intersection =
1073 (**m).intersection(FittedTrajectory);
1074 const Amg::Vector3D offset = intersection->direction() * tolerance;
1075 const CurvilinearUVT uvt(intersection->direction());
1076 const PlaneSurface plane(intersection->position() - offset, uvt);
1077
1078 if (m_useStepPropagator == 99) {
1079 std::optional<TrackSurfaceIntersection> const newIntersectionSTEP =
1080 m_stepPropagator->intersectSurface(
1081 ctx, plane, *intersection, qOverP,
1082 Trk::MagneticFieldProperties(Trk::FullField), Trk::muon);
1083 intersection =
1084 m_intersector->intersectSurface(plane, *intersection, qOverP);
1085 if (newIntersectionSTEP && intersection) {
1086 // double dist =
1087 // 1000.*(newIntersectionSTEP->position()-intersection->position()).mag();
1088 // std::cout << " iMat 3 distance STEP and
1089 // Intersector " << dist << std::endl;
1090 // if(dist>10.) std::cout << " iMat 3 ALARM
1091 // distance STEP and Intersector " << dist <<
1092 // std::endl;
1093 } else {
1094 // if(intersection) std::cout << " iMat 3 ALARM
1095 // STEP did not intersect! " << std::endl;
1096 }
1097 } else {
1099 ? m_stepPropagator->intersectSurface(
1100 ctx, plane, *intersection, qOverP,
1102 : m_intersector->intersectSurface(
1103 plane, *intersection, qOverP);
1104 }
1105 Amg::Vector2D localPos;
1106 if (intersection &&
1107 plane.globalToLocal(intersection->position(),
1108 intersection->direction(), localPos)) {
1109 newParameters = std::make_unique<AtaPlane>(
1110 localPos[locR], localPos[locZ], intersection->direction().phi(),
1111 intersection->direction().theta(), qOverP, plane);
1112 parameters = newParameters.get();
1113 startDirection = intersection->direction();
1114 startPosition = intersection->position();
1115 }
1116 }
1117
1118 // save the last indet measurement, signal any out-of-order meas
1119 const double distance = startDirection.dot(
1120 (**m).intersection(FittedTrajectory).position() - startPosition);
1121 if (!endIndetMeasurement || distance > endIndetDistance) {
1122 endIndetDistance = distance;
1123 endIndetMeasurement = *m;
1124 }
1125 } else { // outside indet
1126 break;
1127 }
1128 }
1129 if (!endIndetMeasurement) {
1130 return;
1131 }
1132
1133 ATH_MSG_DEBUG(" indetMaterial: ALARM no material found on track");
1134
1135 // allocate indet material from TrackingGeometry
1136 const Amg::Vector3D endPosition =
1137 endIndetMeasurement->intersection(FittedTrajectory).position();
1138 startDirection = (endPosition - startPosition).unit();
1139 endIndetDistance =
1140 startDirection.dot(endPosition - startPosition) + tolerance;
1141 ATH_MSG_VERBOSE(" indetMaterial: using extrapolateM out to distance "
1142 << endIndetDistance);
1143 const std::vector<const TrackStateOnSurface*>* indetMaterial =
1145 *endIndetMeasurement->surface(), alongMomentum,
1146 false, particleHypothesis, garbage);
1147
1148 if (!indetMaterial || indetMaterial->empty()) {
1149 deleteMaterial(indetMaterial, garbage);
1150 return;
1151 }
1152
1153 // insert the material into the measurement list
1154 // ignore trailing material - with a few mm radial tolerance
1155 std::vector<const Surface*> surfaces;
1156 surfaces.reserve(indetMaterial->size());
1157 std::vector<const TrackStateOnSurface*>::const_iterator indetMaterialEnd =
1158 indetMaterial->begin();
1159 int trailing = indetMaterial->size();
1160 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1161 indetMaterial->begin();
1162 s != indetMaterial->end(); ++s, --trailing) {
1163 if ((**s).trackParameters()) {
1164 if (startDirection.dot((**s).trackParameters()->position() -
1165 startPosition) < endIndetDistance) {
1166 indetMaterialEnd = s;
1167 ++indetMaterialEnd;
1168 } else {
1169 ATH_MSG_VERBOSE(" indetMaterial: "
1170 << trailing
1171 << " trailing TSOS (after last measurement)");
1172 break;
1173 }
1174 }
1175 }
1176
1177 // return in case of extrapolateM problem
1178 if (indetMaterialEnd == indetMaterial->begin()) {
1179 // extrapolateM finds no material on track !!
1180 m_messageHelper->printWarning(1);
1181 deleteMaterial(indetMaterial, garbage);
1182 return;
1183 }
1184
1185 // debug
1186 if (msgLvl(MSG::VERBOSE)) {
1187 double p1 = indetMaterial->front()->trackParameters()->momentum().mag();
1188
1189 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1190 indetMaterial->begin();
1191 s != indetMaterialEnd; ++s) {
1192 if (!(**s).trackParameters())
1193 continue;
1194 const double distance = startDirection.dot((**s).trackParameters()->position() -
1195 startPosition);
1196 double deltaE = 0.;
1197 double thickness = 0.;
1198 const MaterialEffectsOnTrack* materialEffects =
1199 dynamic_cast<const MaterialEffectsOnTrack*>(
1200 (**s).materialEffectsOnTrack());
1201 if ((**s).materialEffectsOnTrack()) {
1202 if (materialEffects)
1203 deltaE = materialEffects->energyLoss()->deltaE();
1204 thickness = (**s).materialEffectsOnTrack()->thicknessInX0();
1205 }
1206 const double p2 = (**s).trackParameters()->momentum().mag();
1208 std::setiosflags(std::ios::fixed)
1209 << " material: RZ" << std::setw(9) << std::setprecision(3)
1210 << (**s).trackParameters()->position().perp() << std::setw(10)
1211 << std::setprecision(3) << (**s).trackParameters()->position().z()
1212 << " distance " << std::setw(10) << std::setprecision(3) << distance
1213 << " pt " << std::setw(8) << std::setprecision(3)
1214 << (**s).trackParameters()->momentum().perp() / Gaudi::Units::GeV
1215 << " X0thickness " << std::setw(8) << std::setprecision(4)
1216 << thickness << " deltaE " << std::setw(8) << std::setprecision(4)
1217 << deltaE << " diffP " << std::setw(8) << std::setprecision(4)
1218 << p2 - p1);
1219 p1 = p2;
1220 }
1221 }
1222
1223 // firstly: add the material belonging to each measurement layer (and skip
1224 // leading material)
1225 FitMeasurement* leadingDelimiter = nullptr;
1226 Amg::Vector3D nextMomentum(0., 0., 0.);
1227 Amg::Vector3D nextPosition(0., 0., 0.);
1228 m = measurements.begin();
1229 std::vector<const TrackStateOnSurface*>::const_iterator s =
1230 indetMaterial->begin();
1231 for (; m != measurements.end(); ++m) {
1232 if (*m == endIndetMeasurement || s == indetMaterialEnd)
1233 break;
1234 if (!leadingDelimiter && (**m).isOutlier())
1235 continue;
1236
1237 Amg::Vector3D direction = (**m).intersection(FittedTrajectory).direction();
1238 Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
1239 double closestDistance = direction.dot(position - startPosition);
1240 const MaterialEffectsOnTrack* materialEffects = nullptr;
1241 const TrackParameters* materialParameters = nullptr;
1242 const Surface* materialSurface = nullptr;
1243
1244 // find the closest material TSOS (inside radial tolerance)
1245 for (; s != indetMaterialEnd; ++s) {
1246 if (!dynamic_cast<const MaterialEffectsOnTrack*>(
1247 (**s).materialEffectsOnTrack()) ||
1248 !(**s).trackParameters())
1249 continue;
1250 nextMomentum = (**s).trackParameters()->momentum();
1251 nextPosition = (**s).trackParameters()->position();
1252 const double distance = direction.dot(nextPosition - position);
1253
1254 // increasing distance - break when past minimum
1255 if (distance > closestDistance)
1256 break;
1257
1258 // downstream material - check not significantly closer to following
1259 // measurement
1260 // (material too early is better than too late)
1261 if (distance > 0.) {
1262 ++m;
1263 const double nextDistance = direction.dot(
1264 (**s).trackParameters()->position() - (**m).position());
1265 --m;
1266 if (std::abs(nextDistance) < distance && distance > tolerance) {
1267 if (s != indetMaterial->begin())
1268 --s;
1269 materialSurface = nullptr;
1270 break;
1271 }
1272 closestDistance = distance;
1273 } else {
1274 closestDistance = -distance;
1275 }
1276
1277 // when upstream of leading break any previous surface is going to be
1278 // ignored
1279 if (!leadingDelimiter && materialSurface)
1280 surfaces.push_back(materialSurface);
1281
1282 materialEffects = dynamic_cast<const MaterialEffectsOnTrack*>(
1283 (**s).materialEffectsOnTrack());
1284 materialParameters = (**s).trackParameters();
1285 materialSurface = &materialParameters->associatedSurface();
1286 }
1287
1288 // skip if the material has not been allocated to a measurement surface
1289 if (!materialSurface)
1290 continue;
1291
1292 // or if it's already been allocated upstream
1293 if (!surfaces.empty() && materialSurface == surfaces.back())
1294 continue;
1295
1296 // skip leading material during the fit (up to and including first
1297 // measurement) insert an materialDelimiter so the leading material can be
1298 // allocated after the fit converges
1299 if (!leadingDelimiter) {
1300 position = 0.5 * (materialParameters->position() + nextPosition);
1301 direction = (materialParameters->momentum() + nextMomentum).unit();
1302 TrackSurfaceIntersection const breakIntersection(position, direction, 0.);
1303 leadingDelimiter = new FitMeasurement(breakIntersection, 0.);
1304 while (*m != endIndetMeasurement &&
1305 direction.dot((**m).intersection(FittedTrajectory).position() -
1306 position) < 0.)
1307 ++m;
1308 m = measurements.insert(m, leadingDelimiter);
1309 surfaces.push_back(materialSurface);
1310 continue;
1311 }
1312
1313 // check inside tolerance
1314 if (closestDistance > tolerance)
1315 continue;
1316
1317 // insert material at measurement surface
1318 const std::bitset<MaterialEffectsBase::NumberOfMaterialEffectsTypes>
1319 typePattern;
1320 std::unique_ptr<Trk::EnergyLoss> energyLoss = nullptr;
1321 if (materialEffects->energyLoss()) {
1322 energyLoss = std::unique_ptr<Trk::EnergyLoss>(
1323 materialEffects->energyLoss()->clone());
1324 }
1325 MaterialEffectsOnTrack* meot = new MaterialEffectsOnTrack(
1326 materialEffects->thicknessInX0(), std::move(energyLoss),
1327 *(**m).surface(), typePattern);
1328 const TrackSurfaceIntersection& intersection = (**m).intersection(FittedTrajectory);
1329 if (++m == measurements.end())
1330 --m;
1331 m = measurements.insert(
1332 m,
1333 new FitMeasurement(meot, Trk::ParticleMasses::mass[particleHypothesis],
1334 intersection.position()));
1335 (**m).intersection(FittedTrajectory, intersection);
1336 (**m).qOverP(materialParameters->parameters()[Trk::qOverP]);
1337 (**m).setMaterialEffectsOwner();
1338 surfaces.push_back(materialSurface);
1339 }
1340
1341 // secondly: insert remaining material between measurement layers
1342 m = measurements.begin();
1343 int im = 0;
1344 ATH_MSG_VERBOSE(" measurements.size() "
1345 << measurements.size() << " surfaces.size() "
1346 << surfaces.size() << " indetMaterial->size() "
1347 << indetMaterial->size());
1348 std::vector<const Surface*>::const_iterator r = surfaces.begin();
1349 for (s = indetMaterial->begin(); s != indetMaterialEnd; ++s) {
1350 if (!(**s).trackParameters() || !(**s).materialEffectsOnTrack())
1351 continue;
1352
1353 if (r != surfaces.end() &&
1354 **r == (**s).trackParameters()->associatedSurface()) {
1355 ++r;
1356 continue;
1357 }
1358
1359 const double distance =
1360 startDirection.dot((**s).trackParameters()->position() - startPosition);
1361
1362 ATH_MSG_VERBOSE(" startPosition " << startPosition.perp() << " z "
1363 << startPosition.z());
1365 " (**m).intersection(FittedTrajectory).position() measurement "
1366 "position r "
1367 << (**m).intersection(FittedTrajectory).position().perp() << " z "
1368 << (**m).intersection(FittedTrajectory).position().z());
1370 " (**s).trackParameters()->position() material surface position "
1371 "r "
1372 << (**s).trackParameters()->position().perp() << " z "
1373 << (**s).trackParameters()->position().z());
1374 ATH_MSG_VERBOSE(" distance material surface " << distance);
1375
1376 bool endIndet = false;
1377 while (distance >
1378 startDirection.dot((**m).intersection(FittedTrajectory).position() -
1379 startPosition)) {
1380 if (*m == endIndetMeasurement) {
1381 if (*m != measurements.back()) {
1382 ++m;
1383 ++im;
1384 ATH_MSG_VERBOSE(" measurements.back() im " << im);
1385 }
1386 ATH_MSG_VERBOSE(" break im " << im);
1387 endIndet = true;
1388 break;
1389 }
1390 if (*m != measurements.back()) {
1391 ++m;
1392 ++im;
1394 " loop im "
1395 << im
1396 << " (**m).intersection(FittedTrajectory).position() "
1397 "measurement position r "
1398 << (**m).intersection(FittedTrajectory).position().perp() << " z "
1399 << (**m).intersection(FittedTrajectory).position().z());
1400 } else {
1401 break;
1402 }
1403 }
1405 " im " << im << " distance measurement "
1406 << startDirection.dot(
1407 (**m).intersection(FittedTrajectory).position() -
1408 startPosition));
1410 " (**m).intersection(FittedTrajectory).position() measurement position "
1411 "r "
1412 << (**m).intersection(FittedTrajectory).position().perp() << " z "
1413 << (**m).intersection(FittedTrajectory).position().z());
1414
1415 m = measurements.insert(
1416 m, new FitMeasurement((**s).materialEffectsOnTrack(),
1417 Trk::ParticleMasses::mass[particleHypothesis],
1418 (**s).trackParameters()->position()));
1419 TrackSurfaceIntersection intersection = TrackSurfaceIntersection(
1420 (**s).trackParameters()->position(),
1421 (**s).trackParameters()->momentum().unit(), 0.);
1422 (**m).intersection(FittedTrajectory, intersection);
1423 (**m).qOverP((**s).trackParameters()->parameters()[Trk::qOverP]);
1424 ATH_MSG_VERBOSE(" successfull insertion ");
1425 if (endIndet)
1426 --m;
1427 }
1428
1429 m = measurements.begin();
1430 im = 0;
1431 for (; m != measurements.end(); ++m) {
1432 if (!leadingDelimiter && (**m).isOutlier())
1433 continue;
1434
1435 Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
1436 ++im;
1437 ATH_MSG_VERBOSE(" im " << im << " position R " << position.perp() << " z "
1438 << position.z());
1439 }
1440
1441 // memory management
1442 deleteMaterial(indetMaterial, garbage);
1443
1444 ATH_MSG_VERBOSE(" finished indetMaterial ");
1445}
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
ParametersBase< TrackParametersDim, Charged > TrackParameters
constexpr double tolerance

◆ initialize()

StatusCode Trk::MaterialAllocator::initialize ( )
overridevirtual

Definition at line 71 of file MaterialAllocator.cxx.

71 {
72 // fill WARNING messages
73 m_messageHelper->setMaxNumberOfMessagesPrinted(m_maxWarnings);
74 m_messageHelper->setMessage(
75 0,
76 "leadingSpectrometerTSOS: missing TrackingGeometrySvc - no leading "
77 "material will be added");
78 m_messageHelper->setMessage(
79 1, "indetMaterial: extrapolateM finds no material on track");
80 m_messageHelper->setMessage(
81 2,
82 "spectrometerMaterial: missing TrackingGeometrySvc - no spectrometer "
83 "material added");
84 m_messageHelper->setMessage(3,
85 "spectrometerMaterial: did not find MS entrance "
86 "surface - no MS material taken into account");
87 m_messageHelper->setMessage(4, "spectrometerMaterial: failed extrapolation");
88 m_messageHelper->setMessage(
89 5, "spectrometerMaterial: extrapolateM finds no material on track");
90
91 // retrieve the necessary Extrapolators (muon tracking geometry is very
92 // picky!)
93 ATH_CHECK(m_extrapolator.retrieve());
94 ATH_MSG_DEBUG("Retrieved tool " << m_extrapolator);
95
96 ATH_CHECK(m_intersector.retrieve());
97 ATH_MSG_DEBUG("Retrieved tool " << m_intersector);
98
99 // retrieve services
100 if (m_trackingGeometryReadKey.empty()) {
102 } else
104 // need to create the IndetExit and MuonEntrance TrackingVolumes
106 ATH_MSG_DEBUG("Retrieved Svc " << m_trackingVolumesSvc);
109 m_indetVolume = &(
111
112 if (m_useStepPropagator > 0) {
113 ATH_CHECK(m_stepPropagator.retrieve());
114 }
115
116 // Field for StepPropagator
117 m_stepField = Trk::MagneticFieldProperties(Trk::FullField);
118 if (m_useStepPropagator == 2)
119 m_stepField = Trk::MagneticFieldProperties(Trk::FastField);
120
121 return StatusCode::SUCCESS;
122}
#define ATH_CHECK
Evaluate an expression and check for errors.
@ CalorimeterEntryLayer
Tracking Volume which defines the entrance srufaces of the calorimeter.
@ MuonSpectrometerEntryLayer
Tracking Volume which defines the entrance surfaces of the MS.
ServiceHandle< ITrackingVolumesSvc > m_trackingVolumesSvc
@ FastField
call the fast field access method of the FieldSvc

◆ initializeScattering()

void Trk::MaterialAllocator::initializeScattering ( std::vector< FitMeasurement * > & measurements) const
overridevirtual

IMaterialAllocator interface: initialize scattering (needs to know X0 integral)

Implements Trk::IMaterialAllocator.

Definition at line 534 of file MaterialAllocator.cxx.

535 {
536 // loop over scatterers to include log term corresponding to integral
537 // thickness
538 bool integrate = false;
539 double previousScattering = 0.;
540 double X0Integral = 0.;
541
542 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
543
544 // start integration after any leading material
545 while (!(**m).isPositionMeasurement() || (**m).isOutlier())
546 ++m;
547
548 for (; m != measurements.end(); ++m) {
549 if (integrate && (**m).isPositionMeasurement() && !(**m).isOutlier()) {
550 // restart integration for log term
551 integrate = false;
552 previousScattering = 0.;
553 X0Integral = 0.;
554 }
555 if ((**m).isScatterer()) {
556 if (integrate) {
557 // reset if measurement closely following
558 std::vector<Trk::FitMeasurement*>::iterator next = m;
559 if (++next != measurements.end() && !(**next).hitOnTrack() &&
560 (**next).isPositionMeasurement() && !(**next).isOutlier()) {
561 const Amg::Vector3D position =
562 (**next).intersection(FittedTrajectory).position();
563 if (((**m).intersection(FittedTrajectory).position() - position)
564 .mag() < 1. * Gaudi::Units::mm)
565 integrate = false;
566 }
567
568 if (!integrate) {
569 // restart integration for log term
570 previousScattering = 0.;
571 X0Integral = 0.;
572 }
573 }
574
575 integrate = true;
576 double thicknessInX0 = (**m).materialEffects()->thicknessInX0();
577 if ((**m).materialEffects()->thicknessInX0() < 0.) {
578 ATH_MSG_WARNING("thicknessInX0 smaller or equal to zero "
579 << (**m).materialEffects()->thicknessInX0() << " "
580 << *(**m).materialEffects());
581 thicknessInX0 = 1e-6;
582 }
583 X0Integral += thicknessInX0;
584 double logTerm = 1.;
585 if (X0Integral > 0.) {
586 logTerm = 1.0 + m_scatteringLogCoeff * std::log(X0Integral);
587 } else {
588 ATH_MSG_WARNING("X0Integral smaller or equal to zero "
589 << X0Integral << " thicknessInX0 "
590 << (**m).materialEffects()->thicknessInX0() << " "
591 << *(**m).materialEffects());
592 X0Integral = 1e-6;
593 }
594 const double scattering = X0Integral * logTerm * logTerm;
595 const double angle =
596 m_scatteringConstant * std::sqrt(scattering - previousScattering);
597 previousScattering = scattering;
598 (**m).numberDoF(2);
599 (**m).scatteringAngle(angle, X0Integral);
600 }
601 }
602}
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
@ next
Definition BinningData.h:33
TH1D * integrate(TH1D *hin)
generate an integrated distribution
Definition generate.cxx:68

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interfaceID()

const InterfaceID & Trk::IMaterialAllocator::interfaceID ( )
inlinestaticinherited

AlgTool and IAlgTool interface methods.

Definition at line 46 of file IMaterialAllocator.h.

46{ return IID_IMaterialAllocator; }
static const InterfaceID IID_IMaterialAllocator("IMaterialAllocator", 1, 0)
Interface ID for IMaterialAllocator.

◆ leadingSpectrometerTSOS()

std::vector< const TrackStateOnSurface * > * Trk::MaterialAllocator::leadingSpectrometerTSOS ( const TrackParameters & spectrometerParameters,
Garbage_t & garbage ) const
overridevirtual

IMaterialAllocator interface: material TSOS between spectrometer entrance surface and parameters given in spectrometer.

Implements Trk::IMaterialAllocator.

Definition at line 605 of file MaterialAllocator.cxx.

606 {
607 const EventContext& ctx = Gaudi::Hive::currentContext();
608 const Trk::TrackingVolume* spectrometerEntrance = getSpectrometerEntrance();
609 if (!spectrometerEntrance)
610 return nullptr;
611 // check input parameters are really in the spectrometer
612 if (m_calorimeterVolume->inside(spectrometerParameters.position()))
613 return nullptr;
614
615 std::unique_ptr<const TrackParameters> const entranceParameters(
616 m_extrapolator->extrapolateToVolume(ctx, spectrometerParameters,
617 *spectrometerEntrance, anyDirection,
619 if (!entranceParameters) {
621 std::setiosflags(std::ios::fixed)
622 << "leadingSpectrometerTSOS: no material found from RZ" << std::setw(9)
623 << std::setprecision(3) << spectrometerParameters.position().perp()
624 << std::setw(10) << std::setprecision(3)
625 << spectrometerParameters.position().z() << " with p " << std::setw(8)
626 << std::setprecision(3)
627 << spectrometerParameters.momentum().mag() / Gaudi::Units::GeV);
628 return nullptr;
629 }
630
631 const Surface& entranceSurface = entranceParameters->associatedSurface();
632 std::unique_ptr<const std::vector<const TrackStateOnSurface*>>
633 extrapolatedTSOS(extrapolatedMaterial(
634 m_extrapolator, spectrometerParameters, entranceSurface, anyDirection,
635 false, Trk::muon, garbage));
636
637 if (!extrapolatedTSOS || extrapolatedTSOS->empty() ||
638 !extrapolatedTSOS->front()->trackParameters()) {
640 std::setiosflags(std::ios::fixed)
641 << "leadingSpectrometerTSOS: no material found from RZ" << std::setw(9)
642 << std::setprecision(3) << spectrometerParameters.position().perp()
643 << std::setw(10) << std::setprecision(3)
644 << spectrometerParameters.position().z() << " with p " << std::setw(8)
645 << std::setprecision(3)
646 << spectrometerParameters.momentum().mag() / Gaudi::Units::GeV);
647 return nullptr;
648 }
649
650 std::vector<std::unique_ptr<FitMeasurement>> leadingMeasurements;
651 std::unique_ptr<std::vector<const TrackStateOnSurface*>> leadingTSOS =
652 std::make_unique<std::vector<const TrackStateOnSurface*>>();
653 leadingTSOS->reserve(extrapolatedTSOS->size());
654 double outgoingEnergy = spectrometerParameters.momentum().mag();
655 const double particleMass = Trk::ParticleMasses::mass[Trk::muon];
656 for (const auto* s : *extrapolatedTSOS) {
657 if (!(*s).trackParameters())
658 continue;
659 std::unique_ptr<FitMeasurement> measurement(
660 measurementFromTSOS(*s, outgoingEnergy, particleMass));
661 outgoingEnergy = (*s).trackParameters()->momentum().mag();
662
663 if (measurement) {
664 leadingMeasurements.emplace(leadingMeasurements.begin(),
665 std::move(measurement));
666 } else {
667 leadingTSOS->push_back((*s).clone());
668 }
669 }
670
671 // convert back to TSOS
672 for (const auto& m : leadingMeasurements)
673 leadingTSOS->emplace_back(new TrackStateOnSurface(
674 nullptr, nullptr, m->materialEffects()->uniqueClone()));
675
676 deleteMaterial(extrapolatedTSOS.release(), garbage);
677
678 // debug
679 if (msgLvl(MSG::VERBOSE) && !leadingTSOS->empty()) {
681 std::setiosflags(std::ios::fixed)
682 << "leadingSpectrometerTSOS: from RZ" << std::setw(9)
683 << std::setprecision(3) << spectrometerParameters.position().perp()
684 << std::setw(10) << std::setprecision(3)
685 << spectrometerParameters.position().z() << " with p " << std::setw(8)
686 << std::setprecision(3)
687 << spectrometerParameters.momentum().mag() / Gaudi::Units::GeV);
688 // printMeasurements(leadingMeasurements);
689 }
690 return leadingTSOS.release();
691}
const Trk::TrackingVolume * getSpectrometerEntrance() const
static FitMeasurement * measurementFromTSOS(const TrackStateOnSurface &tsos, double outwardsEnergy, double particleMass)
@ anyDirection

◆ materialAggregation() [1/2]

std::pair< FitMeasurement *, FitMeasurement * > Trk::MaterialAllocator::materialAggregation ( const std::vector< const TrackStateOnSurface * > & material,
std::vector< FitMeasurement * > & measurements,
double particleMass ) const
private

Definition at line 1448 of file MaterialAllocator.cxx.

1451 {
1452 // aggregation possible in indet and MS. Frequent occurrence in MS
1453 ATH_MSG_INFO("segment material aggregation " << material.size());
1454 FitMeasurement* measurement1 = nullptr;
1455 FitMeasurement* measurement2 = nullptr;
1456 if (material.empty())
1457 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1458 measurement2);
1459
1460
1461 int adjacentScatterers = 0;
1462 std::vector<FitMeasurement*> aggregateScatterers;
1463 bool hasReferencePosition = false;
1464 Amg::Vector3D referencePosition;
1465 bool const haveAggregation = false;
1466 // bool makeAggregation = false;
1467 // double maxDistance = 0.;
1468 for (std::vector<const TrackStateOnSurface*>::const_reverse_iterator tsos =
1469 material.rbegin();
1470 tsos != material.rend(); ++tsos) {
1471 if (!(**tsos).trackParameters() || !(**tsos).materialEffectsOnTrack()){
1472 continue;
1473 }
1474 ++adjacentScatterers;
1475 if (!hasReferencePosition) {
1476 referencePosition = Amg::Vector3D((**tsos).trackParameters()->position());
1477 hasReferencePosition = true;
1478 }
1479 const double distance =
1480 ((**tsos).trackParameters()->position() - referencePosition).mag();
1481 const double weight = (**tsos).materialEffectsOnTrack()->thicknessInX0();
1482
1483 ATH_MSG_INFO(" material position " << (**tsos).trackParameters()->position()
1484 << " distance " << distance
1485 << " thickness " << 100. * weight);
1486 }
1487
1488 // if 2 or less selected TSOS: just set scatterers on TSOS
1489 if (adjacentScatterers < 3) {
1490 }
1491
1492 // in case of aggregation: insert aggregateScatterers onto track
1493 if (haveAggregation) {
1494 }
1495
1496 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1497 measurement2);
1498}
#define ATH_MSG_INFO(x)

◆ materialAggregation() [2/2]

void Trk::MaterialAllocator::materialAggregation ( std::vector< FitMeasurement * > & measurements,
double particleMass ) const
private

Definition at line 1500 of file MaterialAllocator.cxx.

1501 {
1502 // Aggregate when at least 2 scatterers exist between delimiter pair.
1503 //
1504 // First loop over measurements to create aggregateScatterer vector.
1505 // This contains any aggregated scatterers along with sparse existing
1506 // scatterers which haven't been aggregated. The remaining existing scatterers
1507 // (those which have been aggregated) are flagged for discard (via the outlier
1508 // flag).
1509
1510 // currently aggregation only performed for MS:
1511 Amg::Vector3D referencePosition =
1512 measurements.back()->intersection(FittedTrajectory).position();
1513 if (m_calorimeterVolume->inside(referencePosition))
1514 return;
1515
1516 Amg::Vector3D referenceDirection =
1517 measurements.back()->intersection(FittedTrajectory).direction();
1518 int adjacentScatterers = 0;
1519 std::vector<FitMeasurement*> aggregateScatterers;
1520 bool haveAggregation = false;
1521 bool makeAggregation = false;
1522 double maxDistance = 0.;
1523 FitMeasurement* measurement1 = nullptr;
1524 FitMeasurement* measurement2 = nullptr;
1525 double totalDistance = 0.;
1526 double totalDistanceSq = 0.;
1527 double totalEnergyDeposit = 0.;
1528 double totalThickness = 0.;
1529 std::vector<FitMeasurement*>::reverse_iterator start;
1530 std::vector<FitMeasurement*>::reverse_iterator previous =
1531 measurements.rbegin();
1532 for (std::vector<FitMeasurement*>::reverse_iterator m = measurements.rbegin();
1533 m != measurements.rend(); ++m) {
1534 if ((**m).isScatterer())
1535 aggregateScatterers.push_back(*m);
1536 if (m_calorimeterVolume->inside((**m).position())) {
1537 if (!adjacentScatterers)
1538 continue;
1539 makeAggregation = true;
1540 }
1541 // if (m_calorimeterVolume->inside((**m).position())
1542 // && ! m_indetVolume->inside((**m).position())) continue;
1543 // look for adjacent scatterers
1544 else if (adjacentScatterers) {
1545 if ((**m).isScatterer()) {
1546 const Amg::Vector3D position =
1547 (**m).intersection(FittedTrajectory).position();
1548 const double distance =
1549 std::abs(referenceDirection.dot(position - referencePosition));
1550 if (distance < maxDistance) {
1551 ++adjacentScatterers;
1552 const double weight = (**m).radiationThickness();
1553 totalDistance += weight * distance;
1554 totalDistanceSq += weight * distance * distance;
1555 totalEnergyDeposit += (**m).energyLoss();
1556 totalThickness += weight;
1557 if (*m == measurements.front())
1558 makeAggregation = true;
1559 // ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
1560 // << " distance "
1561 // << std::setw(8) << std::setprecision(0)
1562 // << distance
1563 // << " adjacentScatterers " << adjacentScatterers );
1564 } else if (adjacentScatterers > 1) {
1565 makeAggregation = true;
1566 } else {
1567 adjacentScatterers = 0;
1568 }
1569 } else if (!(**m).isMaterialDelimiter()) {
1570 previous = m;
1571 continue;
1572 } else if (adjacentScatterers > 1) {
1573 makeAggregation = true;
1574 } else {
1575 adjacentScatterers = 0;
1576 }
1577 }
1578
1579 if (makeAggregation) {
1580 // double dist =
1581 // ((**m).intersection(FittedTrajectory).position() -
1582 // referencePosition).mag();
1583 // ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
1584 // << " makeAggregation: reference R,Z "
1585 // << std::setw(8) << std::setprecision(0)
1586 // << referencePosition.perp()
1587 // << std::setw(8) << std::setprecision(0)
1588 // << referencePosition.z()
1589 // << " current R,Z "
1590 // << std::setw(8) << std::setprecision(0)
1591 // << (**m).intersection(FittedTrajectory).position().perp()
1592 // << std::setw(8) << std::setprecision(0)
1593 // << (**m).intersection(FittedTrajectory).position().z()
1594 // << " adjacentScatterers " << std::setw(2)
1595 // << adjacentScatterers
1596 // << " distance "
1597 // << std::setw(8) << std::setprecision(0)
1598 // << dist );
1599 const double meanDistance = totalDistance / totalThickness;
1600 double rmsDistance = 0.;
1601 const double meanSquare =
1602 totalDistanceSq / totalThickness - meanDistance * meanDistance;
1603 if (meanSquare > 0.)
1604 rmsDistance = std::sqrt(meanSquare);
1605 const double gap = 2. * rmsDistance;
1606 if (adjacentScatterers > 2 || gap < m_scattererMinGap) {
1607 const double distance1 = meanDistance - rmsDistance;
1608 double distance2 = meanDistance + rmsDistance;
1609 if (gap < m_scattererMinGap)
1610 distance2 = meanDistance;
1611 const Amg::Vector3D position =
1612 (**m).intersection(FittedTrajectory).position();
1613 const double distance =
1614 std::abs(referenceDirection.dot(position - referencePosition));
1615 // ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
1616 // << " distance1 "
1617 // << std::setw(8) << std::setprecision(0)
1618 // << distance1
1619 // << " distance2 "
1620 // << std::setw(8) << std::setprecision(0)
1621 // << distance2
1622 // << " distance "
1623 // << std::setw(8) << std::setprecision(0)
1624 // << distance );
1625 if (distance2 > distance || distance1 < 0.) {
1626 // msg() << " distance out of bounds: range " << distance
1627 // << " to " << 0. << endmsg;
1628 } else {
1629 FitMeasurement* after = nullptr;
1630 FitMeasurement* before = *start;
1631 double previousDistance = 0.;
1632 haveAggregation = true;
1633
1634 for (std::vector<Trk::FitMeasurement*>::reverse_iterator s = start;
1635 s != measurements.rend(); ++s) {
1636 if (!(**s).isScatterer())
1637 continue;
1638 Amg::Vector3D position =
1639 (**s).intersection(FittedTrajectory).position();
1640 const double distance =
1641 std::abs(referenceDirection.dot(position - referencePosition));
1642 if (!measurement1 && distance > distance1 &&
1643 gap > m_scattererMinGap) {
1644 after = *s;
1645 const double separation = distance - previousDistance;
1646 const double fractionAfter =
1647 (distance1 - previousDistance) / separation;
1648 const double fractionBefore = (distance - distance1) / separation;
1649 // ATH_MSG_INFO( std::setiosflags(std::ios::fixed)
1650 // << " distance "
1651 // << std::setw(8) << std::setprecision(0)
1652 // << distance<< " fraction before "
1653 // << std::setw(6) << std::setprecision(2)
1654 // << fractionBefore
1655 // << " fraction after "
1656 // << std::setw(6) << std::setprecision(2)
1657 // << fractionAfter );
1658 position = fractionBefore *
1659 before->intersection(FittedTrajectory).position() +
1660 fractionAfter *
1661 after->intersection(FittedTrajectory).position();
1662 const Amg::Vector3D direction =
1663 fractionBefore *
1664 before->intersection(FittedTrajectory).direction() +
1665 fractionAfter *
1666 after->intersection(FittedTrajectory).direction();
1667 const double qOverP = fractionBefore * before->qOverP() +
1668 fractionAfter * after->qOverP();
1669 measurement1 = new FitMeasurement(
1670 0.5 * totalThickness, -0.5 * totalEnergyDeposit, particleMass,
1671 position, direction, qOverP);
1672 }
1673
1674 if (distance > distance2) {
1675 after = *s;
1676 const double separation = distance - previousDistance;
1677 const double fractionAfter =
1678 (distance2 - previousDistance) / separation;
1679 const double fractionBefore = (distance - distance2) / separation;
1680 // ATH_MSG_INFO( std::setiosflags(std::ios::fixed)
1681 // << " distance "
1682 // << std::setw(8) << std::setprecision(0)
1683 // << distance<< " fraction before "
1684 // << std::setw(6) << std::setprecision(2)
1685 // << fractionBefore
1686 // << " fraction after "
1687 // << std::setw(6) << std::setprecision(2)
1688 // << fractionAfter << endmsg );
1689 position = fractionBefore *
1690 before->intersection(FittedTrajectory).position() +
1691 fractionAfter *
1692 after->intersection(FittedTrajectory).position();
1693 const Amg::Vector3D direction =
1694 fractionBefore *
1695 before->intersection(FittedTrajectory).direction() +
1696 fractionAfter *
1697 after->intersection(FittedTrajectory).direction();
1698 const double qOverP = fractionBefore * before->qOverP() +
1699 fractionAfter * after->qOverP();
1700 if (measurement1) {
1701 measurement2 = new FitMeasurement(
1702 0.5 * totalThickness, -0.5 * totalEnergyDeposit,
1703 particleMass, position, direction, qOverP);
1704 } else {
1705 measurement2 = new FitMeasurement(
1706 totalThickness, -totalEnergyDeposit, particleMass, position,
1707 direction, qOverP);
1708 }
1709 bool keepCurrentMeas = false;
1710 if ((**m).isScatterer() && *m != measurements.front()) {
1711 keepCurrentMeas = true;
1712 aggregateScatterers.pop_back();
1713 }
1714 while (adjacentScatterers--) {
1715 aggregateScatterers.back()->setOutlier();
1716 aggregateScatterers.pop_back();
1717 }
1718 if (measurement1)
1719 aggregateScatterers.push_back(measurement1);
1720 if (measurement2)
1721 aggregateScatterers.push_back(measurement2);
1722 if (keepCurrentMeas)
1723 aggregateScatterers.push_back(*m);
1724 measurement1 = nullptr;
1725 measurement2 = nullptr;
1726 break;
1727 }
1728 before = *s;
1729 previousDistance = distance;
1730 }
1731 }
1732 }
1733 adjacentScatterers = 0;
1734 makeAggregation = false;
1735 }
1736
1737 // new candidate for merging
1738 if ((**m).isScatterer() && !adjacentScatterers &&
1739 !m_calorimeterVolume->inside((**m).position())) {
1740 adjacentScatterers = 1;
1741 const double weight = (**m).radiationThickness();
1742 referencePosition =
1743 (**previous).intersection(FittedTrajectory).position();
1744 referenceDirection =
1745 (**previous).intersection(FittedTrajectory).direction();
1746 const Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
1747 const double distance =
1748 std::abs(referenceDirection.dot(position - referencePosition));
1749 maxDistance = distance + 2. * Gaudi::Units::meter;
1750 start = m;
1751 totalDistance = weight * distance;
1752 totalDistanceSq = weight * distance * distance;
1753 totalEnergyDeposit = (**m).energyLoss();
1754 totalThickness = weight;
1755 // ATH_MSG_INFO(std::setiosflags(std::ios::fixed)
1756 // << " distance "
1757 // << std::setw(8) << std::setprecision(0)
1758 // << distance
1759 // << " adjacentScatterers " << adjacentScatterers );
1760 }
1761 previous = m;
1762 }
1763
1764 // avoid possible leak
1765 delete measurement1;
1766 // delete measurement2; // redundant!
1767
1768 // in case of aggregation: insert the aggregateScatterers into the measurement
1769 // list (second loop over measurements)
1770 if (haveAggregation) {
1771 referencePosition =
1772 measurements.back()->intersection(FittedTrajectory).position();
1773 referenceDirection =
1774 (referencePosition -
1775 measurements.front()->intersection(FittedTrajectory).position())
1776 .unit();
1777 std::vector<Trk::FitMeasurement*>::reverse_iterator s =
1778 aggregateScatterers.rbegin();
1779 Amg::Vector3D scattererPosition =
1780 (**s).intersection(FittedTrajectory).position();
1781 double scattererDistance =
1782 std::abs(referenceDirection.dot(scattererPosition - referencePosition));
1783 for (std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1784 m != measurements.end(); ) {
1785 // insert scatterers from aggregrate vector
1786 const Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
1787 const double distance =
1788 std::abs(referenceDirection.dot(position - referencePosition));
1789 while (distance <= scattererDistance && s != aggregateScatterers.rend()) {
1790 m = measurements.insert(m, *s);
1791 ++m;
1792 if (++s != aggregateScatterers.rend()) {
1793 scattererPosition = (**s).intersection(FittedTrajectory).position();
1794 scattererDistance = std::abs(
1795 referenceDirection.dot(scattererPosition - referencePosition));
1796 }
1797 }
1798 if ((**m).isScatterer()) {
1799 // delete the scatterer if it has been aggregated
1800 if ((**m).isOutlier())
1801 delete *m;
1802 // in any case it must be removed from the list to avoid double counting
1803 m = measurements.erase(m);
1804 }
1805 else {
1806 ++m;
1807 }
1808 }
1809 }
1810
1811 // verbose table of fit measurements including material
1812 if (msgLvl(MSG::VERBOSE)) {
1813 ATH_MSG_VERBOSE(" finished material aggregation: ");
1814 int n = 0;
1815 const Amg::Vector3D startPosition =
1816 measurements.front()->intersection(FittedTrajectory).position();
1817 const Amg::Vector3D startDirection =
1818 measurements.front()->intersection(FittedTrajectory).direction();
1819 for (auto* measurement : measurements) {
1820 const Amg::Vector3D position =
1821 (*measurement).intersection(FittedTrajectory).position();
1822 const double distance = std::abs(startDirection.dot(position - startPosition));
1823 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1824 << ++n << std::setw(10) << std::setprecision(3)
1825 << distance << " " << (*measurement).type();
1826 if ((*measurement).isOutlier()) {
1827 msg() << " outlier ";
1828 } else if ((*measurement).materialEffects()) {
1829 msg() << std::setw(8) << std::setprecision(3)
1830 << (*measurement).materialEffects()->thicknessInX0() << " ";
1831 } else {
1832 msg() << " ";
1833 }
1834 if (!(*measurement).isMaterialDelimiter()) {
1835 msg() << std::setw(10) << std::setprecision(1)
1836 << (*measurement).position().perp() << std::setw(9)
1837 << std::setprecision(4) << (*measurement).position().phi()
1838 << std::setw(10) << std::setprecision(1)
1839 << (*measurement).position().z();
1840 }
1841 msg() << endmsg;
1842 }
1843 }
1844
1845 // loops to erase material delimiters and set energy gain when appropriate
1846 bool energyGain = false;
1847 for (auto& measurement : measurements) {
1848 if ((*measurement).materialEffects() && (*measurement).numberDoF() &&
1849 (*measurement).energyLoss() < 0.)
1850 energyGain = true;
1851 }
1852
1853 if (energyGain) {
1854 for (auto& measurement : measurements) {
1855 if ((*measurement).materialEffects())
1856 (*measurement).setEnergyGain();
1857 }
1858 }
1859}
#define endmsg
MsgStream & msg() const
float distance2(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the squared distance between two point in 3D space
gap(flags, cells_name, *args, **kw)

◆ measurementFromTSOS()

FitMeasurement * Trk::MaterialAllocator::measurementFromTSOS ( const TrackStateOnSurface & tsos,
double outwardsEnergy,
double particleMass )
staticprivate

Definition at line 1861 of file MaterialAllocator.cxx.

1863 {
1864 if (!tsos.trackParameters() || !tsos.materialEffectsOnTrack())
1865 return nullptr;
1866
1867 const double deltaE = outgoingEnergy - tsos.trackParameters()->momentum().mag();
1868 const double thicknessInX0 = tsos.materialEffectsOnTrack()->thicknessInX0();
1869 const Amg::Vector3D position = tsos.trackParameters()->position();
1870 const Amg::Vector3D direction = tsos.trackParameters()->momentum().unit();
1871 double qOverP = 1. / outgoingEnergy;
1872 if (tsos.trackParameters()->charge() < 0)
1873 qOverP = -qOverP;
1874
1875 return new FitMeasurement(thicknessInX0, deltaE, particleMass, position,
1876 direction, qOverP);
1877}

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ orderMeasurements()

void Trk::MaterialAllocator::orderMeasurements ( std::vector< FitMeasurement * > & measurements,
Amg::Vector3D startDirection,
Amg::Vector3D startPosition ) const
overridevirtual

IMaterialAllocator interface: clear temporary TSOS.

Implements Trk::IMaterialAllocator.

Definition at line 693 of file MaterialAllocator.cxx.

695 {
696 // order measurements
697 ATH_MSG_VERBOSE(" measurement ordering with startDirection phi "
698 << startDirection.phi() << " theta "
699 << startDirection.theta());
700
701 // note: preserve original order for close double measurements (such as
702 // crossed eta/phi)
703 double previousDistance = -m_orderingTolerance;
704 std::vector<std::pair<double, FitMeasurement*>> measurementOrder;
705 std::vector<std::pair<double, FitMeasurement*>> originalOrder;
706 for (auto* measurement : measurements) {
707 double distance = startDirection.dot(
708 (*measurement).intersection(FittedTrajectory).position() -
709 startPosition);
710 if (distance < previousDistance)
712 previousDistance = distance - m_orderingTolerance;
713 measurementOrder.emplace_back(distance, measurement);
714 originalOrder.emplace_back(distance, measurement);
715 }
716 std::sort(measurementOrder.begin(), measurementOrder.end(),
718 std::vector<std::pair<double, FitMeasurement*>>::const_iterator orig =
719 originalOrder.begin();
720 bool shouldReorder = false;
722 measurements.erase(measurements.begin(), measurements.end());
723
724 for (std::vector<std::pair<double, FitMeasurement*>>::const_iterator order =
725 measurementOrder.begin();
726 order != measurementOrder.end(); ++order, ++orig) {
727 if (m_allowReordering) {
728 measurements.push_back((*order).second);
729 }
730
731 // signal if reordering would help
732 // FIXME add tolerance
733 if ((*order).second == (*orig).second ||
734 std::abs((*order).first - (*orig).first) < m_orderingTolerance)
735 continue;
736 shouldReorder = true;
737 // ATH_MSG_INFO( " reorder distance " << (*order).first - (*orig).first );
738 }
739
740 if (shouldReorder) {
741 if (m_allowReordering) {
742 ATH_MSG_DEBUG(" measurements have been reordered ");
743 } else {
744 ATH_MSG_DEBUG(" measurement reordering would improve the track fit ");
745 }
746 }
747}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ printMeasurements()

void Trk::MaterialAllocator::printMeasurements ( std::vector< FitMeasurement * > & measurements) const
private

Definition at line 1879 of file MaterialAllocator.cxx.

1880 {
1882 "measurements and material: distance X0 deltaE E "
1883 " pT"
1884 << " R phi Z DoF phi theta");
1885
1886 if (measurements.empty())
1887 return;
1888
1889 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1890 while (m != measurements.end() && !(**m).isPositionMeasurement())
1891 ++m;
1892 if (m == measurements.end())
1893 m = measurements.begin();
1894
1895 const Amg::Vector3D direction = (**m).intersection(FittedTrajectory).direction();
1896 const Amg::Vector3D startPosition = (**m).intersection(FittedTrajectory).position();
1897 int scatterers = 0;
1898 int leadingMaterial = 0;
1899 double leadingX0 = 0.;
1900 double sumX0 = 0.;
1901 double leadingELoss = 0.;
1902 double sumELoss = 0.;
1903 int n = 0;
1904 for (auto& measurement : measurements) {
1905 const double distance =
1906 direction.dot((*measurement).intersection(FittedTrajectory).position() -
1907 startPosition);
1908 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1909 << ++n << " " << (*measurement).type() << std::setw(11)
1910 << std::setprecision(3) << distance;
1911 if ((*measurement).isOutlier()) {
1912 msg() << " outlier " << std::setw(44);
1913 } else if ((*measurement).materialEffects()) {
1914 double deltaE = 0.;
1915 const MaterialEffectsOnTrack* materialEffects =
1916 dynamic_cast<const MaterialEffectsOnTrack*>(
1917 (*measurement).materialEffects());
1918 if (materialEffects && materialEffects->energyLoss())
1919 deltaE = materialEffects->energyLoss()->deltaE();
1920 if ((*measurement).isEnergyDeposit())
1921 deltaE = -deltaE;
1922 msg() << std::setw(10) << std::setprecision(3)
1923 << (*measurement).materialEffects()->thicknessInX0() << std::setw(9)
1924 << std::setprecision(1) << deltaE << " ";
1925 if (distance > 0.) {
1926 ++scatterers;
1927 sumX0 += (*measurement).materialEffects()->thicknessInX0();
1928 sumELoss -= deltaE;
1929 } else {
1930 ++leadingMaterial;
1931 leadingX0 += (*measurement).materialEffects()->thicknessInX0();
1932 leadingELoss -= deltaE;
1933 }
1934
1935 if ((*measurement).qOverP()) {
1936 msg() << std::setw(11) << std::setprecision(4)
1937 << 1. / std::abs((*measurement).qOverP() * Gaudi::Units::GeV)
1938 << std::setw(10) << std::setprecision(3)
1939 << (*measurement)
1940 .intersection(FittedTrajectory)
1941 .direction()
1942 .perp() /
1943 ((*measurement).qOverP() * Gaudi::Units::GeV)
1944 << std::setw(12);
1945 }
1946 } else {
1947 msg() << std::setw(54);
1948 }
1949 if ((*measurement).isMaterialDelimiter()) {
1950 msg() << std::setprecision(1)
1951 << (*measurement).intersection(FittedTrajectory).position().perp()
1952 << std::setw(9) << std::setprecision(4)
1953 << (*measurement).intersection(FittedTrajectory).position().phi()
1954 << std::setw(10) << std::setprecision(1)
1955 << (*measurement).intersection(FittedTrajectory).position().z()
1956 << std::setw(14) << std::setprecision(4)
1957 << (*measurement).intersection(FittedTrajectory).direction().phi()
1958 << std::setw(9) << std::setprecision(4)
1959 << (*measurement).intersection(FittedTrajectory).direction().theta()
1960 << endmsg;
1961 } else {
1962 msg() << std::setprecision(1) << (*measurement).position().perp()
1963 << std::setw(9) << std::setprecision(4)
1964 << (*measurement).position().phi() << std::setw(10)
1965 << std::setprecision(1) << (*measurement).position().z()
1966 << std::setw(5) << (*measurement).numberDoF() << endmsg;
1967 }
1968 }
1969
1970 // fix counting at allocation stage
1971 if (!scatterers) {
1972 scatterers = leadingMaterial;
1973 leadingMaterial = 0;
1974 }
1975
1977 " material: "
1978 << scatterers << " (" << leadingMaterial
1979 << ") fitted scattering centres (leading material centres) giving "
1980 << std::setiosflags(std::ios::fixed) << std::setw(8)
1981 << std::setprecision(3) << sumX0 << " (" << std::setw(8)
1982 << std::setprecision(3) << leadingX0 << ")"
1983 << " X0 and " << std::setw(8) << std::setprecision(3)
1984 << sumELoss / Gaudi::Units::GeV << " (" << std::setw(8)
1985 << std::setprecision(3) << leadingELoss / Gaudi::Units::GeV << ")"
1986 << " GeV Eloss");
1987}

◆ reallocateMaterial()

bool Trk::MaterialAllocator::reallocateMaterial ( std::vector< FitMeasurement * > & measurements,
FitParameters & fitParameters,
Garbage_t & garbage ) const
overridevirtual

IMaterialAllocator interface: has material been reallocated?

Implements Trk::IMaterialAllocator.

Definition at line 749 of file MaterialAllocator.cxx.

751 {
752 ATH_MSG_DEBUG(" reallocateSpectrometerMaterial ");
753
754 int n = 0;
755 for (auto& measurement : measurements) {
756 if (!(*measurement).isMaterialDelimiter())
757 continue;
758
759 const double distance =
760 ((*measurement).intersection(FittedTrajectory).position() -
761 (*measurement).position())
762 .mag();
764 std::setiosflags(std::ios::fixed)
765 << std::setw(5) << ++n << std::setw(10) << std::setprecision(3)
766 << distance << " " << (*measurement).type() << std::setw(10)
767 << std::setprecision(1)
768 << (*measurement).intersection(FittedTrajectory).position().perp()
769 << std::setw(9) << std::setprecision(4)
770 << (*measurement).intersection(FittedTrajectory).position().phi()
771 << std::setw(10) << std::setprecision(1)
772 << (*measurement).intersection(FittedTrajectory).position().z());
773 }
774
775 // put iterator at MS entrance
776 double qOverP = 0;
777 ATH_MSG_INFO("qOverP " << qOverP);
778
779 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
780 for (; m != measurements.end(); ++m) {
781 if (m_calorimeterVolume->inside((**m).position())) {
782 // save qOverP for following use with spectrometer
783 if ((**m).materialEffects())
784 qOverP = (**m).qOverP();
785 if ((**m).isMaterialDelimiter())
786 ATH_MSG_INFO(" at material delimiter");
787 ATH_MSG_INFO("qOverP " << qOverP);
788 } else {
789 if ((**m).isMaterialDelimiter())
790 ATH_MSG_INFO(" at material delimiter");
791 break;
792 }
793 }
794
795 // allocate material from outside inwards
797 MsgStream log(msgSvc(), name());
798 const TrackParameters* trackParameters =
799 parameters.trackParameters(log, *measurements.back());
800
801 // protect the momentum to avoid excessive Eloss
802 Amg::VectorX parameterVector = trackParameters->parameters();
803 const double Emax = 50000.;
804 if (parameterVector[Trk::qOverP] == 0.) {
805 parameterVector[Trk::qOverP] = 1. / Emax;
806 } else {
807 if (std::abs(parameterVector[Trk::qOverP]) * Emax < 1)
808 parameterVector[Trk::qOverP] = trackParameters->charge() / Emax;
809 }
810
811 // correct track parameters for high momentum track (otherwise Eloss is too
812 // large)
813 trackParameters =
814 (trackParameters->associatedSurface())
815 .createUniqueTrackParameters(
816 parameterVector[Trk::loc1], parameterVector[Trk::loc2],
817 parameterVector[Trk::phi], parameterVector[Trk::theta],
818 parameterVector[Trk::qOverP], std::nullopt)
819 .release();
820
821 for (std::vector<Trk::FitMeasurement*>::reverse_iterator r =
822 measurements.rbegin();
823 r != measurements.rend(); ++r) {
824 if (!(**r).isMaterialDelimiter())
825 continue;
826 const std::vector<const TrackStateOnSurface*>* spectrometerMaterial =
827 extrapolatedMaterial(m_extrapolator, *trackParameters, *(**r).surface(),
828 oppositeMomentum, false, Trk::muon, garbage);
829
831 // for (std::vector<const
832 // TrackStateOnSurface*>::const_reverse_iterator s =
833 // spectrometerMaterial->rbegin();
834 // s != spectrometerMaterial->rend();
835 // ++s)
836 // {
837 // if (! (**s).trackParameters() || ! (**s).materialEffectsOnTrack())
838 // continue; ATH_MSG_INFO( " material " <<
839 // (**s).trackParameters()->position() );
840 // }
841
842 std::pair<FitMeasurement*, FitMeasurement*> const fms =
843 materialAggregation(*spectrometerMaterial, measurements, mass);
844 delete fms.first;
845 delete fms.second;
846 // ATH_MSG_INFO( " delete TSOS " );
847
848 for (const auto* s : *spectrometerMaterial)
849 delete s;
850 }
851 // ATH_MSG_INFO( " delete material " );
853 delete trackParameters;
854
855 MsgStream log(msgSvc(), name());
856 trackParameters = parameters.trackParameters(log, **r);
857 }
858
859 delete trackParameters;
860
861 // erase materialDelimiters
862 for (m = measurements.begin(); m != measurements.end(); ++m) {
863 if (!(**m).isMaterialDelimiter())
864 continue;
865 delete *m;
866 std::vector<Trk::FitMeasurement*>::iterator const n = m;
867 --m;
868 measurements.erase(n);
869 }
870
871 return true;
872}
std::pair< FitMeasurement *, FitMeasurement * > materialAggregation(const std::vector< const TrackStateOnSurface * > &material, std::vector< FitMeasurement * > &measurements, double particleMass) const
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
@ theta
Definition ParamDefs.h:66
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ phi
Definition ParamDefs.h:75
@ loc1
Definition ParamDefs.h:34

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ spectrometerMaterial()

void Trk::MaterialAllocator::spectrometerMaterial ( std::vector< FitMeasurement * > & measurements,
ParticleHypothesis particleHypothesis,
FitParameters & fitParameters,
const TrackParameters & startParameters,
Garbage_t & garbage ) const
private

Definition at line 1989 of file MaterialAllocator.cxx.

1992 {
1993 const EventContext& ctx = Gaudi::Hive::currentContext();
1994 // return if no MS measurement
1995 if (m_calorimeterVolume->inside(measurements.back()->position()))
1996 return;
1997
1998 // check that the spectrometer measurements are ordered and that material
1999 // allocation is required
2000 Amg::Vector3D startDirection = startParameters.momentum().unit();
2001 Amg::Vector3D startPosition = startParameters.position();
2002 bool haveMaterial = false;
2003 bool haveLeadingMaterial = false;
2004 bool reorderMS = false;
2005 bool reorderID = false;
2006 bool firstMSHit = false;
2007 double previousDistance = 0.;
2008 double previousDistanceR = 0.;
2009 double previousDistanceZ = 0.;
2010 double minDistanceID = 0.;
2011 double minDistanceMS = 0.;
2012 double minRDistanceMS = 0.;
2013 double minZDistanceMS = 0.;
2014 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
2015 for (; m != measurements.end(); ++m) {
2016 const Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
2017 const Amg::Vector3D positionSurf = (**m).surface()->center();
2018 Amg::Vector3D positionMst = startPosition;
2019 if ((**m).measurementBase())
2020 positionMst = (**m).measurementBase()->globalPosition();
2021 const double distance = startDirection.dot(position - startPosition);
2022 const double distanceR = std::hypot(positionMst.x() - startPosition.x(),
2023 positionMst.y() - startPosition.y());
2024 double distanceZ = (positionMst.z() - startPosition.z());
2025 if (startDirection.z() < 0)
2026 distanceZ = -distanceZ;
2027 if (!m_calorimeterVolume->inside(position) ||
2028 !m_calorimeterVolume->inside(positionSurf)) {
2029 if (distance - previousDistance < -m_orderingTolerance) {
2030 reorderMS = true;
2031 if (distance - previousDistance < minDistanceMS) {
2032 minDistanceMS = distance - previousDistance;
2033 minRDistanceMS = distanceR - previousDistanceR;
2034 minZDistanceMS = distanceZ - previousDistanceZ;
2035 }
2036 }
2037 if ((**m).isScatterer())
2038 haveMaterial = true;
2039 if ((**m).measurementBase() && !firstMSHit) {
2040 firstMSHit = true;
2041 }
2042 if ((**m).isScatterer() && !firstMSHit)
2043 haveLeadingMaterial = true;
2044 } else {
2045 if (distance - previousDistance < -m_orderingTolerance) {
2046 reorderID = true;
2047 if (distance - previousDistance < minDistanceID)
2048 minDistanceID = distance - previousDistance;
2049 }
2050 }
2051 previousDistance = distance;
2052 previousDistanceZ = distanceZ;
2053 previousDistanceR = distanceR;
2054 }
2055
2056 if (reorderMS && (minRDistanceMS > -m_orderingTolerance ||
2057 minZDistanceMS > -m_orderingTolerance)) {
2058 // 3D distance of the intersection is problematic but the R or Z distance
2059 // of the measurementBase is fine we should not reorder
2060
2061 reorderMS = false;
2062 }
2063
2064 // if(!m_allowReordering) {
2065 if (reorderMS && fabs(minDistanceMS) > -2.)
2066 ATH_MSG_DEBUG(" reorder MS part of track with minimum distance "
2067 << minDistanceMS << " minRDistanceMS " << minRDistanceMS
2068 << " minZDistanceMS " << minZDistanceMS);
2069 if (reorderID && fabs(minDistanceID) > -2.)
2070 ATH_MSG_DEBUG(" reorder ID part of track with minimum distance "
2071 << minDistanceID);
2072 // }
2073
2074 if (reorderMS || reorderID) {
2075 if (msgLvl(MSG::DEBUG))
2076 printMeasurements(measurements);
2077 }
2078
2079 if (!haveLeadingMaterial && haveMaterial) {
2081 " MS part of track has no leading material in front of first MS hit ");
2082 }
2083
2084 if (reorderMS)
2085 orderMeasurements(measurements, startDirection, startPosition);
2086
2087 // nothing to do if spectrometer material already exists
2088 if (haveMaterial)
2089 return;
2090
2092 " spectrometerMaterial: ALARM no material found on track can happen for "
2093 "MuGirl");
2094
2095 // material has to be added: need inner and outer TrackParameters
2096 FitMeasurement* innerMeasurement = nullptr;
2097 FitMeasurement* outerMeasurement = nullptr;
2098 for (m = measurements.begin(); m != measurements.end(); ++m) {
2099 if (!(**m).isPositionMeasurement() || (**m).isOutlier())
2100 continue;
2101 const Amg::Vector3D position = (**m).intersection(FittedTrajectory).position();
2102 if (m_calorimeterVolume->inside(position))
2103 continue;
2104 if (innerMeasurement) {
2105 outerMeasurement = *m;
2106 } else {
2107 innerMeasurement = *m;
2108 }
2109 }
2110 if (!outerMeasurement)
2111 return;
2112
2113 // insert delimiters
2114 addSpectrometerDelimiters(measurements);
2115
2116 const Trk::TrackingVolume* spectrometerEntrance = getSpectrometerEntrance();
2117 if (!spectrometerEntrance)
2118 return;
2119
2120 // entranceParameters are at the MS entrance surface (0 if perigee downstream)
2121 TrackSurfaceIntersection* entranceIntersection = nullptr;
2122 std::unique_ptr<const TrackParameters> entranceParameters;
2123 MsgStream log(msgSvc(), name());
2124 if (m_calorimeterVolume->inside(startParameters.position())) {
2125 std::unique_ptr<const TrackParameters> innerParameters(
2126 fitParameters.trackParameters(log, *innerMeasurement, false));
2127 if (!innerParameters)
2128 innerParameters.reset(startParameters.clone());
2129 entranceParameters = m_extrapolator->extrapolateToVolume(
2130 ctx, *innerParameters, *spectrometerEntrance, anyDirection,
2132 if (entranceParameters) {
2133 startDirection = entranceParameters->momentum().unit();
2134 startPosition = entranceParameters->position();
2135 entranceIntersection = new TrackSurfaceIntersection(
2136 entranceParameters->position(), entranceParameters->momentum().unit(),
2137 0.);
2138 std::vector<Trk::FitMeasurement*>::iterator e = measurements.begin();
2139 FitMeasurement* entranceDelimiter =
2140 new FitMeasurement(*entranceIntersection, 0.);
2141 for (m = measurements.begin(); m != measurements.end(); ++m) {
2142 if (!m_calorimeterVolume->inside((**m).position()))
2143 break;
2144 e = m;
2145 }
2146
2147 // insert a material delimiter at the start of the spectrometer (or at
2148 // perigee if in MS)
2149 e = measurements.insert(++e, entranceDelimiter);
2150 delete entranceIntersection;
2151 } else {
2152 // did not find MS entrance surface - no MS material taken into account
2153 // m_messageHelper->printWarning(3); ATLASRECTS-7528
2154 return;
2155 }
2156 }
2157
2158 // insert a material delimiter after the last measurement (endParameters)
2159 std::unique_ptr<const TrackParameters> outerParameters(
2160 fitParameters.trackParameters(log, *outerMeasurement, false));
2161 if (!outerParameters)
2162 outerParameters.reset(startParameters.clone());
2163 const Surface& endSurface = *measurements.back()->surface();
2164 std::unique_ptr<const TrackParameters> endParameters(
2165 m_extrapolator->extrapolate(ctx, *outerParameters, endSurface,
2166 anyDirection, false, particleHypothesis));
2167
2168 if (!endParameters) {
2169 endParameters =
2170 m_extrapolator->extrapolate(ctx, *outerParameters, endSurface,
2172
2173 if (!endParameters) {
2174 // failed extrapolation
2175 m_messageHelper->printWarning(4);
2176 endParameters = std::move(outerParameters);
2177 }
2178 }
2179 // insert delimiter
2180 const TrackSurfaceIntersection endIntersection(
2181 endParameters->position(), endParameters->momentum().unit(), 0.);
2182 FitMeasurement* endBreak =
2183 new FitMeasurement(endIntersection, 20. * Gaudi::Units::mm);
2184 measurements.push_back(endBreak);
2185
2186 const double endSpectrometerDistance = startDirection.dot(
2187 measurements.back()->intersection(FittedTrajectory).position() -
2188 startPosition);
2189 const std::vector<const TrackStateOnSurface*>* spectrometerMaterial = nullptr;
2190
2191 // protect the momentum to avoid excessive Eloss
2192
2193 Amg::VectorX parameterVector = endParameters->parameters();
2194 const double Emax = 50000.;
2195 if (parameterVector[Trk::qOverP] == 0.) {
2196 parameterVector[Trk::qOverP] = 1. / Emax;
2197 } else {
2198 if (std::abs(parameterVector[Trk::qOverP]) * Emax < 1)
2199 parameterVector[Trk::qOverP] = endParameters->charge() / Emax;
2200 }
2201
2202 // correct track parameters for high momentum track (otherwise Eloss is too
2203 // large)
2204 endParameters =
2205 endParameters->associatedSurface().createUniqueTrackParameters(
2206 parameterVector[Trk::loc1], parameterVector[Trk::loc2],
2207 parameterVector[Trk::phi], parameterVector[Trk::theta],
2208 parameterVector[Trk::qOverP], std::nullopt);
2209
2210 if (entranceParameters) {
2211 const Surface& entranceSurface = entranceParameters->associatedSurface();
2213 extrapolatedMaterial(m_extrapolator, *endParameters, entranceSurface,
2214 anyDirection, false, Trk::muon, garbage);
2215 } else {
2216 const Surface& entranceSurface = startParameters.associatedSurface();
2218 extrapolatedMaterial(m_extrapolator, *endParameters, entranceSurface,
2219 anyDirection, false, Trk::muon, garbage);
2220 }
2221
2222 // debug
2223 if (msgLvl(MSG::VERBOSE) && spectrometerMaterial &&
2224 !spectrometerMaterial->empty()) {
2225 ATH_MSG_VERBOSE(" spectrometerMaterial: "
2226 << "using extrapolateM inwards from outermost measurement");
2227 double p1 = 0.;
2228 if (spectrometerMaterial->front()->trackParameters())
2229 p1 = spectrometerMaterial->front()->trackParameters()->momentum().mag();
2230 for (const auto* ss : *spectrometerMaterial) {
2231 if (!(*ss).trackParameters() || !(*ss).materialEffectsOnTrack())
2232 continue;
2233 const double distance = startDirection.dot((*ss).trackParameters()->position() -
2234 startPosition);
2235 double deltaE = 0.;
2236 const double thickness = (*ss).materialEffectsOnTrack()->thicknessInX0();
2237 const MaterialEffectsOnTrack* materialEffects =
2238 dynamic_cast<const MaterialEffectsOnTrack*>(
2239 (*ss).materialEffectsOnTrack());
2240 if (materialEffects && materialEffects->energyLoss())
2241 deltaE = materialEffects->energyLoss()->deltaE();
2242 const double p2 = (*ss).trackParameters()->momentum().mag();
2244 std::setiosflags(std::ios::fixed)
2245 << " material: RZ" << std::setw(9) << std::setprecision(3)
2246 << (*ss).trackParameters()->position().perp() << std::setw(10)
2247 << std::setprecision(3) << (*ss).trackParameters()->position().z()
2248 << " distance " << std::setw(10) << std::setprecision(3) << distance
2249 << " pt " << std::setw(8) << std::setprecision(3)
2250 << (*ss).trackParameters()->momentum().perp() / Gaudi::Units::GeV
2251 << " X0thickness " << std::setw(8) << std::setprecision(4)
2252 << thickness << " deltaE " << std::setw(8) << std::setprecision(4)
2253 << deltaE << " diffP " << std::setw(8) << std::setprecision(4)
2254 << p2 - p1);
2255 p1 = p2;
2256 }
2257 }
2258
2259 // insert the material into the measurement list
2260 if (!spectrometerMaterial || spectrometerMaterial->empty()) {
2261 // m_messageHelper->printWarning(5);
2262 // Suppressing, as discussed in ATLASRECTS-7515, but keeping this here to remind us
2263 // to investigate it properly.
2264 delete spectrometerMaterial;
2265 spectrometerMaterial = nullptr;
2266 } else {
2267 std::vector<const TrackStateOnSurface*>::const_reverse_iterator s =
2268 spectrometerMaterial->rbegin();
2269 std::vector<FitMeasurement*> material;
2270 const double particleMass = Trk::ParticleMasses::mass[particleHypothesis];
2271 material.reserve(spectrometerMaterial->size());
2272 std::vector<FitMeasurement*>::iterator m = measurements.begin();
2273 for (; s != spectrometerMaterial->rend();) {
2274 const TrackStateOnSurface& tsos = **s;
2275 while (++s != spectrometerMaterial->rend() && !(**s).trackParameters())
2276 ;
2277
2278 double outgoingEnergy = 0.;
2279 if (s != spectrometerMaterial->rend()) {
2280 outgoingEnergy = (**s).trackParameters()->momentum().mag();
2281 } else {
2282 outgoingEnergy = endParameters->momentum().mag();
2283 }
2284
2285 FitMeasurement* measurement =
2286 measurementFromTSOS(tsos, outgoingEnergy, particleMass);
2287 if (!measurement)
2288 continue;
2289
2290 // insert next to adjacent measurement
2291 material.push_back(measurement);
2292 const double distance = startDirection.dot(tsos.trackParameters()->position() -
2293 startPosition);
2294 if (distance > endSpectrometerDistance) {
2295 delete measurement;
2296 break;
2297 }
2298 while (m != measurements.end() &&
2299 distance > startDirection.dot(
2300 (**m).intersection(FittedTrajectory).position() -
2301 startPosition)) {
2302 ++m;
2303 }
2304 if (m == measurements.end()) {
2305 delete measurement;
2306 break;
2307 }
2308
2309 m = measurements.insert(m, material.back());
2310 }
2311 }
2312
2313 // // check sign and order here
2314 // printMeasurements(measurements);
2315
2316 // memory management
2317 ATH_MSG_VERBOSE(" spectrometer: mem management");
2319
2320 materialAggregation(measurements,
2321 Trk::ParticleMasses::mass[particleHypothesis]);
2322}
static Double_t ss
void addSpectrometerDelimiters(std::vector< FitMeasurement * > &measurements) const
virtual void orderMeasurements(std::vector< FitMeasurement * > &measurements, Amg::Vector3D startDirection, Amg::Vector3D startPosition) const override
IMaterialAllocator interface: clear temporary TSOS.

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_aggregateMaterial

bool Trk::MaterialAllocator::m_aggregateMaterial
private

Definition at line 174 of file MaterialAllocator.h.

◆ m_allowReordering

bool Trk::MaterialAllocator::m_allowReordering
private

Definition at line 175 of file MaterialAllocator.h.

◆ m_calorimeterVolume

const Trk::Volume* Trk::MaterialAllocator::m_calorimeterVolume
private

Definition at line 189 of file MaterialAllocator.h.

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_extrapolator

ToolHandle<IExtrapolator> Trk::MaterialAllocator::m_extrapolator
private
Initial value:
{
this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator", ""}

Definition at line 141 of file MaterialAllocator.h.

141 {
142 this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator", ""};

◆ m_indetVolume

const Trk::Volume* Trk::MaterialAllocator::m_indetVolume
private

Definition at line 190 of file MaterialAllocator.h.

◆ m_intersector

ToolHandle<IIntersector> Trk::MaterialAllocator::m_intersector
private
Initial value:
{
this, "Intersector", "Trk::RungeKuttaIntersector/RungeKuttaIntersector",
""}

Definition at line 143 of file MaterialAllocator.h.

143 {
144 this, "Intersector", "Trk::RungeKuttaIntersector/RungeKuttaIntersector",
145 ""};

◆ m_maxWarnings

unsigned Trk::MaterialAllocator::m_maxWarnings
private

Definition at line 177 of file MaterialAllocator.h.

◆ m_messageHelper

std::unique_ptr<MessageHelper> Trk::MaterialAllocator::m_messageHelper
private

Definition at line 195 of file MaterialAllocator.h.

◆ m_orderingTolerance

double Trk::MaterialAllocator::m_orderingTolerance
private

Definition at line 181 of file MaterialAllocator.h.

◆ m_scattererMinGap

double Trk::MaterialAllocator::m_scattererMinGap
private

Definition at line 182 of file MaterialAllocator.h.

◆ m_scatteringConstant

double Trk::MaterialAllocator::m_scatteringConstant
private

Definition at line 183 of file MaterialAllocator.h.

◆ m_scatteringLogCoeff

double Trk::MaterialAllocator::m_scatteringLogCoeff
private

Definition at line 184 of file MaterialAllocator.h.

◆ m_sectorMaxPhi

double Trk::MaterialAllocator::m_sectorMaxPhi
private

Definition at line 185 of file MaterialAllocator.h.

◆ m_stationMaxGap

double Trk::MaterialAllocator::m_stationMaxGap
private

Definition at line 186 of file MaterialAllocator.h.

◆ m_stepField

Trk::MagneticFieldProperties Trk::MaterialAllocator::m_stepField
private

Definition at line 192 of file MaterialAllocator.h.

◆ m_stepPropagator

ToolHandle<IPropagator> Trk::MaterialAllocator::m_stepPropagator
private
Initial value:
{
this, "STEP_Propagator", "Trk::STEP_Propagator/AtlasSTEP_Propagator", ""}

Definition at line 151 of file MaterialAllocator.h.

151 {
152 this, "STEP_Propagator", "Trk::STEP_Propagator/AtlasSTEP_Propagator", ""};

◆ m_trackingGeometryReadKey

SG::ReadCondHandleKey<TrackingGeometry> Trk::MaterialAllocator::m_trackingGeometryReadKey
private
Initial value:
{
this, "TrackingGeometryReadKey", "AtlasTrackingGeometry",
"Key of the TrackingGeometry conditions data."}

Definition at line 154 of file MaterialAllocator.h.

154 {
155 this, "TrackingGeometryReadKey", "AtlasTrackingGeometry",
156 "Key of the TrackingGeometry conditions data."};

◆ m_trackingGeometrySvc

ServiceHandle<ITrackingGeometrySvc> Trk::MaterialAllocator::m_trackingGeometrySvc
private
Initial value:
{
this, "TrackingGeometrySvc","", ""}

Definition at line 146 of file MaterialAllocator.h.

146 {
147 this, "TrackingGeometrySvc","", ""};

◆ m_trackingVolumesSvc

ServiceHandle<ITrackingVolumesSvc> Trk::MaterialAllocator::m_trackingVolumesSvc
private
Initial value:
{
this, "TrackingVolumesSvc", "Trk::TrackingVolumesSvc/TrackingVolumesSvc",
""}

Definition at line 148 of file MaterialAllocator.h.

148 {
149 this, "TrackingVolumesSvc", "Trk::TrackingVolumesSvc/TrackingVolumesSvc",
150 ""};

◆ m_useStepPropagator

int Trk::MaterialAllocator::m_useStepPropagator
private

Definition at line 176 of file MaterialAllocator.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: