50 static const bool testOffline{
false};
53 surfaceOnTrackIdentifier(
const T& tsos,
const bool useTrackParameters =
true) {
57 if (mesb and mesb->associatedSurface().associatedDetectorElement()) {
58 result = mesb->associatedSurface().associatedDetectorElement()->identify();
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.");
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;
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;
245 const std::map<Identifier, unsigned int>* badChips{
nullptr};
250 double timecor{-20.};
253 if (theComTime.isValid()) {
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;
279 fieldCondObj->getInitializedCache(fieldCache);
280 const bool solenoidOn{fieldCache.
solenoidOn()};
284 if (not tracks.isValid()) {
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");
410 std::map < Identifier, double > mapOfTrackHitResiduals;
415 float min_layerSide{999.};
416 float max_layerSide{-1.};
421 surfaceID = surfaceOnTrackIdentifier(tsos);
423 if (not surfaceID.is_valid()) {
445 mapOfTrackHitResiduals[surfaceID] =
getResidual(surfaceID, tsos->trackParameters(), &*p_sctclcontainer);
446 sctNHitsPerRegion[waferIndex]++;
452 sctNHolesPerRegion[waferIndex]++;
459 if (tsos->trackParameters()) {
460 zpos = tsos->trackParameters()->position().z();
464 ATH_MSG_WARNING(
"No track parameter found. Zmin and Zmax not recalculated.");
470 min_layerSide =
std::min(min_layerSide, layerSide);
471 max_layerSide =
std::max(max_layerSide, layerSide);
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);
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);
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.5
f};
544 double trackHitResidual{
getResidual(surfaceID, trkParamOnSurface, &*p_sctclcontainer)};
554 bool otherFaceFound{
false};
555 IdentifierHash otherSideHash;
559 m_sctId->
get_id(otherSideHash, otherSideSurfaceID, &context);
560 otherFaceFound = mapOfTrackHitResiduals.find(otherSideSurfaceID) != mapOfTrackHitResiduals.end();
562 int nOther{sctNHits};
570 if (trkParamOnSurface and (not
findAnglesToWaferSurface(trkParamOnSurface->momentum(), surfaceID, elements, theta, phiUp))) {
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;
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.};
650 if (not trkParamOnSurface)
continue;
651 double xl{trkParamOnSurface->localPosition()[0]};
652 double yl{trkParamOnSurface->localPosition()[1]};
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};
691 bool swap{(pElement->swapPhiReadoutDirection()) ?
true :
false};
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")) {
727 fill(regionNames[isub].
data(), effAcc, ineffAcc, ietaAcc, iphiAcc, layerAcc, lumiAcc, isFirstBCIDAcc);
728 fill(
"SCTHitEffMonitor", effAcc, lumiAcc, isubAcc, sideHashAcc, isFirstBCIDAcc);
731 ATH_MSG_INFO(
"Filling " << detIndex <<
", " <<
side <<
" eta " << ieta <<
" phi " << iphi);
737 return StatusCode::SUCCESS;