diff --git a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt index 8663ec5a1fe553202b26c7bf7b38dcdb5e67dd60..cde4cd61a5f3ea01face700c16b1b0e4a12fef22 100644 --- a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt +++ b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/CMakeLists.txt @@ -14,8 +14,11 @@ atlas_depends_on_subdirs( PUBLIC Tracking/TrkTools/TrkToolInterfaces PRIVATE DetectorDescription/AtlasDetDescr + DetectorDescription/GeoModel/GeoModelInterfaces DetectorDescription/Identifier InnerDetector/InDetConditions/InDetConditionsSummaryService + InnerDetector/InDetConditions/SCT_ConditionsServices + InnerDetector/InDetDetDescr/InDetIdentifier InnerDetector/InDetDetDescr/InDetReadoutGeometry InnerDetector/InDetRecTools/InDetRecToolInterfaces Tracking/TrkDetDescr/TrkDetDescrUtils diff --git a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/InDetTrackHoleSearch/InDetTrackHoleSearchTool.h b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/InDetTrackHoleSearch/InDetTrackHoleSearchTool.h index 7a6fffaf016fac92368aaa661d0f2cab4a86143f..6e36c0b4d1082086575b27d38f47e2353bdf9b63 100644 --- a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/InDetTrackHoleSearch/InDetTrackHoleSearchTool.h +++ b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/InDetTrackHoleSearch/InDetTrackHoleSearchTool.h @@ -19,14 +19,20 @@ #include <map> class AtlasDetectorID; +class SCT_ID; class Identifier; class AtlasID; class IInDetConditionsSvc; +class ISCT_ConfigurationConditionsSvc; +class ISCT_ByteStreamErrorsSvc; namespace InDet {class IInDetTestPixelLayerTool; } +class IGeoModelSvc; namespace Trk { class RIO_OnTrack; class TrackStateOnSurface; class Track;} namespace Trk { class IExtrapolator;} +namespace InDetDD { class SiDetectorElement; } + namespace InDet { @@ -111,6 +117,15 @@ namespace InDet /** Handles to IConditionsSummaryServices for Pixels and SCT*/ ServiceHandle <IInDetConditionsSvc> m_pixelCondSummarySvc, m_sctCondSummarySvc; ToolHandle< IInDetTestPixelLayerTool > m_pixelLayerTool; + ServiceHandle <ISCT_ConfigurationConditionsSvc> m_sctConfCondSvc; + + /** Handle to ISCT_ByteStreamErrorsSvc*/ + ServiceHandle <ISCT_ByteStreamErrorsSvc> m_sctBsErrSvc; + + /** Handle for IGeoModelSvc to retrieve geo model information */ + ServiceHandle<IGeoModelSvc> m_geoModelSvc; + + const SCT_ID* m_sct_id; /** Configure outwards hole search */ bool m_extendedListOfHoles,m_cosmic; @@ -118,6 +133,9 @@ namespace InDet /** Control usage of pixel, SCT and TRT info */ bool m_usepix, m_usesct; + /** Control check of bad SCT chip (should be false for ITk Strip) */ + bool m_checkBadSCTChip; + /** Min number of hits **/ int m_minSiHits; @@ -169,6 +187,8 @@ namespace InDet const Trk::Track* addHolesToTrack(const Trk::Track& oldTrack, std::vector<const Trk::TrackStateOnSurface*>* listOfHoles) const; + /** This method checks the SCT ABCD chip where the track passes through is bad or not */ + bool isBadSCTChip(const Identifier& waferId, const Trk::TrackParameters& parameters, const InDetDD::SiDetectorElement& siElement) const; }; } // end of namespace diff --git a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/src/InDetTrackHoleSearchTool.cxx b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/src/InDetTrackHoleSearchTool.cxx index 33b07500ea0d744df21ee2aa3128b57af65dbee8..a3dca9c31e57f41d2221ab4ddbcb860d68638e0d 100644 --- a/InnerDetector/InDetRecTools/InDetTrackHoleSearch/src/InDetTrackHoleSearchTool.cxx +++ b/InnerDetector/InDetRecTools/InDetTrackHoleSearch/src/InDetTrackHoleSearchTool.cxx @@ -21,12 +21,16 @@ #include "TrkDetDescrUtils/SharedObject.h" #include "TrkGeometry/TrackingVolume.h" #include "Identifier/Identifier.h" +#include "InDetIdentifier/SCT_ID.h" #include "AtlasDetDescr/AtlasDetectorID.h" #include "InDetConditionsSummaryService/IInDetConditionsSvc.h" +#include "SCT_ConditionsServices/ISCT_ConfigurationConditionsSvc.h" +#include "SCT_ConditionsServices/ISCT_ByteStreamErrorsSvc.h" #include "InDetReadoutGeometry/SiDetectorElement.h" #include "InDetRecToolInterfaces/IInDetTestPixelLayerTool.h" #include "TrkVolumes/Volume.h" #include "TrkVolumes/CylinderVolumeBounds.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" #include <set> //================ Constructor ================================================= @@ -38,21 +42,30 @@ InDet::InDetTrackHoleSearchTool::InDetTrackHoleSearchTool(const std::string& t, m_pixelCondSummarySvc("PixelConditionsSummarySvc",n), m_sctCondSummarySvc ("SCT_ConditionsSummarySvc",n), m_pixelLayerTool("InDet::InDetTestPixelLayerTool"), + m_sctConfCondSvc("SCT_ConfigurationConditionsSvc", n), + m_sctBsErrSvc("SCT_ByteStreamErrorsSvc", n), + m_geoModelSvc("GeoModelSvc", n), + m_sct_id(nullptr), m_extendedListOfHoles(false), m_cosmic(false), m_usepix(true), m_usesct(true), + m_checkBadSCTChip(false), m_warning(0) { declareInterface<ITrackHoleSearchTool>(this); declareProperty("Extrapolator" , m_extrapolator); declareProperty("PixelSummarySvc" , m_pixelCondSummarySvc); declareProperty("SctSummarySvc" , m_sctCondSummarySvc); + declareProperty("SctConfCondSvc" , m_sctConfCondSvc); + declareProperty("SctBsErrSvc" , m_sctBsErrSvc); declareProperty("PixelLayerTool" , m_pixelLayerTool); + declareProperty("GeoModelService" , m_geoModelSvc); declareProperty("ExtendedListOfHoles" , m_extendedListOfHoles = false); declareProperty("Cosmics" , m_cosmic); declareProperty("usePixel" , m_usepix); declareProperty("useSCT" , m_usesct); + declareProperty("checkBadSCTChip" , m_checkBadSCTChip); declareProperty("minSiHits" , m_minSiHits = 3); declareProperty("CountDeadModulesAfterLastHit", m_countDeadModulesAfterLastHit = true); declareProperty("phitol" , m_phitol = 3.); @@ -72,32 +85,32 @@ StatusCode InDet::InDetTrackHoleSearchTool::initialize() sc = detStore()->retrieve(m_atlasId, "AtlasID"); if (sc.isFailure()) { - msg(MSG::ERROR) << "Could not get AtlasID helper !" << endreq; + ATH_MSG_ERROR("Could not get AtlasID helper !"); return StatusCode::FAILURE; } // Get TrkExtrapolator from ToolService if ( m_extrapolator.retrieve().isFailure() ) { - msg(MSG::FATAL) << "Failed to retrieve tool " << m_extrapolator << endreq; + ATH_MSG_FATAL("Failed to retrieve tool " << m_extrapolator); return StatusCode::FAILURE; } else { - msg(MSG::INFO) << "Retrieved tool " << m_extrapolator << endreq; + ATH_MSG_INFO("Retrieved tool " << m_extrapolator); } if (m_usepix) { // Get PixelConditionsSummarySvc if ( m_pixelCondSummarySvc.retrieve().isFailure() ) { - msg(MSG::FATAL) << "Failed to retrieve tool " << m_pixelCondSummarySvc << endreq; + ATH_MSG_FATAL("Failed to retrieve tool " << m_pixelCondSummarySvc); return StatusCode::FAILURE; } else { - msg(MSG::INFO) << "Retrieved tool " << m_pixelCondSummarySvc << endreq; + ATH_MSG_INFO("Retrieved tool " << m_pixelCondSummarySvc); } // Get InDetPixelLayerTool from ToolService if ( m_pixelLayerTool.retrieve().isFailure() ) { - msg(MSG::FATAL) << "Failed to retrieve tool " << m_pixelLayerTool << endreq; + ATH_MSG_FATAL("Failed to retrieve tool " << m_pixelLayerTool); return StatusCode::FAILURE; } else { - msg(MSG::INFO) << "Retrieved tool " << m_pixelLayerTool << endreq; + ATH_MSG_INFO("Retrieved tool " << m_pixelLayerTool); } } @@ -105,17 +118,51 @@ StatusCode InDet::InDetTrackHoleSearchTool::initialize() if (m_usesct) { // Get SctConditionsSummarySvc if ( m_sctCondSummarySvc.retrieve().isFailure() ) { - msg(MSG::FATAL) << "Failed to retrieve tool " << m_sctCondSummarySvc << endreq; + ATH_MSG_FATAL("Failed to retrieve service " << m_sctCondSummarySvc); return StatusCode::FAILURE; } else { - msg(MSG::INFO) << "Retrieved tool " << m_sctCondSummarySvc << endreq; + ATH_MSG_INFO("Retrieved service " << m_sctCondSummarySvc); + } + + if(m_checkBadSCTChip) { + // Get SctConditionsSummarySvc + if ( m_sctConfCondSvc.retrieve().isFailure() ) { + ATH_MSG_FATAL("Failed to retrieve service " << m_sctConfCondSvc); + return StatusCode::FAILURE; + } else { + ATH_MSG_INFO("Retrieved service " << m_sctConfCondSvc); + } + // Get SCT_ByteStreamErrorsSvc + if ( m_sctBsErrSvc.retrieve().isFailure() ) { + ATH_MSG_FATAL("Failed to retrieve service " << m_sctBsErrSvc); + return StatusCode::FAILURE; + } else { + ATH_MSG_INFO("Retrieved service " << m_sctBsErrSvc); + } + // Get SCT_ID helper + if( detStore()->retrieve(m_sct_id, "SCT_ID").isFailure() ) { + ATH_MSG_FATAL("Cannot retrieve SCT ID helper!"); + return StatusCode::FAILURE; + } + + // Check if ITk Strip is used because isBadSCTChip method is valid only for SCT. + if(m_geoModelSvc.retrieve().isFailure()) { + ATH_MSG_FATAL("Could not locate GeoModelSvc"); + return StatusCode::FAILURE; + } + if(m_geoModelSvc->geoConfig()==GeoModel::GEO_RUN4 or + m_geoModelSvc->geoConfig()==GeoModel::GEO_ITk) { + ATH_MSG_WARNING("Since ITk Strip is used, m_checkBadSCTChip is turned off."); + m_checkBadSCTChip = false; + } } } - if (m_extendedListOfHoles) - msg(MSG::INFO) << "Search for extended list of holes " << endreq; + if (m_extendedListOfHoles) { + ATH_MSG_INFO("Search for extended list of holes "); + } - msg(MSG::INFO) << "initialize() successful in " << name() << endreq; + ATH_MSG_INFO("initialize() successful in " << name()); return StatusCode::SUCCESS; } @@ -284,9 +331,9 @@ bool InDet::InDetTrackHoleSearchTool::getMapOfHits(const Trk::Track& track , ++imeas; if (!(*iterTSOS)->trackParameters() && m_warning<10) { m_warning++; - msg(MSG::WARNING) << "No track parameters available for state of type measurement" << endreq; - msg(MSG::WARNING) << "Don't run this tool on slimmed tracks!" << endreq; - if (m_warning==10) msg(MSG::WARNING) << "(last message!)" << endreq; + ATH_MSG_WARNING("No track parameters available for state of type measurement"); + ATH_MSG_WARNING("Don't run this tool on slimmed tracks!"); + if (m_warning==10) ATH_MSG_WARNING("(last message!)"); } } // for cosmics: remember parameters of first SI TSOS @@ -524,20 +571,20 @@ bool InDet::InDetTrackHoleSearchTool::getMapOfHits(const Trk::Track& track , { if (!foundFirst && !(*iterTSOS)->type(Trk::TrackStateOnSurface::Outlier)) { - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Found first Si measurement !" << endreq; + ATH_MSG_VERBOSE("Found first Si measurement !"); foundFirst = true; } // is this a surface which might have a better prediction ? if (iTSOS->second->trackParameters()) { - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Found track parameter on Si surface, take it" << endreq; + ATH_MSG_VERBOSE("Found track parameter on Si surface, take it"); delete startParameters; startParameters = iTSOS->second->trackParameters()->clone(); } else { - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "No parameter, take extrapolation" << endreq; + ATH_MSG_VERBOSE("No parameter, take extrapolation"); delete startParameters; startParameters = thisParameters->clone(); } @@ -547,10 +594,10 @@ bool InDet::InDetTrackHoleSearchTool::getMapOfHits(const Trk::Track& track , const Trk::TrackParameters *clonepar=thisParameters->clone(); std::pair<const Trk::TrackParameters*,const bool> trackparampair (clonepar,true); if (mapOfPredictions.insert(std::pair<const Identifier, std::pair<const Trk::TrackParameters*,const bool> >(id2,trackparampair)).second){ - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Added Si surface to mapOfPredictions" << endreq; + ATH_MSG_VERBOSE("Added Si surface to mapOfPredictions"); } else { - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Had this, it is a double, skipped" << endreq; + ATH_MSG_VERBOSE("Had this, it is a double, skipped"); delete clonepar; } } @@ -565,7 +612,7 @@ bool InDet::InDetTrackHoleSearchTool::getMapOfHits(const Trk::Track& track , if ( !(m_atlasId->is_pixel(id) || m_atlasId->is_sct(id)) ) { - if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Target was no longer an Si element, break loop" << endreq; + ATH_MSG_VERBOSE("Target was no longer an Si element, break loop"); break; } @@ -799,7 +846,7 @@ void InDet::InDetTrackHoleSearchTool::performHoleSearchStepWise(std::map<const I else if (iter->second->type(Trk::TrackStateOnSurface::Measurement)) ++imeasurements; else - msg(MSG::ERROR) << "Found wrong TSOS in map !!!" << endreq; + ATH_MSG_ERROR("Found wrong TSOS in map !!!"); } if ( imeasurements > 0 ) { @@ -915,6 +962,13 @@ bool InDet::InDetTrackHoleSearchTool::isSensitive(const Trk::TrackParameters* pa // this detElement is only cosidered as hole if the extrapolation of // the track plus its error hits the active material if (isActiveElement) { + + if(m_checkBadSCTChip and isBadSCTChip(id, *parameters, *siElement)) { + ATH_MSG_VERBOSE ("Track is hiting a bad SCT chip, this is not a hole candidate!"); + isgood = false; + return false; + } + ATH_MSG_VERBOSE ("SCT module is good, this is a hole candidate !"); return true; } @@ -924,7 +978,7 @@ bool InDet::InDetTrackHoleSearchTool::isSensitive(const Trk::TrackParameters* pa } } } else { - msg(MSG::WARNING) << "unknown identifier type, this should not happen !" << endreq; + ATH_MSG_WARNING("unknown identifier type, this should not happen !"); return false; } // the extrapolation of the track plus its error might not @@ -987,7 +1041,7 @@ const Trk::Track* InDet::InDetTrackHoleSearchTool::addHolesToTrack(const Trk::T DataVector doesn't have stable sort, so we need to tamper with its vector content in order to avoid sort to get caught in DV full object ownership */ - if (msgLvl(MSG::DEBUG)) msg() << "sorting vector with stable_sort "<<endreq; + ATH_MSG_DEBUG("sorting vector with stable_sort "); std::vector<const Trk::TrackStateOnSurface*>* PtrVector = const_cast<std::vector<const Trk::TrackStateOnSurface*>* > (&trackTSOS->stdcont()); stable_sort( PtrVector->begin(), PtrVector->end(), *CompFunc ); @@ -1003,3 +1057,85 @@ const Trk::Track* InDet::InDetTrackHoleSearchTool::addHolesToTrack(const Trk::T return newTrack; } +// ==================================================================================================================== +bool InDet::InDetTrackHoleSearchTool::isBadSCTChip(const Identifier& waferId, + const Trk::TrackParameters& parameters, + const InDetDD::SiDetectorElement& siElement) const { + // Check if the track passes through a bad SCT ABCD chip + // A chip is determined by the extrapolated position. + // Algorithm is based on InnerDetector/InDetMonitoring/SCT_Monitoring/src/SCTHitEffMonTool.cxx + + // Check the input + if(not m_atlasId->is_sct(waferId)) { + ATH_MSG_WARNING(waferId << " is not an SCT Identifier"); + return true; + } + + // wafer id -> module id + const Identifier moduleId(m_sct_id->module_id(waferId)); + // badChips word for the module from SCT_ConfigurationConditionsSvc + // tempMaskedChips word for the module from SCT_ByteStreamErrorSvc should also be added. + // https://its.cern.ch/jira/browse/ATLASRECTS-4011 + unsigned int badChips(m_sctConfCondSvc->badChips(moduleId)); + // badChips holds 12 bits. + // bit 0 (LSB) is chip 0 for side 0. + // bit 5 is chip 5 for side 0. + // bit 6 is chip 6 for side 1. + // bit 11 is chip 11 for side 1. + // Temporarily masked chip information from SCT_ByteStreamErrorsSvc + const unsigned int tempMaskedChips(m_sctBsErrSvc->tempMaskedChips(moduleId)); + // Information of chips with ABCD errors from SCT_ByteStreamErrorsSvc + const unsigned int abcdErrorChips(m_sctBsErrSvc->abcdErrorChips(moduleId)); + // Take 'OR' of badChips, tempMaskedChips and abcdErrorChips + badChips |= tempMaskedChips; + badChips |= abcdErrorChips; + + // If there is no bad chip, this check is done. + if(badChips==0) return false; + + const int side(m_sct_id->side(waferId)); + // Check the six chips on the side + // 0x3F = 0000 0011 1111 + // 0xFC0 = 1111 1100 0000 + // If there is no bad chip on the side, this check is done. + if((side==0 and (badChips & 0x3F)==0) or (side==1 and (badChips & 0xFC0)==0)) return false; + + // There is at least one bad chip on the side. + // Get strip id from local position + const Amg::Vector2D localPos(parameters.localPosition()); + const Identifier stripIdentifier(siElement.identifierOfPosition(localPos)); + if(not m_atlasId->is_sct(stripIdentifier)) { + ATH_MSG_WARNING(stripIdentifier << " is not an SCT Identifier"); + return true; + } + + // Get strip number from strip id + const int strip(m_sct_id->strip(stripIdentifier)); + if(strip<0 or strip>=768) { + ATH_MSG_WARNING("strip number is invalid: " << strip); + return true; + } + + // Conversion from strip to chip (specific for present SCT) + int chip(strip/128); // One ABCD chip reads 128 strips + // Relation between chip and offline strip is determined by the swapPhiReadoutDirection method. + // If swap is false + // offline strip: 0 767 + // chip on side 0: 0 1 2 3 4 5 + // chip on side 1: 11 10 9 8 7 6 + // If swap is true + // offline strip: 0 767 + // chip on side 0: 5 4 3 2 1 0 + // chip on side 1: 6 7 8 9 10 11 + const bool swap(siElement.swapPhiReadoutDirection()); + if(side==0) { + chip = swap ? 5 - chip : chip; + } else { + chip = swap ? 11 - chip : 6 + chip; + } + + // Check if the chip is bad + const bool badChip(badChips & (1<<chip)); + + return badChip; +}