11 #include "GaudiKernel/MsgStream.h"
26 #include "CLHEP/Random/RandFlat.h"
28 using namespace InDet;
37 m_holeSearchTool(
"InDet::InDetTrackHoleSearchTool"),
38 m_trackCollectionKey(
"Tracks"),
39 m_saveNewTracksInSG(false),
41 m_removeOverlapHitsOnly(
false),
42 m_ignoreTrackEnds(
true),
43 m_randomRemovalMode(
false),
44 m_maxNumberOfHoles(3),
45 m_rndmGenSvc(
"AthRNGSvc",
name),
46 m_randomEngineName(
"HoleSearchRnd")
49 declareProperty(
"HoleSearchTool" , m_holeSearchTool);
50 declareProperty(
"TrackCollection" , m_trackCollectionKey,
"Name of the reference track collection");
52 declareProperty(
"SaveNewTracksInSG" , m_saveNewTracksInSG ,
"Boolean: save tracks in SG");
57 declareProperty(
"RemovePIX0" , m_removeParts[Parts::kPix0] ,
"Remove hit(s) in PIXEL layer 0");
58 declareProperty(
"RemovePIX1" , m_removeParts[Parts::kPix1] ,
"Remove hit(s) in PIXEL layer 1");
59 declareProperty(
"RemovePIX2" , m_removeParts[Parts::kPix2] ,
"Remove hit(s) in PIXEL layer 2");
61 declareProperty(
"RemoveSCT0" , m_removeParts[Parts::kSct0] ,
"Remove hit(s) in SCT layer 0");
62 declareProperty(
"RemoveSCT1" , m_removeParts[Parts::kSct1] ,
"Remove hit(s) in SCT layer 1");
63 declareProperty(
"RemoveSCT2" , m_removeParts[Parts::kSct2] ,
"Remove hit(s) in SCT layer 2");
64 declareProperty(
"RemoveSCT3" , m_removeParts[Parts::kSct3] ,
"Remove hit(s) in SCT layer 3");
66 declareProperty(
"RemoveSCT4" , m_removeParts[Parts::kSct4] ,
"Remove hit(s) in SCT endcap layer 4");
67 declareProperty(
"RemoveSCT5" , m_removeParts[Parts::kSct5] ,
"Remove hit(s) in SCT endcap layer 5");
68 declareProperty(
"RemoveSCT6" , m_removeParts[Parts::kSct6] ,
"Remove hit(s) in SCT endcap layer 6");
69 declareProperty(
"RemoveSCT7" , m_removeParts[Parts::kSct7] ,
"Remove hit(s) in SCT endcap layer 7");
70 declareProperty(
"RemoveSCT8" , m_removeParts[Parts::kSct8] ,
"Remove hit(s) in SCT endcap layer 8");
72 declareProperty(
"RemoveSCTSide0" , m_removeParts[Parts::kSctSide0] ,
"Remove SCT hits on side 0");
73 declareProperty(
"RemoveSCTSide1" , m_removeParts[Parts::kSctSide1] ,
"Remove SCT hits on side 1");
75 declareProperty(
"RemoveOverlapHitsOnly" , m_removeOverlapHitsOnly,
"Only remove overlap track hits");
76 declareProperty(
"IgnoreTrackEnds" , m_ignoreTrackEnds ,
"Ignore hits at the end of the track");
78 declareProperty(
"RandomRemovalMode" , m_randomRemovalMode ,
"Randomly remove track hits (overwrites the other flags!)");
79 declareProperty(
"MaximalHoles" , m_maxNumberOfHoles ,
"Number of maximal holes to be created");
81 declare( m_trackCollectionOutputKey );
84 m_trackStats = std::vector< std::vector< unsigned int> >(0, std::vector< unsigned int>(0));
96 return StatusCode::SUCCESS;
102 if (
sc.isFailure()) {
104 return StatusCode::SUCCESS;
109 if (
sc.isFailure()) {
111 return StatusCode::SUCCESS;
116 if (
sc.isFailure()) {
118 return StatusCode::SUCCESS;
123 if (
sc.isFailure()) {
125 return StatusCode::SUCCESS;
132 if (
sc.isFailure()) {
139 return StatusCode::FAILURE;
148 return StatusCode::SUCCESS;
155 CLHEP::HepRandomEngine* engine = wrapper->
getEngine (ctx);
157 std::array<bool,Parts::kNParts> remove_parts{};
163 std::unique_ptr<TrackCollection> newTrackCollection(
m_saveNewTracksInSG ? std::make_unique<TrackCollection>() :
nullptr );
169 return StatusCode::FAILURE;
174 for ( ; trackIterator < tracks->end(); ++trackIterator) {
175 if (!((*trackIterator))) {
183 ATH_MSG_DEBUG(
"Perform hole search on unmodified track (" << *trackIterator <<
")"
184 <<
" which contains " << tsos->
size() <<
" track states" ) ;
188 auto vecTsos = std::make_unique<Trk::TrackStates>();
194 unsigned int nRemoved = 0;
196 std::vector< unsigned int > pixelHitsPerLayer = std::vector< unsigned int>(3);
197 std::vector< unsigned int > sctHitsPerLayer = std::vector< unsigned int>(9);
201 int maxPixelLayerBarrel = -1;
202 int maxPixelLayerEndcap = -1;
203 int maxSctLayerBarrel = -1;
204 int maxSctLayerEndcap = -1;
207 ATH_MSG_VERBOSE(
"Parsing track first to find end layers and maximal numbers" ) ;
208 for ( ; iTsos != iTsosEnd ; ++iTsos) {
221 maxPixelLayerBarrel = plLayer > maxPixelLayerBarrel ? plLayer : maxPixelLayerBarrel;
223 maxPixelLayerEndcap = plLayer > maxPixelLayerEndcap ? plLayer : maxPixelLayerEndcap;
229 maxSctLayerBarrel = plLayer > maxSctLayerBarrel ? plLayer : maxSctLayerBarrel;
231 maxSctLayerEndcap = plLayer > maxSctLayerEndcap ? plLayer : maxSctLayerEndcap;
236 maxPixelLayerBarrel = maxSctLayerBarrel > 0 ? -1 : maxPixelLayerBarrel;
237 maxPixelLayerEndcap = maxSctLayerEndcap > 0 ? -1 : maxPixelLayerEndcap;
239 iTsos = tsos->
begin();
243 for ( ; iTsos != iTsosEnd ; ++iTsos) {
250 unsigned int randomHoles = 0;
254 ATH_MSG_VERBOSE(
"Random mode chosen: will create " << randomHoles <<
" holes on the track.");
257 unsigned int maxPixel = maxPixelLayerBarrel > maxPixelLayerEndcap
258 ? maxPixelLayerBarrel : maxPixelLayerEndcap;
260 unsigned int maxSct = maxSctLayerBarrel > maxSctLayerEndcap
261 ? maxSctLayerBarrel : maxSctLayerEndcap;
263 int maxHit = maxPixel + maxSct;
264 int holesTriggered = 0;
267 for (
unsigned int ihole = 0; ihole < randomHoles && holesTriggered <
int(randomHoles); ++ihole){
269 unsigned int holeId = (
unsigned int)(maxHit*CLHEP::RandFlat::shoot(engine));
270 ATH_MSG_VERBOSE(
"Random mode : layer identifier " << holeId <<
" chosen." );
274 case 0 : { remove_parts[
Parts::kPix0] =
true; ++holesTriggered; };
break;
275 case 1 : { remove_parts[
Parts::kPix1] =
true; ++holesTriggered; };
break;
276 case 2 : { remove_parts[
Parts::kPix2] =
true; ++holesTriggered; };
break;
277 case 3 : { remove_parts[
Parts::kSct0] =
true; ++holesTriggered; };
break;
278 case 4 : { remove_parts[
Parts::kSct1] =
true; ++holesTriggered; };
break;
279 case 5 : { remove_parts[
Parts::kSct2] =
true; ++holesTriggered; };
break;
280 case 6 : { remove_parts[
Parts::kSct3] =
true; ++holesTriggered; };
break;
281 case 7 : { remove_parts[
Parts::kSct4] =
true; ++holesTriggered; };
break;
282 case 8 : { remove_parts[
Parts::kSct5] =
true; ++holesTriggered; };
break;
283 case 9 : { remove_parts[
Parts::kSct6] =
true; ++holesTriggered; };
break;
284 case 10 : { remove_parts[
Parts::kSct7] =
true; ++holesTriggered; };
break;
285 case 11 : { remove_parts[
Parts::kSct8] =
true; ++holesTriggered; };
break;
290 double sideDecision = CLHEP::RandFlat::shoot(engine);
291 if ( sideDecision < 1./3. )
293 else if ( sideDecision < 2./3. )
314 pixelHitsPerLayer[
layer]++;
320 ATH_MSG_VERBOSE(
"This pixel hit is not removed, it is at the track end." ) ;
344 sctHitsPerLayer[
layer]++;
353 ATH_MSG_VERBOSE(
"This SCT hit is not removed, it is at the track end." ) ;
406 vecTsos->push_back(newTsos);
409 ATH_MSG_DEBUG(
"Removed total of " << nRemoved <<
" TSoS on track." ) ;
415 unsigned int foundHoles = abs(
static_cast<int>(newHoles) -
static_cast<int>(oldHoles));
417 if ( foundHoles == nRemoved )
418 ATH_MSG_DEBUG(
"== OK : "<< nRemoved <<
" generated holes out of which all were found" ) ;
420 ATH_MSG_DEBUG(
"== PROBLEM : "<< nRemoved <<
" generated holes out of which "<< newHoles - oldHoles <<
" were found" ) ;
426 while (m_trackStats.size() < nRemoved+1) {
427 m_trackStats.emplace_back(0 );
429 while (m_trackStats[nRemoved].
size() < foundHoles+1) {
430 m_trackStats[nRemoved].push_back( 0 );
432 ATH_MSG_DEBUG(
"m_trackStats.size()= " << m_trackStats.size() );
434 m_trackStats[nRemoved][foundHoles]++;
439 newTrackCollection->push_back( newTrack );
449 if (newTrackCollection_handle.
record( std::move(newTrackCollection) ).isFailure()){
451 return StatusCode::FAILURE;
454 return StatusCode::SUCCESS;
460 ATH_MSG_INFO(
"Printing statistics for hole search validation:" ) ;
461 ATH_MSG_INFO(
" # removed hits | # tracks / found holes | ... " ) ;
462 for (
unsigned int nRemoved = 0; nRemoved < m_trackStats.size(); ++nRemoved) {
463 unsigned int nTracks = 0;
464 for (
unsigned int holes = 0;
holes < m_trackStats[nRemoved].size(); ++
holes) nTracks += m_trackStats[nRemoved][
holes];
465 if ( nTracks == 0)
continue;
466 ATH_MSG_INFO(
"Removed " << nRemoved <<
" hits from track -- found: " ) ;
467 for (
unsigned int holes = 0;
holes < m_trackStats[nRemoved].size(); ++
holes) {
469 <<
"% of tracks with " <<
holes <<
" holes (" << m_trackStats[nRemoved][
holes] <<
" / " <<
float(nTracks) <<
")") ;
473 return StatusCode::SUCCESS;
479 unsigned int nHoles(0);
481 std::unique_ptr<const Trk::TrackStates> holesOnTrack
488 nHoles = holesOnTrack->
size();
491 it!=holesOnTrack->
end(); ++
it) {
493 ATH_MSG_WARNING(
"TrackStateOnSurface from hole search tool == Null" ) ;