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 int index = 1;
893 for (std::vector<FitMeasurement*>::iterator m = measurements.begin();
894 m != measurements.end(); ++m, ++index) {
895 // skip 'non'-measurements
896 if (!(**m).isPositionMeasurement() || (**m).isPseudo())
897 continue;
898
899 // material delimiters in MS follow the entrance break which should be
900 // already present
901 const Amg::Vector3D position = (**m).position();
902 if (m_calorimeterVolume->inside(position))
903 continue;
904
905 // break can be before measurement or after previous measurement
906 bool preBreak = false;
907 bool postBreak = false;
908 double distance = 0.;
909 if (!previous) {
910 // preBreak at first measurement in MS
911 preBreak = true;
912 referenceDirection = (**m).intersection(FittedTrajectory).direction();
913 referencePosition = (**m).intersection(FittedTrajectory).position();
914 referencePhi = position.phi();
915 startDirection = referenceDirection;
916 startPosition = referencePosition;
917 } else {
918 // post and pre breaks for cluster/drift transition,
919 // large gap between measurements,
920 // sector overlap
921 distance = referenceDirection.dot(
922 (**m).intersection(FittedTrajectory).position() - referencePosition);
923 if (((**m).isDrift() && !previous->isDrift()) ||
924 (!(**m).isDrift() && previous->isDrift()) ||
925 distance > m_stationMaxGap ||
926 ((**m).isDrift() &&
927 std::abs(position.phi() - referencePhi) > m_sectorMaxPhi)) {
928 preBreak = true;
929 if (distance > previousDistance + m_scattererMinGap)
930 postBreak = true;
931 }
932 }
933
934 if (!(preBreak || postBreak)) {
935 previous = *m;
936 previousDistance = distance;
937 continue;
938 }
939
940 // ///////
941 // msg(MSG::INFO) << std::setiosflags(std::ios::fixed)
942 // << " index" << std::setw(3) << index+1
943 // << " at " << std::setw(10) << std::setprecision(1)
944 // << startDirection.dot(
945 // (**m).intersection(FittedTrajectory).position() -
946 // startPosition)
947 // << std::setw(10) << std::setprecision(1) << distance
948 // << std::setw(9) << std::setprecision(4)
949 // << std::abs(position.phi() - referencePhi);
950 // if (preBreak) msg() << " preBreak ";
951 // if (postBreak) msg() << " postBreak ";
952 // if ((**m).isDrift()) msg() << " isDrift ";
953 // msg() << endmsg;
954 // ///////
955
956 if (postBreak && previous) {
957 // if (distance < offset) offset = 0.5*distance;
958 FitMeasurement* current = *m;
959 while (*m != previous)
960 --m;
961 FitMeasurement* delimiter = new FitMeasurement(
962 (**m).intersection(FittedTrajectory), 0.5 * m_scattererMinGap);
963 m = measurements.insert(++m, delimiter);
964 while (*m != current)
965 ++m;
966 }
967 if (preBreak) {
968 double offset = -0.5 * m_scattererMinGap;
969 if (distance - previousDistance < m_scattererMinGap)
970 offset = 0.5 * (previousDistance - distance);
971
972 FitMeasurement* delimiter =
973 new FitMeasurement((**m).intersection(FittedTrajectory), offset);
974 m = measurements.insert(m, delimiter);
975 ++m;
976 }
977 previous = *m;
978 previousDistance = 0.;
979 referenceDirection = (**m).intersection(FittedTrajectory).direction();
980 referencePosition = (**m).intersection(FittedTrajectory).position();
981 referencePhi = position.phi();
982 }
983 // orderMeasurements(measurements,startDirection,startPosition);
984 // printMeasurements(measurements);
985}
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
str index
Definition DeMoScan.py:362
@ 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 987 of file MaterialAllocator.cxx.

989 {
990 if (material) {
991 for (const TrackStateOnSurface* m : *material) {
992 garbage.push_back(std::unique_ptr<const TrackStateOnSurface>(m));
993 }
994 delete material;
995 }
996}

◆ 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 999 of file MaterialAllocator.cxx.

