50 static const bool testOffline{
false};
53 surfaceOnTrackIdentifier(
const T& tsos,
const bool useTrackParameters =
true) {
59 }
else if (useTrackParameters and tsos->trackParameters()) {
60 result = tsos->trackParameters()->associatedSurface().associatedDetectorElementIdentifier();
65 constexpr double radianDegrees{180. /
M_PI};
67 static const double stripWidth{79.95e-3};
69 static const std::array < std::string, N_REGIONS > regionNames = {
70 "SCTHitEffMonitorEC",
"SCTHitEffMonitorB",
"SCTHitEffMonitorEA"
139 if (barrel_ec ==
BARREL) {
149 ATH_MSG_WARNING(
"The barrel_bc index" << barrel_ec <<
" is not defined.");
152 return waferIndex + layer_disk *
N_SIDES + side;
157 const InDet::SCT_ClusterContainer* p_sctclcontainer)
const {
158 double trackHitResidual{-999.};
160 if (trkParam==
nullptr) {
161 ATH_MSG_WARNING(
"Not track parameters found. Returning default residual value.");
162 return trackHitResidual;
165 auto containerIterator{p_sctclcontainer->indexFindPtr(idh)};
166 if (containerIterator !=
nullptr) {
168 if ((cluster==
nullptr) or (cluster->detectorElement()==
nullptr)) {
172 if (surfaceID ==
m_sctId->wafer_id(cluster->detectorElement()->identify())) {
174 std::unique_ptr<const Trk::RIO_OnTrack> rio{
m_rotcreator->correct(*rioo, *trkParam, Gaudi::Hive::currentContext())};
178 if (not residualPull)
continue;
179 if (std::abs(residualPull->residual()[
Trk::loc1]) < std::abs(trackHitResidual)) {
180 trackHitResidual = residualPull->residual()[
Trk::loc1];
186 return trackHitResidual;
202 ATH_MSG_VERBOSE(
"findAnglesToWaferSurface: failed to find detector element for id = " <<
m_sctId->print_to_string(
id));
203 return StatusCode::FAILURE;
205 double pNormal{mom.dot(element->
normal())};
206 double pEta{mom.dot(element->
etaAxis())};
207 double pPhi{mom.dot(element->
phiAxis())};
215 phi = std::atan(pPhi / pNormal) * radianDegrees;
216 theta = std::atan(pEta / pNormal) * radianDegrees;
218 return StatusCode::SUCCESS;
222 double xLeftEdge{xl +
N_STRIPS / 2. * stripWidth};
223 int chipPos{
static_cast<int>(xLeftEdge / (stripWidth *
N_STRIPS) *
N_CHIPS)};
226 chipPos =
swap ? 5 - chipPos : chipPos;
228 chipPos =
swap ? 11 - chipPos : 6 + chipPos;
236 return StatusCode::FAILURE;
239 return StatusCode::SUCCESS;
244 const std::string histoName{
"SCTHitEffMonitor"};
245 const std::map<Identifier, unsigned int>* badChips{
nullptr};
250 double timecor{-20.};
254 timecor = theComTime->getTime();
262 const EventIDBase& pEvent{ctx.eventID()};
263 unsigned BCID{pEvent.bunch_crossing_id()};
266 ATH_MSG_ERROR(
"Unable to retrieve BunchCrossing conditions object" );
267 return StatusCode::FAILURE;
274 if (fieldCondObj==
nullptr) {
275 ATH_MSG_ERROR(
"AtlasFieldCacheCondObj cannot be retrieved.");
276 return StatusCode::RECOVERABLE;
280 const bool solenoidOn{fieldCache.
solenoidOn()};
286 return StatusCode::SUCCESS;
292 if (not p_sctclcontainer.
isValid()) {
294 return StatusCode::SUCCESS;
300 return StatusCode::SUCCESS;
306 if (elements==
nullptr) {
308 return StatusCode::FAILURE;
314 if (pthisTrack==
nullptr) {
317 if (
failCut(pthisTrack and pthisTrack->trackParameters() and pthisTrack->trackParameters()->size(),
318 "track cut: presence")) {
323 "track cut: inside-out only")) {
326 if (pthisTrack->perigeeParameters() ==
nullptr) {
329 const Trk::Perigee* perigee{pthisTrack->perigeeParameters()};
335 if (solenoidOn and
failCut(perigee->
pT() >=
m_minPt,
"track cut: Min Pt")) {
351 if (pthisTrack==
nullptr) {
354 if (
failCut(pthisTrack and pthisTrack->trackParameters() and pthisTrack->trackParameters()->size(),
355 "track cut: presence")) {
360 "track cut: inside-out only")) {
363 if (pthisTrack->perigeeParameters() ==
nullptr) {
366 const Trk::Perigee* perigee{pthisTrack->perigeeParameters()};
388 std::unique_ptr<const Trk::Track> trackWithHoles(
m_holeSearchTool->getTrackWithHoles(*pthisTrack));
389 if (not trackWithHoles) {
393 ATH_MSG_VERBOSE(
"Found " << trackWithHoles->trackStateOnSurfaces()->size() <<
" states on track");
402 std::array<int, N_LAYERS_TOTAL*N_SIDES> sctNHitsPerRegion{};
403 std::array<int, N_LAYERS_TOTAL*N_SIDES> sctNHolesPerRegion{};
410 std::map < Identifier, double > mapOfTrackHitResiduals;
411 double zmin = std::numeric_limits<float>::max();
412 double zmax = -std::numeric_limits<float>::max();
415 float min_layerSide{999.};
416 float max_layerSide{-1.};
421 surfaceID = surfaceOnTrackIdentifier(tsos);
430 if (
m_sctId->is_sct(surfaceID)) {
432 m_sctId->layer_disk(surfaceID),
440 if (
m_trtId->is_trt(surfaceID)) {
443 if (
m_sctId->is_sct(surfaceID)) {
445 mapOfTrackHitResiduals[surfaceID] =
getResidual(surfaceID, tsos->trackParameters(), &*p_sctclcontainer);
446 sctNHitsPerRegion.at(waferIndex)++;
451 }
else if (
m_sctId->is_sct(surfaceID)) {
452 sctNHolesPerRegion.at(waferIndex)++;
459 if (tsos->trackParameters()) {
460 zpos = tsos->trackParameters()->position().z();
461 zmax = std::max(zpos, zmax);
462 zmin = std::min(zpos, zmin);
464 ATH_MSG_WARNING(
"No track parameter found. Zmin and Zmax not recalculated.");
467 if (
m_sctId->is_sct(surfaceID)) {
469 static_cast<float>(
m_sctId->layer_disk(surfaceID)) + (
static_cast<float>(
m_sctId->side(surfaceID)) == 0) * 0.5;
470 min_layerSide = std::min(min_layerSide, layerSide);
471 max_layerSide = std::max(max_layerSide, layerSide);
472 }
else if (
m_pixelId->is_pixel(surfaceID)) {
474 }
else if (
m_trtId->is_trt(surfaceID)) {
482 std::vector<bool> layersCrossedByTrack[
N_REGIONS];
483 std::vector<int> nHolesOnLayer[
N_REGIONS];
484 std::vector<int> nHolesDistOnLayer[
N_REGIONS];
486 nHolesDistOnLayer[i].resize(
n_layers[i] * 2, 0);
487 nHolesOnLayer[i].resize(
n_layers[i] * 2, 0);
488 layersCrossedByTrack[i].resize(
n_layers[i] * 2,
false);
494 surfaceID = surfaceOnTrackIdentifier(tsos);
501 int side{
m_sctId->side(surfaceID)};
502 int layer{
m_sctId->layer_disk(surfaceID)};
503 int bec{
m_sctId->barrel_ec(surfaceID)};
509 Int_t sctNHitsExceptThisWafer{0};
510 Int_t sctNHolesExceptThisWafer{0};
513 if (i != waferIndex) {
514 sctNHitsExceptThisWafer += sctNHitsPerRegion[i];
515 sctNHolesExceptThisWafer += sctNHolesPerRegion[i];
523 if ((
unsigned int)(sctNHitsExceptThisWafer + pixelNHits) <
m_minSiHits) {
524 ATH_MSG_VERBOSE(
"This track is rejected due to the number of hits: " << sctNHitsExceptThisWafer * pixelNHits);
527 if ((
unsigned int)(sctNHolesExceptThisWafer + pixelNHoles) >
m_maxSiHoles) {
528 ATH_MSG_VERBOSE(
"This track is rejected due to the number of holes: " << sctNHolesExceptThisWafer * pixelNHoles);
532 std::string etaPhiSuffix =
"_" + std::to_string(layer) +
"_" + std::to_string(side);
534 if (detIndex == -1) {
535 ATH_MSG_WARNING(
"The detector region (barrel, endcap A, endcap C) could not be determined");
541 float layerPlusHalfSide{
static_cast<float>(layer) +
static_cast<float>(side) * 0.5f};
542 float dedicated_layerPlusHalfSide{
static_cast<float>(layer) +
static_cast<float>((side + 1) % 2) * 0.5f};
544 double trackHitResidual{
getResidual(surfaceID, trkParamOnSurface, &*p_sctclcontainer)};
554 bool otherFaceFound{
false};
558 m_sctId->get_other_side(sideHash, otherSideHash);
559 m_sctId->get_id(otherSideHash, otherSideSurfaceID, &context);
560 otherFaceFound = mapOfTrackHitResiduals.find(otherSideSurfaceID) != mapOfTrackHitResiduals.end();
562 int nOther{sctNHits};
576 sctNHits >=
m_minSCTHits,
"track cut: min TRT or SCT hits")) {
600 static const double tmin{-15.};
601 static const double tmax{10.};
602 if (
failCut((timecor >= tmin) and (timecor <= tmax),
"track cut: timing cut")) {
608 bool enclosingHits{
true};
610 if (tsos->trackParameters()) {
611 zpos = tsos->trackParameters()->position().z();
612 enclosingHits = ((zpos > zmin) and (zpos < zmax));
614 ATH_MSG_WARNING(
"No track parameters found. Cannot determine whether it is an enclosed hit.");
615 enclosingHits =
false;
619 +
static_cast<float>(
m_sctId->layer_disk(surfaceID))
620 + (
static_cast<float>(
m_sctId->side(surfaceID)) == 0) * 0.5;
621 enclosingHits = ((layerSide > min_layerSide) and (layerSide < max_layerSide));
625 (not (layerPlusHalfSide == 0.5)) and
626 (not ((isub == 1) and (layerPlusHalfSide == 3))) and
627 (not (layerPlusHalfSide == 8))) {
628 if (
failCut(enclosingHits,
"hit cut: enclosing hits")) {
634 double chi2{trackWithHoles->fitQuality()->chiSquared()};
635 int ndf{trackWithHoles->fitQuality()->numberDoF()};
636 double chi2_div_ndf{ndf > 0. ?
chi2 / ndf : -1.};
642 if (
failCut((ndf > 0) and (chi2_div_ndf <=
m_maxChi2),
"track cut: chi2 cut")) {
650 if (not trkParamOnSurface)
continue;
655 bool insideGuardRing{
true};
658 static const float yGuard{3.};
659 if (xl < -30.7 + xGuard) {
660 insideGuardRing =
false;
662 if (xl > 30.7 - xGuard) {
663 insideGuardRing =
false;
666 static const double yend{63.960 + 0.03 - 1.};
667 static const double ydead{2.06 / 2.};
668 if (yl > yend - yGuard) {
669 insideGuardRing =
false;
671 if (yl < -yend + yGuard) {
672 insideGuardRing =
false;
674 if ((yl < ydead + yGuard) and (yl > -ydead - yGuard)) {
675 insideGuardRing =
false;
679 insideGuardRing =
true;
688 bool nearBadChip{
false};
693 unsigned int status{0};
694 std::map<Identifier, unsigned int>::const_iterator badChip{badChips->find(module_id)};
695 if (badChip != badChips->end()) {
696 status = (*badChip).second;
698 const bool nearBadChipDead{(status & (1 << chipPos)) != 0};
699 const bool nextBadChipDead{(status & (1 << (chipPos + 1))) != 0};
700 const bool isNotEndChip{(chipPos != 5) and (chipPos != 11)};
705 nearBadChip = nearBadChipDead or (isNotEndChip and nextBadChipDead);
707 if (
failCut(not nearBadChip,
"hit cut: not near bad chip")) {
713 const int ieta{
m_sctId->eta_module(surfaceID)};
714 const int iphi{
m_sctId->phi_module(surfaceID)};
727 fill(regionNames[isub].data(), effAcc, ineffAcc, ietaAcc, iphiAcc, layerAcc, lumiAcc, isFirstBCIDAcc);
728 fill(histoName, effAcc, lumiAcc, isubAcc, sideHashAcc, isFirstBCIDAcc);
731 ATH_MSG_INFO(
"Filling " << detIndex <<
", " << side <<
" eta " << ieta <<
" phi " << iphi);
737 return StatusCode::SUCCESS;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
Helpers for checking error return status codes and reporting errors.
void swap(DataVector< T > &a, DataVector< T > &b)
See DataVector<T, BASE>::swap().
Header containing the InDetHierarchy enum, to avoid pulling in a class every time it is needed and na...
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
Handle class for reading from StoreGate.
This is an Identifier helper class for the TRT subdetector.
const ServiceHandle< StoreGateSvc > & detStore() const
Environment_t environment() const
Accessor functions for the environment.
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
int distanceFromFront(const bcid_type bcid, const BunchDistanceType type=NanoSec) const
The distance of the specific bunch crossing from the front of the train.
@ BunchCrossings
Distance in units of 25 nanoseconds.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
bool swapPhiReadoutDirection() const
Determine if readout direction between online and offline needs swapping.
const Amg::Vector3D & etaAxis() const
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
const Amg::Vector3D & phiAxis() const
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
bool solenoidOn() const
status of the magnets
Declare a monitored scalar variable.
FloatProperty m_maxPhiAngle
IntegerProperty m_minTRTHits
SG::ReadHandleKey< TrackCollection > m_TrackName
BooleanProperty m_vetoBadChips
SCTHitEffMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
int becIdxLayer2Index(const int becIdx, const int layer) const
ToolHandle< Trk::ITrackHoleSearchTool > m_holeSearchTool
UnsignedIntegerProperty m_maxSiHoles
BooleanProperty m_useIDGlobal
int getWaferIndex(const int barrel_bc, const int layer_disk, const int side) const
SG::ReadCondHandleKey< BunchCrossingCondData > m_bunchCrossingKey
FloatProperty m_effdistcut
BooleanProperty m_insideOutOnly
IntegerProperty m_minOtherHits
const PixelID * m_pixelId
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
UnsignedIntegerProperty m_maxTracks
SG::ReadHandleKey< ComTime > m_comTimeName
BooleanProperty m_requireOtherFace
BooleanProperty m_requireGuardRing
int previousChip(double xl, int side, bool swap) const
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_sctContainerName
IntegerProperty m_minPixelHits
ToolHandle< Trk::IResidualPullCalculator > m_residualPullCalculator
ToolHandle< ISCT_ConfigurationConditionsTool > m_configConditions
ToolHandle< Trk::IRIO_OnTrackCreator > m_rotcreator
IntegerProperty m_minSCTHits
double getResidual(const Identifier &surfaceID, const Trk::TrackParameters *trkParam, const InDet::SCT_ClusterContainer *p_sctclcontainer) const
StatusCode findAnglesToWaferSurface(const Amg::Vector3D &mom, const Identifier id, const InDetDD::SiDetectorElementCollection *elements, double &theta, double &phi) const
BooleanProperty m_useSCTorTRT
BooleanProperty m_requireEnclosingHits
UnsignedIntegerProperty m_minSiHits
BooleanProperty m_useTRTPhase
virtual StatusCode initialize() override final
initialize
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
FloatProperty m_maxZ0sinTheta
BooleanProperty m_isCosmic
StatusCode failCut(bool value, const std::string &name) const
const_pointer_type retrieve()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
This class is the pure abstract base class for all fittable tracking measurements.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
double pT() const
Access method for transverse momentum.
Amg::Vector2D localPosition() const
Access method for the local coordinates, local parameter definitions differ for each surface type.
@ Unbiased
RP with track state that has measurement not included.
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
@ SiSPSeededFinder
Tracks from SiSPSeedFinder.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
A summary of the information contained by a track.
virtual Identifier identify() const =0
Identifier.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
unsigned int bec2Index(const int becVal)
Conversion bec->index.
static const std::vector< int > n_layers
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfSCTHits
number of SCT holes
void fill(H5::Group &out_file, size_t iterations)