41 #include "TProfile2D.h"
43 #include "TGraphErrors.h"
54 using std::ostringstream;
58 static const bool testOffline(
false);
61 "SCT/SCTEC/eff",
"SCT/SCTB/eff",
"SCT/SCTEA/eff",
"SCT/GENERAL/eff"
63 static const string histogramPathRe[
N_REGIONS] = {
64 "SCT/SCTEC/eff/perLumiBlock",
"SCT/SCTB/eff/perLumiBlock",
"SCT/SCTEA/eff/perLumiBlock"
67 template<
typename T > Identifier
68 surfaceOnTrackIdentifier(
const T& tsos,
const bool useTrackParameters =
true) {
72 if (mesb and mesb->associatedSurface().associatedDetectorElement()) {
73 result = mesb->associatedSurface().associatedDetectorElement()->identify();
74 }
else if (useTrackParameters and tsos->trackParameters()) {
75 result = tsos->trackParameters()->associatedSurface().associatedDetectorElementIdentifier();
80 constexpr
double radianDegrees{180. /
M_PI};
82 static const double stripWidth{79.95e-3};
85 static const std::array < TString, 3 > mapName = {
86 "m_eff_",
"eff_",
"p_eff_"
88 static const std::array < TString, 3 > effLumiName = {
89 "m_eff_Lumi_",
"eff_Lumi_",
"p_eff_Lumi_"
92 static const std::array < TString, N_REGIONS > ineffMapName = {
93 "ineffm_",
"ineff_",
"ineffp_"
96 static const std::array < TString, N_REGIONS > sumeff = {
97 "summaryeffm",
"summaryeff",
"summaryeffp"
99 static const std::array < TString, N_REGIONS > sumeffBCID = {
100 "summaryeffmBCID",
"summaryeffBCID",
"summaryeffpBCID"
102 static const std::array < TString, N_REGIONS > sumefftitle = {
103 "Summary Module Efficiency in Endcap C",
"Summary Module Efficiency in Barrel",
104 "Summary Module Efficiency in Endcap A"
106 static const std::array < TString, N_REGIONS > sumefftitleBCID = {
107 "Summary Module Efficiency in Endcap C for First BC",
"Summary Module Efficiency in Barrel for First BC",
108 "Summary Module Efficiency in Endcap A for First BC"
124 for (
unsigned int i{0};
i <
m_effMap.size(); ++
i) {
176 return StatusCode::SUCCESS;
182 return StatusCode::SUCCESS;
185 ATH_MSG_WARNING(
"Running on cosmics: releasing d0 cut and forcing use of TRT timing");
190 for (
const std::pair<const Identifier, unsigned int>& chip: *
m_badChips) {
194 std::array < MonGroup, N_REGIONS_INC_GENERAL > histGroupE = {
201 std::array < MonGroup, N_REGIONS > histGroupL = {
207 std::array < MonGroup, N_REGIONS_INC_GENERAL > histGroupShift = {
229 "Efficiency vs Luminosity block", NBINS_LBs, 0.5, NBINS_LBs + 0.5));
233 "SCT Efficiency Distribution", 500, 0, 1));
239 for (
unsigned int isub{0}; isub <
N_REGIONS; ++isub) {
240 for (
int i{0};
i < n_layers[isub]; ++
i) {
242 if (detIndex == -1) {
243 ATH_MSG_WARNING(
"Subdetector region (barrel, endcap A, endcap C) could not be determined");
246 for (
int j{0}; j < 2; ++j) {
249 ineffMapName[isub] +
i +
"_" + j,
250 "Hit inefficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub],
251 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
252 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
253 m_ineffMap[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
254 m_ineffMap[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
258 mapName[isub] +
i +
"_" + j,
259 "Hit efficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub],
260 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
261 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
262 m_effMap[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
263 m_effMap[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
266 mapName[isub] +
i +
"_" + j +
"_bcid",
267 "Hit efficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub] +
" for first BCID",
268 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
269 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
270 m_effMapFirstBCID[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
271 m_effMapFirstBCID[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
274 effLumiName[isub] +
i +
"_" + j,
275 "Efficiency vs LumiBlock of" + layerName[isub] +
i +
" / side " + j +
" in " +
277 NBINS_LBs, 0.5, NBINS_LBs + 0.5));
278 m_effLumiBlock[detIndex][j]->GetXaxis()->SetTitle(
"Luminosity Block");
285 2 * n_layers[isub], 0., n_layers[isub]));
287 sumefftitleBCID[isub], 2 * n_layers[isub], 0., n_layers[isub]));
291 for (
unsigned int i{0};
i <
limit[isub];
i++) {
294 m_Eff_summaryHisto[isub]->GetXaxis()->SetBinLabel(
i + 1, layerSide.dedicated_title().c_str());
301 "Efficiency vs Luminosity block in " + subDetName[isub], NBINS_LBs, 0.5, NBINS_LBs + 0.5));
307 return StatusCode::SUCCESS;
313 ATH_MSG_WARNING(
"Running on cosmics: releasing d0 cut and forcing use of TRT timing");
318 for (
const std::pair<const Identifier, unsigned int>& chip: *
m_badChips) {
322 std::array < MonGroup, N_REGIONS_INC_GENERAL > histGroupE = {
329 std::array < MonGroup, N_REGIONS > histGroupL = {
335 std::array < MonGroup, N_REGIONS_INC_GENERAL > histGroupShift = {
357 "Efficiency vs Luminosity block", NBINS_LBs, 0.5, NBINS_LBs + 0.5));
359 for (
unsigned int isub{0}; isub <
N_REGIONS; ++isub) {
360 for (
int i{0};
i < n_layers[isub]; ++
i) {
362 if (detIndex == -1) {
363 ATH_MSG_WARNING(
"Detector region (barrel, endcap A, endcap C) could not be determined");
366 for (
int j{0}; j < 2; ++j) {
369 ineffMapName[isub] +
i +
"_" + j,
370 "Hit inefficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub],
371 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
372 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
373 m_ineffMap[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
374 m_ineffMap[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
378 mapName[isub] +
i +
"_" + j,
379 "Hit efficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub],
380 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
381 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
382 m_effMap[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
383 m_effMap[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
386 mapName[isub] +
i +
"_" + j +
"_bcid",
387 "Hit efficiency of" + layerName[isub] +
i +
" / side " + j +
" in " + subDetName[isub] +
" for first BCID",
388 n_etabins[isub], f_etabin[isub] - .5, l_etabin[isub] + .5,
389 n_phibins[isub], f_phibin[isub] - .5, l_phibin[isub] + .5));
390 m_effMapFirstBCID[detIndex][j]->GetXaxis()->SetTitle(
"Index in the direction of #eta");
391 m_effMapFirstBCID[detIndex][j]->GetYaxis()->SetTitle(
"Index in the direction of #phi");
394 effLumiName[isub] +
i +
"_" + j,
395 "Efficiency vs LumiBlock" + layerName[isub] +
i +
" / side " + j +
" in " +
398 m_effLumiBlock[detIndex][j]->GetXaxis()->SetTitle(
"Luminosity Block");
404 2 * n_layers[isub], 0., n_layers[isub]));
406 sumefftitleBCID[isub], 2 * n_layers[isub], 0., n_layers[isub]));
410 for (
unsigned int i{0};
i <
limit[isub];
i++) {
412 m_Eff_summaryHisto[isub]->GetXaxis()->SetBinLabel(
i + 1, layerSide.dedicated_title().c_str());
418 "Efficiency vs Luminosity block in " + subDetName[isub], NBINS_LBs, 0.5, NBINS_LBs + 0.5));
424 return StatusCode::SUCCESS;
434 double timecor{-20.};
437 if (theComTime.isValid()) {
438 timecor = theComTime->getTime();
446 const EventContext& ctx{Gaudi::Hive::currentContext()};
447 const EventIDBase& pEvent{ctx.eventID()};
448 unsigned BCID{pEvent.bunch_crossing_id()};
452 ATH_MSG_ERROR(
"Unable to retrieve BunchCrossing conditions object" );
453 return StatusCode::FAILURE;
460 if (fieldCondObj==
nullptr) {
461 ATH_MSG_ERROR(
"AtlasFieldCacheCondObj cannot be retrieved.");
462 return StatusCode::RECOVERABLE;
465 fieldCondObj->getInitializedCache(fieldCache);
466 const bool solenoidOn{fieldCache.
solenoidOn()};
470 if (not tracks.isValid()) {
472 return StatusCode::SUCCESS;
478 if (not p_sctclcontainer.isValid()) {
480 return StatusCode::SUCCESS;
486 return StatusCode::SUCCESS;
492 if (elements==
nullptr) {
494 return StatusCode::FAILURE;
500 if (pthisTrack==
nullptr) {
503 if (
failCut(pthisTrack and pthisTrack->trackParameters() and pthisTrack->trackParameters()->size(),
504 "track cut: presence")) {
509 "track cut: inside-out only")) {
512 if (pthisTrack->perigeeParameters() ==
nullptr) {
515 const Trk::Perigee* perigee{pthisTrack->perigeeParameters()};
521 if (solenoidOn and
failCut(perigee->pT() >=
m_minPt,
"track cut: Min Pt")) {
535 if (pthisTrack==
nullptr) {
538 if (
failCut(pthisTrack and pthisTrack->trackParameters() and pthisTrack->trackParameters()->size(),
539 "track cut: presence")) {
544 "track cut: inside-out only")) {
547 if (pthisTrack->perigeeParameters() ==
nullptr) {
550 const Trk::Perigee* perigee{pthisTrack->perigeeParameters()};
572 std::unique_ptr<const Trk::Track> trackWithHoles(
m_holeSearchTool->getTrackWithHoles(*pthisTrack));
573 if (not trackWithHoles) {
577 ATH_MSG_VERBOSE(
"Found " << trackWithHoles->trackStateOnSurfaces()->size() <<
" states on track");
584 std::map < Identifier, double > mapOfTrackHitResiduals;
589 float min_layerSide{999.};
590 float max_layerSide{-1.};
591 Identifier surfaceID;
595 surfaceID = surfaceOnTrackIdentifier(tsos);
597 if (not surfaceID.is_valid()) {
609 mapOfTrackHitResiduals[surfaceID] =
getResidual(surfaceID, tsos->trackParameters(), &*p_sctclcontainer);
616 if (tsos->trackParameters()) {
617 zpos = tsos->trackParameters()->position().z();
621 ATH_MSG_WARNING(
"No track parameter found. Zmin and Zmax not recalculated.");
627 min_layerSide =
std::min(min_layerSide, layerSide);
628 max_layerSide =
std::max(max_layerSide, layerSide);
639 std::vector<bool> layersCrossedByTrack[
N_REGIONS];
640 std::vector<int> nHolesOnLayer[
N_REGIONS];
641 std::vector<int> nHolesDistOnLayer[
N_REGIONS];
643 nHolesDistOnLayer[
i].resize(n_layers[
i] * 2, 0);
644 nHolesOnLayer[
i].resize(n_layers[
i] * 2, 0);
645 layersCrossedByTrack[
i].resize(n_layers[
i] * 2,
false);
650 surfaceID = surfaceOnTrackIdentifier(tsos);
662 if (detIndex == -1) {
663 ATH_MSG_WARNING(
"The detector region (barrel, endcap A, endcap C) could not be determined");
666 int histnumber{detIndex};
670 float layerPlusHalfSide{
static_cast<float>(
layer) +
static_cast<float>(
side) * 0.5f};
671 float dedicated_layerPlusHalfSide{
static_cast<float>(
layer) +
static_cast<float>((
side + 1) % 2) * 0.5
f};
673 double trackHitResidual{
getResidual(surfaceID, trkParamOnSurface, &*p_sctclcontainer)};
684 bool otherFaceFound{
false};
685 IdentifierHash otherSideHash;
686 Identifier otherSideSurfaceID;
689 m_sctId->
get_id(otherSideHash, otherSideSurfaceID, &context);
690 otherFaceFound = mapOfTrackHitResiduals.find(otherSideSurfaceID) != mapOfTrackHitResiduals.end();
692 int nOther{sctNHits};
706 sctNHits >=
m_minSCTHits,
"track cut: min TRT or SCT hits")) {
730 static const double tmin{-15.};
731 static const double tmax{10.};
732 if (
failCut((timecor >= tmin) and (timecor <= tmax),
"track cut: timing cut")) {
738 bool enclosingHits{
true};
740 if (tsos->trackParameters()) {
741 zpos = tsos->trackParameters()->position().z();
742 enclosingHits = ((zpos >
zmin) and (zpos <
zmax));
744 ATH_MSG_WARNING(
"No track parameters found. Cannot determine whether it is an enclosed hit.");
745 enclosingHits =
false;
750 + (
static_cast<float>(
m_sctId->
side(surfaceID)) == 0) * 0.5;
751 enclosingHits = ((layerSide > min_layerSide) and (layerSide < max_layerSide));
755 (not (layerPlusHalfSide == 0.5)) and
756 (not ((isub == 1) and (layerPlusHalfSide == 3))) and
757 (not (layerPlusHalfSide == 8))) {
758 if (
failCut(enclosingHits,
"hit cut: enclosing hits")) {
764 double chi2{trackWithHoles->fitQuality()->chiSquared()};
765 int ndf{trackWithHoles->fitQuality()->numberDoF()};
766 double chi2_div_ndf{
ndf > 0. ?
chi2 /
ndf : -1.};
780 if (not trkParamOnSurface)
continue;
781 double xl{trkParamOnSurface->localPosition()[0]};
782 double yl{trkParamOnSurface->localPosition()[1]};
785 bool insideGuardRing{
true};
788 static const float yGuard{3.};
789 if (xl < -30.7 + xGuard) {
790 insideGuardRing =
false;
792 if (xl > 30.7 - xGuard) {
793 insideGuardRing =
false;
796 static const double yend{63.960 + 0.03 - 1.};
797 static const double ydead{2.06 / 2.};
798 if (yl > yend - yGuard) {
799 insideGuardRing =
false;
801 if (yl < -yend + yGuard) {
802 insideGuardRing =
false;
804 if ((yl < ydead + yGuard) and (yl > -ydead - yGuard)) {
805 insideGuardRing =
false;
809 insideGuardRing =
true;
817 bool nearBadChip{
false};
820 bool swap{(pElement->swapPhiReadoutDirection()) ?
true :
false};
823 std::map<Identifier, unsigned int>::const_iterator badChip{
m_badChips->find(module_id)};
825 status = (*badChip).second;
827 const bool nearBadChipDead{(
status & (1 << chipPos)) != 0};
828 const bool nextBadChipDead{(
status & (1 << (chipPos + 1))) != 0};
829 const bool isNotEndChip{(chipPos != 5) and (chipPos != 11)};
834 nearBadChip = nearBadChipDead or (isNotEndChip and nextBadChipDead);
854 if ( BCIDpos <= 0 ) {
861 ATH_MSG_INFO(
"Filling " << histnumber <<
", " <<
side <<
" eta " << ieta <<
" phi " << iphi);
866 return StatusCode::SUCCESS;
873 for (
int isub{0}; isub <
N_REGIONS; ++isub) {
874 for (
int i{0};
i < n_layers[isub]; ++
i) {
876 if (detIndex != -1) {
877 for (
int j{0}; j < 2; ++j) {
878 for (
int xbin{1}; xbin <
m_effMap[detIndex][j]->GetNbinsX() + 1; xbin++) {
879 for (
int ybin{1}; ybin <
m_effMap[detIndex][j]->GetNbinsY() + 1; ybin++) {
880 if (
m_effMap[detIndex][j]->GetBinEntries(
m_effMap[detIndex][j]->GetBin(xbin, ybin)) == 0) {
890 return StatusCode::SUCCESS;
897 return StatusCode::FAILURE;
900 return StatusCode::SUCCESS;
905 double xLeftEdge{xl +
N_STRIPS / 2. * stripWidth};
906 int chipPos{
static_cast<int>(xLeftEdge / (stripWidth *
N_STRIPS) *
N_CHIPS)};
909 chipPos =
swap ? 5 - chipPos : chipPos;
911 chipPos =
swap ? 11 - chipPos : 6 + chipPos;
928 return StatusCode::FAILURE;
930 double pNormal{
mom.dot(element->normal())};
931 double pEta{
mom.dot(element->etaAxis())};
932 double pPhi{
mom.dot(element->phiAxis())};
943 return StatusCode::SUCCESS;
952 return StatusCode::SUCCESS;
957 int nbinx,
double x1,
double x2,
958 int nbiny,
double y1,
double y2)
const {
962 return StatusCode::SUCCESS;
967 int nbinx,
double*
xbins,
int nbiny,
double*
ybins)
const {
971 return StatusCode::SUCCESS;
978 double trackHitResidual{-999.};
980 if (trkParam==
nullptr) {
981 ATH_MSG_WARNING(
"Not track parameters found. Returning default residual value.");
982 return trackHitResidual;
986 if (containerIterator !=
nullptr) {
988 if ((cluster==
nullptr) or (cluster->detectorElement()==
nullptr)) {
994 std::unique_ptr<const Trk::RIO_OnTrack> rio{
m_rotcreator->correct(*rioo, *trkParam)};
998 if (not residualPull)
continue;
999 if (std::abs(residualPull->residual()[
Trk::loc1]) < std::abs(trackHitResidual)) {
1000 trackHitResidual = residualPull->residual()[
Trk::loc1];
1006 return trackHitResidual;