1003 {
1004 const EventContext& ctx = Gaudi::Hive::currentContext();
1005 // fix up material duplication appearing after recent TrackingGeometry
1006 // speed-up
1007 const std::vector<const TrackStateOnSurface*>* TGMaterial =
1008 extrapolator->extrapolateM(ctx, parameters, surface, dir, boundsCheck,
1009 particleHypothesis);
1010
1011 if (!TGMaterial || TGMaterial->empty())
1012 return TGMaterial;
1013
1014 std::vector<const TrackStateOnSurface*>* duplicates = nullptr;
1015 std::vector<const TrackStateOnSurface*>* material =
1016 new std::vector<const TrackStateOnSurface*>;
1017 material->reserve(TGMaterial->size());
1018 std::vector<const TrackStateOnSurface*>::const_iterator tg =
1019 TGMaterial->begin();
1020 material->push_back(*tg);
1021 ++tg;
1022 for (; tg != TGMaterial->end(); ++tg) {
1023 const TrackStateOnSurface* TSOS = material->back();
1024 double separation = 0.;
1025 if (TSOS->trackParameters())
1026 separation = (TSOS->trackParameters()->position() -
1027 (**tg).trackParameters()->position())
1028 .mag();
1029
1030 if (separation > 0.001 * Gaudi::Units::mm) {
1031 material->push_back(*tg);
1032 } else {
1034 std::setiosflags(std::ios::fixed)
1035 << " duplicate: RZ" << std::setw(9) << std::setprecision(3)
1036 << (**tg).trackParameters()->position().perp() << std::setw(10)
1037 << std::setprecision(3) << (**tg).trackParameters()->position().z());
1038 if (!duplicates)
1039 duplicates = new std::vector<const TrackStateOnSurface*>;
1040 duplicates->push_back(*tg);
1041 }
1042 }
1043
1044 delete TGMaterial;
1045 if (duplicates)
1046 deleteMaterial(duplicates, garbage);
1047 return material;
1048}

◆ 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 1050 of file MaterialAllocator.cxx.

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

1468 {
1469 // aggregation possible in indet and MS. Frequent occurrence in MS
1470 ATH_MSG_INFO("segment material aggregation " << material.size());
1471 FitMeasurement* measurement1 = nullptr;
1472 FitMeasurement* measurement2 = nullptr;
1473 if (material.empty())
1474 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1475 measurement2);
1476
1477
1478 int adjacentScatterers = 0;
1479 std::vector<FitMeasurement*> aggregateScatterers;
1480 bool hasReferencePosition = false;
1481 Amg::Vector3D referencePosition;
1482 bool const haveAggregation = false;
1483 // bool makeAggregation = false;
1484 // double maxDistance = 0.;
1485 for (std::vector<const TrackStateOnSurface*>::const_reverse_iterator tsos =
1486 material.rbegin();
1487 tsos != material.rend(); ++tsos) {
1488 if (!(**tsos).trackParameters() || !(**tsos).materialEffectsOnTrack()){
1489 continue;
1490 }
1491 ++adjacentScatterers;
1492 if (!hasReferencePosition) {
1493 referencePosition = Amg::Vector3D((**tsos).trackParameters()->position());
1494 hasReferencePosition = true;
1495 }
1496 const double distance =
1497 ((**tsos).trackParameters()->position() - referencePosition).mag();
1498 const double weight = (**tsos).materialEffectsOnTrack()->thicknessInX0();
1499
1500 ATH_MSG_INFO(" material position " << (**tsos).trackParameters()->position()
1501 << " distance " << distance
1502 << " thickness " << 100. * weight);
1503 }
1504
1505 // if 2 or less selected TSOS: just set scatterers on TSOS
1506 if (adjacentScatterers < 3) {
1507 }
1508
1509 // in case of aggregation: insert aggregateScatterers onto track
1510 if (haveAggregation) {
1511 }
1512
1513 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1514 measurement2);
1515}
#define ATH_MSG_INFO(x)

◆ materialAggregation() [2/2]

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

Definition at line 1517 of file MaterialAllocator.cxx.

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

1880 {
1881 if (!tsos.trackParameters() || !tsos.materialEffectsOnTrack())
1882 return nullptr;
1883
1884 const double deltaE = outgoingEnergy - tsos.trackParameters()->momentum().mag();
1885 const double thicknessInX0 = tsos.materialEffectsOnTrack()->thicknessInX0();
1886 const Amg::Vector3D position = tsos.trackParameters()->position();
1887 const Amg::Vector3D direction = tsos.trackParameters()->momentum().unit();
1888 double qOverP = 1. / outgoingEnergy;
1889 if (tsos.trackParameters()->charge() < 0)
1890 qOverP = -qOverP;
1891
1892 return new FitMeasurement(thicknessInX0, deltaE, particleMass, position,
1893 direction, qOverP);
1894}

◆ 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 1896 of file MaterialAllocator.cxx.

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

◆ 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.
msgSvc
Provide convenience handles for various services.
Definition StdJOSetup.py:36
@ 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 2006 of file MaterialAllocator.cxx.

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