ATLAS Offline Software
Loading...
Searching...
No Matches
IDAlignMonResidualsAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ***************************************************************************************
6// IDAlignMonResidualsAlg.cxx
7// AUTHORS: Beate Heinemann, Tobias Golling, Ben Cooper, John Alison
8// Adapted to AthenaMT 2021-2022 by Per Johansson
9// ***************************************************************************************
10
11//main header
13
14#include "TMath.h"
15#include <cmath>
16#include <sstream>
22
28
32
35#include "TrkGeometry/Layer.h"
36#include "TrkSurfaces/Surface.h"
38
41
42
43// *********************************************************************
44// Public Methods
45// *********************************************************************
46
47IDAlignMonResidualsAlg::IDAlignMonResidualsAlg( const std::string & name, ISvcLocator* pSvcLocator ) :
48 AthMonitorAlgorithm(name, pSvcLocator),
49 m_trtcaldbTool("TRT_CalDbTool", this),
50 m_iUpdator ("Trk::KalmanUpdator"),
51 m_propagator ("Trk::RungeKuttaPropagator"),
52 m_residualPullCalculator( "Trk::ResidualPullCalculator/ResidualPullCalculator"),
53 m_trackSelection( "InDet::InDetTrackSelectionTool/TrackSelectionTool", this),
55 declareProperty("CheckRate" , m_checkrate=1000);
56 declareProperty("ITRT_CalDbTool" , m_trtcaldbTool);
57 declareProperty("iUpdator" , m_iUpdator);
58 declareProperty("propagator" , m_propagator);
59 declareProperty("TrackSelectionTool" , m_trackSelection);
60 declareProperty("ResidualPullCalculatorTool", m_residualPullCalculator);
61 declareProperty("HitQualityTool" , m_hitQualityTool);
62 declareProperty("Pixel_Manager" , m_Pixel_Manager);
63 declareProperty("SCT_Manager" , m_SCT_Manager);
64 declareProperty("ApplyTrackSelection" , m_applyTrkSel = true);
65}
66
67//---------------------------------------------------------------------------------------
68
70
72{
73 //initialize tools and services
74 ATH_MSG_DEBUG("Calling initialize() to setup tools/services");
75 StatusCode sc = setupTools();
76 if (sc.isFailure()) {
77 ATH_MSG_WARNING("Failed to initialize tools/services!");
78 return StatusCode::SUCCESS;
79 }
80 else
81 ATH_MSG_DEBUG("Successfully initialized tools/services");
82
84 ATH_CHECK( m_trtcaldbTool.retrieve() );
85
86 ATH_CHECK( m_tracksName.initialize() );
87 ATH_CHECK( m_tracksKey.initialize() );
88
101 m_pixECResidualX_2DProf = Monitored::buildToolMap<int>(m_tools, "PixResidualXEC_2DProf", 2);
102 m_pixECResidualY_2DProf = Monitored::buildToolMap<int>(m_tools, "PixResidualYEC_2DProf", 2);
139
140 ATH_MSG_DEBUG("initialize() -- completed --");
142}
143
144
145//---------------------------------------------------------------------------------------
146
147StatusCode IDAlignMonResidualsAlg::fillHistograms( const EventContext& ctx ) const
148{
149 using namespace Monitored;
150
151 ATH_MSG_DEBUG("fillHistograms() -- dealing with track collection: " << m_tracksName.key());
152
153 // For histogram naming
154 auto residualGroup = getGroup("Residuals");
155
156 //counters
157 bool hasBeenCalledThisEvent=false;
158 float mu = 0.;
159 int nTracks = 0;
160
162 auto mu_m = Monitored::Scalar<float>("mu_m", 0.0);
163 if (!hasBeenCalledThisEvent){
165 mu_m = mu;
166 hasBeenCalledThisEvent=true;
167 }
168 else
169 mu = -999;
170
171 if (m_extendedPlots){
172 fill("residualGroup", mu_m);
173 }
174
175 // Retrieving tracks
176 auto tracks = SG::makeHandle(m_tracksName, ctx);
177 if (not tracks.isValid()) {
178 ATH_MSG_ERROR(m_tracksName.key() << " could not be retrieved");
179 return StatusCode::RECOVERABLE;
180 }
181
182 //looping over tracks
183 ATH_MSG_DEBUG ("IDAlignMonResidual: Start loop on tracks. Number of tracks " << tracks->size());
184 for (const Trk::Track* trksItr: *tracks) {
185
186 // Found track?!
187 if ( !trksItr || trksItr->perigeeParameters() == nullptr ) {
188 ATH_MSG_DEBUG( "InDetAlignmentMonitoringRun3: NULL track pointer in collection" );
189 continue;
190 }
191
192 // Select tracks
193 if ( m_applyTrkSel and !m_trackSelection->accept(*trksItr) )
194 continue;
195
196 nTracks++;
197
198 //check that all TSOS of track have track parameters defined (required to compute residuals/pulls)
199 if(trackRequiresRefit(trksItr)){
200 ATH_MSG_DEBUG("Not all TSOS contain track parameters - will be missing residuals/pulls");
201 }
202 else
203 ATH_MSG_DEBUG("All TSOS of track " << nTracks << "/" << tracks->size() << " contain track parameters - Good!");
204
205 //trackStateOnSurfaces is a vector of Trk::TrackStateOnSurface objects which contain information
206 //on track at each (inner)detector surface it crosses eg hit used to fit track
207 ATH_MSG_DEBUG( "** IDAlignMonResiduals::fillHistograms() ** track: " << nTracks << " has " << trksItr->trackStateOnSurfaces()->size() << " TrkSurfaces");
208
209 int nHits = 0; //counts number of tsos from which we can define residual/pull
210 int nTSOS = -1; //counts all TSOS on the track
211
212 const Trk::Perigee* measPer = trksItr->perigeeParameters();
213 float charge = 1; if (measPer->charge() < 0) charge = -1;
214 float trkpt = -999;
215 trkpt = measPer->pT()/1000.;
216 float qpT = charge*trkpt;
217
218 //looping over the hits of the track
219 for (const Trk::TrackStateOnSurface* tsos : *trksItr->trackStateOnSurfaces()) {
220
221 ++nTSOS;
222
223 if (tsos == nullptr) {
224 ATH_MSG_DEBUG(" TSOS (hit) = " << nTSOS << " is NULL ");
225 continue;
226 }
227
228 //skipping outliers
229 ATH_MSG_DEBUG(" --> testing if hit " << nTSOS << "/" << trksItr->trackStateOnSurfaces()->size() << " is a track measurement");
231 ATH_MSG_DEBUG("Skipping TSOS " << nTSOS << " because it is an outlier (or the first TSOS on the track)");
232 continue;
233 }
234
235 const Trk::MeasurementBase* mesh =tsos->measurementOnTrack();
236 ATH_MSG_DEBUG(" --> Defined hit measurementOnTrack() for hit: " << nTSOS << "/" << trksItr->trackStateOnSurfaces()->size() << " of track " << nTracks);
237
238 //Trk::RIO_OnTrack object contains information on the hit used to fit the track at this surface
239 const Trk::RIO_OnTrack* hit = dynamic_cast <const Trk::RIO_OnTrack*>(mesh);
240 ATH_MSG_DEBUG(" --> Going to retrieve the Trk::RIO_OnTrack for hit " << nTSOS);
241 if (hit== nullptr) {
242 //for some reason the first tsos has no associated hit - maybe because this contains the defining parameters?
243 if (nHits >0) ATH_MSG_DEBUG("No hit associated with TSOS " << nTSOS);
244 continue;
245 }
246
247 ATH_MSG_DEBUG(" --> Going to retrieve the track parameters of this TSOS: " << nTSOS);
248 const Trk::TrackParameters* trackParameter = tsos->trackParameters();
249 if(trackParameter==nullptr) {
250 //if no TrackParameters for TSOS we cannot define residuals
251 ATH_MSG_DEBUG(" Skipping TSOS " << nTSOS << " because it does not have TrackParameters");
252 continue;
253 }
254
255 const AmgSymMatrix(5)* TrackParCovariance = trackParameter ? trackParameter->covariance() : nullptr;
256
257 if(TrackParCovariance==nullptr) {
258 //if no MeasuredTrackParameters the hit will not have associated convariance error matrix and will not
259 //be able to define a pull or unbiased residual (errors needed for propagation)
260 ATH_MSG_DEBUG("Skipping TSOS " << nTSOS << " because does not have MeasuredTrackParameters");
261 continue;
262 }
263
265 " --> going to define residuals and everything of TSOS #" << nTSOS << "/" <<
266 trksItr->trackStateOnSurfaces()->size());
267
268 float residualX = 9999.0;
269 float residualY = 9999.0;
270 float pullX = 9999.0;
271 float pullY = 9999.0;
272 float biasedResidualX = 9999.0;
273 float biasedResidualY = 9999.0;
274 int detType = 99;
275 int barrelEC = 99;
276 int layerDisk = 99;
277 int barrel_ec = 99;
278 int layer_or_wheel = 99;
279 int sctSide = 99;
280 int modEta = 9999;
281 int modPhi = 9999;
282
283 const Identifier & hitId = hit->identify();
284 if (m_idHelper->is_trt(hitId)) detType = 2;
285 else if (m_idHelper->is_sct(hitId)) detType = 1;
286 else if (m_idHelper->is_pixel(hitId)) detType = 0;
287 else detType = 99;
288
289 //hits with detType = 0 are no Inner Detector hits -> skip
290 if ( detType == 99) {
291 ATH_MSG_DEBUG(" --> Hit " << nTSOS << " with detector type " << detType << " is not an Inner Detector hit -> skip this hit");
292 continue;
293 }
294
295 //TRT hits: detType = 2
296 if (detType == 2) {
297 ATH_MSG_DEBUG("** IDAlignMonResidualsAlg::fillHistograms() ** Hit is from the TRT, finding residuals... ");
298 bool isTubeHit = (mesh->localCovariance()(Trk::locX, Trk::locX) > 1.0);
299 const Trk::TrackParameters* trackParameter = tsos->trackParameters();
300 //finding residuals
301 if (!trackParameter) {
302 ATH_MSG_WARNING("No TrackParameters associated with TRT TrkSurface " << nTSOS);
303 continue;
304 }
305 float hitR = hit->localParameters()[Trk::driftRadius];
306 float trketa = tsos->trackParameters()->eta();
307 float pullR = -9.9;
308
309 const Identifier& id = m_trtID->layer_id(hitId);
310 barrel_ec = m_trtID->barrel_ec(id);
311 layer_or_wheel = m_trtID->layer_or_wheel(id);
312 int phi_module = m_trtID->phi_module(id);
313
314
315 ATH_MSG_DEBUG("Found Trk::TrackParameters for hit " << nTSOS << " --> TRT hit (detType= " << detType << ")" );
316
317 //getting unbiased track parameters by removing the hit from the track and refitting
318 //std::unique_ptr <Trk::TrackParameters> trackParameterUnbiased;
319 auto trackParameterUnbiased = getUnbiasedTrackParameters(trksItr, tsos);
320
321 if (!trackParameterUnbiased) {//updator can fail
322 ATH_MSG_WARNING("Cannot define unbiased parameters for hit, skipping it.");
323 continue;
324 }
325 ATH_MSG_DEBUG(" --> TRT UnBiased TrackParameters of hit " << nTSOS << " FOUND");
326
327 float predictR = trackParameterUnbiased->parameters()[Trk::locR];
328
329 const Trk::MeasurementBase* mesh = tsos->measurementOnTrack();
330 std::optional<Trk::ResidualPull> residualPull =
331 m_residualPullCalculator->residualPull(mesh,
332 trackParameterUnbiased.get(),
334
335 if (residualPull) {
336 pullR = residualPull->pull()[Trk::locR];
337 }
338 else {
339 ATH_MSG_DEBUG(" no covariance of the track parameters given, can not calculate pull!");
340 }
341
342 //delete trackParameterUnbiased;
343
344 float residualR = hitR - predictR;
345
346 const InDet::TRT_DriftCircleOnTrack* trtCircle =
347 dynamic_cast<const InDet::TRT_DriftCircleOnTrack*>(tsos->measurementOnTrack());
348
349 if (trtCircle != nullptr) {
350 ATH_MSG_DEBUG(" fillHistograms() ** filling TRT histograms for hit/tsos #" << nTSOS
351 << " Barrel/EndCap: " << barrel_ec
352 << " layer/wheel: " << layer_or_wheel
353 << " phi: " << phi_module
354 << " Residual: " << residualR);
356 fillTRTHistograms(barrel_ec
357 , layer_or_wheel
358 , phi_module
359 , predictR
360 , hitR
361 , residualR
362 , pullR
363 , isTubeHit
364 , trketa
365 , qpT);
366 }
367 }//end-TRT hit
368
369 else { //have identified a PIXEL or SCT hit
370 if(m_doHitQuality) {
371 ATH_MSG_DEBUG("applying hit quality cuts to Silicon hit...");
372 hit = m_hitQualityTool->getGoodHit(tsos);
373 if(hit==nullptr) {
374 ATH_MSG_DEBUG("hit failed quality cuts and is rejected.");
375 continue;
376 }
377 ATH_MSG_DEBUG("hit passed quality cuts");
378 }
379 else ATH_MSG_DEBUG("hit quality cuts NOT APPLIED to Silicon hit.");
380
381 //determining Si module physical position (can modify residual calculation eg. SCT endcaps)
382 if (detType==0){//pixel
383 const Identifier& id = m_pixelID->wafer_id(hitId);
384 barrelEC = m_pixelID -> barrel_ec(id);
385 layerDisk = m_pixelID -> layer_disk(id);
386 modEta = m_pixelID->eta_module(id); //For the endcaps these are the rings
387 modPhi = m_pixelID->phi_module(id);
388 }
389 else {//sct. Since detType == 0 or detType == 1 here
390 const Identifier& id = m_sctID->wafer_id(hitId);
391 barrelEC = m_sctID->barrel_ec(id);
392 layerDisk = m_sctID->layer_disk(id);
393 modEta = m_sctID->eta_module(id);
394 modPhi = m_sctID->phi_module(id);
395 sctSide = m_sctID->side(id);
396 }
397
398 //finding residuals
399 if(trackParameter){//should always have TrackParameters since we now skip tracks with no MeasuredTrackParameters
400
401 ATH_MSG_DEBUG("Found Trk::TrackParameters " << trackParameter);
402
403 double unbiasedResXY[4] = {9999.0,9999.0,9999.0,9999.0};
404 double biasedResXY[4] = {9999.0,9999.0,9999.0,9999.0};
405
406 //finding unbiased single residuals
407 StatusCode sc;
408 sc = getSiResiduals(trksItr,tsos,true,unbiasedResXY);
409 if (sc.isFailure()) {
410 ATH_MSG_DEBUG("Problem in determining unbiased residuals! Hit is skipped.");
411 auto detType_m = Monitored::Scalar<int>( "m_detType", detType);
412 fill(residualGroup, detType_m);
413 continue;
414 }
415 else
416 ATH_MSG_DEBUG("unbiased residuals found ok");
417
418 residualX = (float)unbiasedResXY[0];
419 residualY = (float)unbiasedResXY[1];
420 pullX = (float)unbiasedResXY[2];
421 pullY = (float)unbiasedResXY[3];
422
423 //finding biased single residuals (for interest)
424 sc = getSiResiduals(trksItr,tsos,false,biasedResXY);
425 if (sc.isFailure()) {
426 ATH_MSG_DEBUG("Problem in determining biased residuals! Hit is skipped.");
427 continue;
428 }
429 else
430 ATH_MSG_DEBUG("biased residuals found ok");
431
432 biasedResidualX = (float)biasedResXY[0];
433 biasedResidualY = (float)biasedResXY[1];
434
435 }
436 else {
437 ATH_MSG_DEBUG("No TrackParameters associated with Si TrkSurface "<< nTSOS << " - Hit is probably an outlier");
438 }
439 }//end-Pixel and SCT hits
440
441 //--------------------------------------------
442 //
443 // Filling Residual Histograms for Pixel and SCT
444 //
445 //--------------------------------------------
446
447 //Common for Pixel and SCT and other variables used
448 auto si_residualx_m = Monitored::Scalar<float>( "m_si_residualx", 0.0);
449 auto si_b_residualx_m = Monitored::Scalar<float>( "m_si_b_residualx", 0.0);
450 auto si_barrel_resX_m = Monitored::Scalar<float>( "m_si_barrel_resX", 0.0);
451 auto si_barrel_resY_m = Monitored::Scalar<float>( "m_si_barrel_resY", 0.0);
452 auto si_barrel_pullX_m = Monitored::Scalar<float>( "m_si_barrel_pullX", 0.0);
453 auto si_barrel_pullY_m = Monitored::Scalar<float>( "m_si_barrel_pullY", 0.0);
454 auto si_eca_resX_m = Monitored::Scalar<float>( "m_si_eca_resX", 0.0);
455 auto si_eca_resY_m = Monitored::Scalar<float>( "m_si_eca_resY", 0.0);
456 auto si_eca_pullX_m = Monitored::Scalar<float>( "m_si_eca_pullX", 0.0);
457 auto si_eca_pullY_m = Monitored::Scalar<float>( "m_si_eca_pullY", 0.0);
458 auto si_ecc_resX_m = Monitored::Scalar<float>( "m_si_ecc_resX", 0.0);
459 auto si_ecc_resY_m = Monitored::Scalar<float>( "m_si_ecc_resY", 0.0);
460 auto si_ecc_pullX_m = Monitored::Scalar<float>( "m_si_ecc_pullX", 0.0);
461 auto si_ecc_pullY_m = Monitored::Scalar<float>( "m_si_ecc_pullY", 0.0);
462 auto residualX_m = Monitored::Scalar<float>( "m_residualX", residualX);
463 auto residualY_m = Monitored::Scalar<float>( "m_residualY", residualY);
464 auto modEta_m = Monitored::Scalar<int>( "m_modEta", modEta );
465 auto modPhi_m = Monitored::Scalar<int>( "m_modPhi", modPhi );
466 int lb = GetEventInfo(ctx)->lumiBlock();
467 auto lb_m = Monitored::Scalar<int>( "m_lb", lb );
468 auto layerDisk_m = Monitored::Scalar<float>("m_layerDisk", layerDisk);
469 auto layerDisk_si_m = Monitored::Scalar<float>("m_layerDisk_si", 0);
470
471 if (detType==0) {//filling pixel histograms
472 ATH_MSG_DEBUG(" This is a PIXEL hit " << hitId << " - filling histograms");
473
474 si_residualx_m = residualX;
475 fill(residualGroup, si_residualx_m);
476
477 if(barrelEC==0){//filling pixel barrel histograms
478 int ModEtaShift[4] = {12, 38, 60, 82};
479 int ModPhiShift[4] = {0, 24, 56, 104};
480
481 //common Si plots
482 si_b_residualx_m = residualX;
483 fill(residualGroup, si_b_residualx_m);
484
485 layerDisk_si_m = layerDisk;
486 si_barrel_resX_m = residualX;
487 si_barrel_resY_m = residualY;
488 si_barrel_pullX_m = pullX;
489 si_barrel_pullY_m = pullY;
490 fill(residualGroup, layerDisk_si_m, si_barrel_resX_m, si_barrel_resY_m, si_barrel_pullX_m, si_barrel_pullY_m);
491
492 //Pixel Residual plots
493 auto pix_b_residualx_m = Monitored::Scalar<float>( "m_pix_b_residualx", residualX);
494 auto pix_b_biased_residualx_m = Monitored::Scalar<float>( "m_pix_b_biased_residualx", biasedResidualX);
495 auto pix_b_residualy_m = Monitored::Scalar<float>( "m_pix_b_residualy", residualY);
496 auto pix_b_biased_residualy_m = Monitored::Scalar<float>( "m_pix_b_biased_residualy", biasedResidualY);
497 fill(residualGroup, pix_b_residualx_m, pix_b_biased_residualx_m, pix_b_residualy_m, pix_b_biased_residualy_m);
498 auto pix_b_residualsx_m = Monitored::Scalar<float>("m_pix_residualsx", residualX);
499 fill(m_tools[m_pixResidualX[layerDisk]], pix_b_residualsx_m);
500 fill(m_tools[m_pixResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, pix_b_residualsx_m);
501 auto pix_b_residualsy_m = Monitored::Scalar<float>("m_pix_residualsy", residualY);
502 fill(m_tools[m_pixResidualY[layerDisk]], pix_b_residualsy_m);
503 fill(m_tools[m_pixResidualY_2DProf[layerDisk]], modEta_m, modPhi_m, pix_b_residualsy_m);
504 auto pix_b_pullsx_m = Monitored::Scalar<float>("m_pix_pullsx", pullX);
505 fill(m_tools[m_pixPullX[layerDisk]], pix_b_pullsx_m);
506 auto pix_b_pullsy_m = Monitored::Scalar<float>("m_pix_pullsy", pullY);
507 fill(m_tools[m_pixPullY[layerDisk]], pix_b_pullsy_m);
508
509 //Residuals vs Eta and Phi
510 fill(m_tools[m_pixResidualXvsEta[layerDisk]], modEta_m, residualX_m );
511 fill(m_tools[m_pixResidualYvsEta[layerDisk]], modEta_m, residualY_m );
512 fill(m_tools[m_pixResidualXvsPhi[layerDisk]], modPhi_m, residualX_m );
513 fill(m_tools[m_pixResidualYvsPhi[layerDisk]], modPhi_m, residualY_m );
514
515 auto residualX_barrel_m = Monitored::Scalar<float>( "m_residualX_barrel", residualX);
516 auto residualY_barrel_m = Monitored::Scalar<float>( "m_residualY_barrel", residualY);
517 auto modPhiShift_barrel_m = Monitored::Scalar<int>( "m_modPhiShift_barrel", modPhi + ModPhiShift[layerDisk] );
518 auto modEtaShift_barrel_m = Monitored::Scalar<int>( "m_modEtaShift_barrel", modEta + ModEtaShift[layerDisk] );
519 fill(residualGroup, modPhiShift_barrel_m, residualX_barrel_m, residualY_barrel_m);
520 fill(residualGroup, modEtaShift_barrel_m, residualX_barrel_m, residualY_barrel_m);
521 }
522 else if(barrelEC==2){//three Pixel endcap disks from 0-2
523 int ModPhiShift[3] = {0, 55, 110};
524
525 //Common Si plots
526 layerDisk_si_m = layerDisk;
527 si_eca_resX_m = residualX;
528 si_eca_resY_m = residualY;
529 si_eca_pullX_m = pullX;
530 si_eca_pullY_m = pullY;
531 fill(residualGroup, layerDisk_si_m, si_eca_resX_m, si_eca_resY_m, si_eca_pullX_m, si_eca_pullY_m);
532
533 //Pixel Residual plots
534 auto pix_eca_residualx_m = Monitored::Scalar<float>( "m_pix_eca_residualx", residualX);
535 auto pix_ec_residualx_m = Monitored::Scalar<float>( "m_pix_ec_residualx", residualX);
536 fill(m_tools[m_pixECResidualX_2DProf[0]], layerDisk_m , modPhi_m, pix_ec_residualx_m);
537 auto pix_eca_residualy_m = Monitored::Scalar<float>( "m_pix_eca_residualy", residualY);
538 auto pix_ec_residualy_m = Monitored::Scalar<float>( "m_pix_ec_residualy", residualY);
539 fill(residualGroup, pix_eca_residualx_m, pix_eca_residualy_m);
540 fill(m_tools[m_pixECResidualY_2DProf[0]], layerDisk_m, modPhi_m, pix_ec_residualy_m);
541 auto pix_eca_pullx_m = Monitored::Scalar<float>( "m_pix_eca_pullx", pullX);
542 auto pix_eca_pully_m = Monitored::Scalar<float>( "m_pix_eca_pully", pullY);
543 fill(residualGroup, pix_eca_pullx_m, pix_eca_pully_m);
544
545 //Residuals vs Eta and Phi
546 auto residualX_eca_m = Monitored::Scalar<float>( "m_residualX_eca", residualX );
547 auto residualY_eca_m = Monitored::Scalar<float>( "m_residualY_eca", residualY );
548 auto modPhiShift_eca_m = Monitored::Scalar<int>( "m_modPhiShift_eca", modPhi + ModPhiShift[layerDisk]);
549 fill(m_tools[m_pixECAResidualX[layerDisk]], modPhi_m, pix_eca_residualx_m);
550 fill(m_tools[m_pixECAResidualY[layerDisk]], modPhi_m, pix_eca_residualy_m);
551 fill(residualGroup, modPhiShift_eca_m, residualX_eca_m, residualY_eca_m);
552 }
553 else if(barrelEC==-2){
554 int ModPhiShift[3] = {0, 55, 110};
555
556 //Common Si plots
557 layerDisk_si_m = layerDisk;
558 si_ecc_resX_m = residualX;
559 si_ecc_resY_m = residualY;
560 si_ecc_pullX_m = pullX;
561 si_ecc_pullY_m = pullY;
562 fill(residualGroup, layerDisk_si_m, si_ecc_resX_m, si_ecc_resY_m, si_ecc_pullX_m, si_ecc_pullY_m);
563
564 //Pixel Residual plots
565 auto pix_ecc_residualx_m = Monitored::Scalar<float>( "m_pix_ecc_residualx", residualX);
566 auto pix_ec_residualx_m = Monitored::Scalar<float>( "m_pix_ec_residualx", residualX);
567 fill(m_tools[m_pixECResidualX_2DProf[1]], layerDisk_m , modPhi_m, pix_ec_residualx_m);
568 auto pix_ecc_residualy_m = Monitored::Scalar<float>( "m_pix_ecc_residualy", residualY);
569 auto pix_ec_residualy_m = Monitored::Scalar<float>( "m_pix_ec_residualy", residualY);
570 fill(residualGroup, pix_ecc_residualx_m, pix_ecc_residualy_m);
571 fill(m_tools[m_pixECResidualY_2DProf[1]], layerDisk_m, modPhi_m, pix_ec_residualy_m);
572 auto pix_ecc_pullx_m = Monitored::Scalar<float>( "m_pix_ecc_pullx", pullX);
573 auto pix_ecc_pully_m = Monitored::Scalar<float>( "m_pix_ecc_pully", pullY);
574 fill(residualGroup, pix_ecc_pullx_m, pix_ecc_pully_m);
575
576 //Residuals vs Eta and Phi
577 auto residualX_ecc_m = Monitored::Scalar<float>( "m_residualX_ecc", residualX);
578 auto residualY_ecc_m = Monitored::Scalar<float>( "m_residualY_ecc", residualY);
579 auto modPhiShift_ecc_m = Monitored::Scalar<int>( "m_modPhiShift_ecc", modPhi + ModPhiShift[layerDisk] );
580 fill(m_tools[m_pixECCResidualX[layerDisk]], modPhi_m, pix_ecc_residualx_m);
581 fill(m_tools[m_pixECCResidualY[layerDisk]], modPhi_m, pix_ecc_residualy_m);
582 fill(residualGroup, modPhiShift_ecc_m, residualX_ecc_m, residualY_ecc_m);
583 }
584 }
585 else if (detType==1) {//filling SCT histograms
586 si_residualx_m = residualX;
587 fill(residualGroup, si_residualx_m);
588
589 ATH_MSG_DEBUG(" This is a SCT hit " << hitId << " - filling histograms");
590
591 if(barrelEC==0){//filling SCT barrel histograms
592 int ModPhiShift[4] = {0, 42, 92, 150};
593 int ModEtaShift[4] = {12, 34, 54, 78};
594
595 //common Si plots
596 si_b_residualx_m = residualX;
597 fill(residualGroup, si_b_residualx_m);
598
599 layerDisk_si_m = 4 + 2 * layerDisk + sctSide;
600 si_barrel_resX_m = residualX;
601 si_barrel_pullX_m = pullX;
602 fill(residualGroup, layerDisk_si_m, si_barrel_resX_m, si_barrel_pullX_m);
603
604 //SCT Residual plots
605 auto sct_b_residualx_m = Monitored::Scalar<float>( "m_sct_b_residualx", residualX);
606 fill(residualGroup, sct_b_residualx_m);
607 auto sct_b_biased_residualx_m = Monitored::Scalar<float>( "m_sct_b_biased_residualx", biasedResidualX);
608 auto sct_b_residualsx_m = Monitored::Scalar<float>("m_sct_residualsx", residualX);
609 fill(m_tools[m_sctResidualX[layerDisk]], sct_b_residualsx_m);
610 fill(m_tools[m_sctResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_b_residualsx_m);
611 auto sct_b_pullsx_m = Monitored::Scalar<float>("m_sct_pullsx", pullX);
612 fill(m_tools[m_sctPullX[layerDisk]], sct_b_pullsx_m);
613 if (sctSide == 0) {
614 fill(m_tools[m_sct_s0_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_b_residualsx_m);
615 } else {
616 fill(m_tools[m_sct_s1_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_b_residualsx_m);
617 }
618
619 //Residuals vs Eta and Phi
620 fill(m_tools[m_sctResidualXvsEta[layerDisk]], modEta_m, residualX_m);
621 fill(m_tools[m_sctResidualXvsPhi[layerDisk]], modPhi_m, residualX_m);
622
623 auto residualX_sct_barrel_m = Monitored::Scalar<float>( "m_residualX_sct_barrel", residualX);
624 auto modPhiShift_sct_barrel_m = Monitored::Scalar<int>( "m_modPhiShift_sct_barrel", modPhi + ModPhiShift[layerDisk] );
625 auto modEtaShift_sct_barrel_m = Monitored::Scalar<int>( "m_modEtaShift_sct_barrel", modEta + ModEtaShift[layerDisk] );
626 fill(residualGroup, modPhiShift_sct_barrel_m, modEtaShift_sct_barrel_m, residualX_sct_barrel_m);
627 } // end SCT barrel
628
629 else if(barrelEC==2){//nine SCT endcap disks from 0-8
630 int Nmods = 52;
631 int gap_sct = 10;
632
633 //Common Si plots
634 layerDisk_si_m = 3 + 2 * layerDisk + sctSide;
635 si_eca_resX_m = residualX;
636 si_eca_pullX_m = pullX;
637 fill(residualGroup, layerDisk_si_m, si_eca_resX_m, si_eca_pullX_m);
638
639 //SCT Residual plots
640 auto sct_eca_residualx_m = Monitored::Scalar<float>( "m_sct_eca_residualx", residualX);
641 fill(m_tools[m_sctECAResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_eca_residualx_m);
642 auto sct_eca_pullx_m = Monitored::Scalar<float>( "m_sct_eca_pullx", pullX);
643 fill(residualGroup, sct_eca_residualx_m, sct_eca_pullx_m);
644 if (sctSide == 0) {
645 fill(m_tools[m_sctECA_s0_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_eca_residualx_m);
646 } else {
647 fill(m_tools[m_sctECA_s1_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_eca_residualx_m);
648 }
649
650 //Residuals vs Eta and Phi
651 auto residualX_sct_eca_m = Monitored::Scalar<float>( "m_residualX_sct_eca", residualX);
652 auto modPhiShift_sct_eca_m = Monitored::Scalar<int>( "m_modPhiShift_sct_eca", modPhi + layerDisk * (gap_sct + Nmods) );
653 fill(residualGroup, modPhiShift_sct_eca_m, residualX_sct_eca_m);
654 } // end SCT end-cap A
655
656 else if(barrelEC==-2){//start SCT end-cap C
657 int Nmods = 52;
658 int gap_sct = 10;
659
660 //Common Si plots
661 layerDisk_si_m = 3 + 2 * layerDisk + sctSide;
662 si_ecc_resX_m = residualX;
663 si_ecc_pullX_m = pullX;
664 fill(residualGroup, layerDisk_si_m, si_ecc_resX_m, si_ecc_pullX_m);
665
666 //SCT Residual plots
667 auto sct_ecc_residualx_m = Monitored::Scalar<float>( "m_sct_ecc_residualx", residualX);
668 fill(m_tools[m_sctECCResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_ecc_residualx_m);
669 auto sct_ecc_pullx_m = Monitored::Scalar<float>( "m_sct_ecc_pullx", pullX);
670 fill(residualGroup, sct_ecc_residualx_m, sct_ecc_pullx_m);
671 if (sctSide == 0) {
672 fill(m_tools[m_sctECC_s0_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_ecc_residualx_m);
673 } else {
674 fill(m_tools[m_sctECC_s1_ResidualX_2DProf[layerDisk]], modEta_m, modPhi_m, sct_ecc_residualx_m);
675 }
676
677 //Residuals vs Eta and Phi
678 auto residualX_sct_ecc_m = Monitored::Scalar<float>( "m_residualX_sct_ecc", residualX);
679 auto modPhiShift_sct_ecc_m = Monitored::Scalar<int>( "m_modPhiShift_sct_ecc", modPhi + layerDisk * (gap_sct + Nmods) );
680 fill(residualGroup, modPhiShift_sct_ecc_m, residualX_sct_ecc_m);
681 } // end SCT end-cap C
682 }// end of SCT
683 ++nHits;
684 //++nHitsEvent;
685 }//end of loop on track surfaces
686 } // end of loop on tracks
687
688 ATH_MSG_DEBUG("Number of tracks : "<< nTracks);
689
690 return StatusCode::SUCCESS;
691}
692
693//__________________________________________________________________________
694StatusCode IDAlignMonResidualsAlg::getSiResiduals(const Trk::Track* track, const Trk::TrackStateOnSurface* tsos, bool unBias, double* results) const
695{
696 if (!m_doPulls) return StatusCode::FAILURE;
697
698 StatusCode sc = StatusCode::SUCCESS;
699
700 double residualX = -9999.0;
701 double residualY = -9999.0;
702 double pullX = -9999.0;
703 double pullY = -9999.0;
704
705 //extract the hit object from the tsos
706 const Trk::MeasurementBase* mesh =tsos->measurementOnTrack();
707 const Trk::RIO_OnTrack* hit = dynamic_cast <const Trk::RIO_OnTrack*>(mesh);
708
709 //get the unbiased track parameters (can fail if no MeasuredTrackParameters exists)
710 std::unique_ptr <Trk::TrackParameters> trackParameterUnbiased{};
711 if(unBias) trackParameterUnbiased = getUnbiasedTrackParameters(track,tsos);
712
713 //updator can fail in defining unbiased parameters, in which case we use biased
714 std::unique_ptr <Trk::TrackParameters> trackParameterForResiduals{};
715 if(trackParameterUnbiased){
716 trackParameterForResiduals = std:: move(trackParameterUnbiased);
717 }
718 else {
719 //use the original biased track parameters
720 std::unique_ptr <Trk::TrackParameters> uTrkPtr = tsos->trackParameters()->uniqueClone();
721 trackParameterForResiduals = std::move(uTrkPtr);
722 }
723
724 if (!m_residualPullCalculator.empty()) {
725
726 if (hit && trackParameterForResiduals) {
727
728 ATH_MSG_DEBUG(" got hit and track parameters ");
729
730 std::optional<Trk::ResidualPull> residualPull = std::nullopt;
731 if(unBias) residualPull = m_residualPullCalculator->residualPull(mesh, trackParameterForResiduals.get(), Trk::ResidualPull::Unbiased);
732 else residualPull = m_residualPullCalculator->residualPull(mesh, trackParameterForResiduals.get(), Trk::ResidualPull::Biased);
733
734 ATH_MSG_DEBUG(" got hit and track parameters...done ");
735 if (residualPull) {
736
737 ATH_MSG_DEBUG(" got residual pull object");
738 residualX = residualPull->residual()[Trk::loc1];
739 if(residualPull->isPullValid()) pullX = residualPull->pull()[Trk::loc1];
740 else {
741 ATH_MSG_DEBUG("ResidualPullCalculator finds invalid X Pull!!!");
742 sc = StatusCode::FAILURE;
743 }
744
745 if (residualPull->dimension() >= 2){
746
747 ATH_MSG_DEBUG(" residualPull dim >= 2");
748 residualY = residualPull->residual()[Trk::loc2];
749
750 ATH_MSG_DEBUG(" residual Y = " << residualY);
751 if(residualPull->isPullValid()) pullY = residualPull->pull()[Trk::loc2];
752 else {
753 ATH_MSG_DEBUG("ResidualPullCalculator finds invalid Y Pull!!!");
754 sc = StatusCode::FAILURE;
755 }
756 }
757 }
758 else {
759 ATH_MSG_DEBUG("ResidualPullCalculator failed!");
760 sc = StatusCode::FAILURE;
761 }
762 }
763 }
764
765 // for SCT modules the residual pull calculator only finds the (rotated) Rphi residual
766 // for each of the SCT sides; residualPull->dimension()==1 always.
767
768 //std::pair <double, double> result(residualX, residualY);
769 results[0] = residualX;
770 results[1] = residualY;
771 results[2] = pullX;
772 results[3] = pullY;
773
774 if(pullX!=pullX || pullY!=pullY){
775 ATH_MSG_DEBUG("ResidualPullCalculator finds Pull=NAN!!!");
776 sc = StatusCode::FAILURE;
777 }
778
779 return sc;
780
781}
782
783
784void IDAlignMonResidualsAlg::fillTRTHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool isTubeHit, float trketa, float qpT) const {
785 bool LRcorrect = (predictR * hitR > 0);
786
787 //Need to correct the TRT residual on the C-side.
788 if (barrel_ec == -1) {
789 residualR *= -1;
790 }
791
792 if (barrel_ec == 1 || barrel_ec == -1)
794 , layer_or_wheel
795 , phi_module
796 , predictR
797 , hitR
798 , residualR
799 , pullR
800 , LRcorrect
801 , isTubeHit
802 , trketa);
803
805 if (barrel_ec == 2 || barrel_ec == -2)
807 , layer_or_wheel
808 , phi_module
809 , predictR
810 , hitR
811 , residualR
812 , pullR
813 , LRcorrect
814 , isTubeHit
815 , trketa
816 , qpT);
817
818 return;
819}
820
821//Filling barrel histograms
822void IDAlignMonResidualsAlg::fillTRTBarrelHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool LRcorrect, bool isTubeHit, float trketa) const {
823
824 //Loop over the barrel sides
825 for (unsigned int side = 0; side < 3; ++side) {
826 bool doFill = false;
827 if (!side) doFill = true;
828 else if (side == 1 && barrel_ec == 1) doFill = true;
829 else if (side == 2 && barrel_ec == -1) doFill = true;
830
831 if (!doFill) continue;
832
833 auto trt_b_PredictedR_m = Monitored::Scalar<float>( "m_trt_b_PredictedR", predictR);
834 fill(m_tools[m_trtBPredictedR[side]], trt_b_PredictedR_m);
835 auto trt_b_MeasuredR_m = Monitored::Scalar<float>( "m_trt_b_MeasuredR", hitR);
836 fill(m_tools[m_trtBMeasuredR[side]], trt_b_MeasuredR_m);
837 auto trt_b_residualR_m = Monitored::Scalar<float>( "m_trt_b_residualR", residualR);
838 fill(m_tools[m_trtBResidualR[side]], trt_b_residualR_m);
839 auto trt_b_pullR_m = Monitored::Scalar<float>( "m_trt_b_pullR", pullR);
840 fill(m_tools[m_trtBPullR[side]], trt_b_pullR_m);
841
842 if (!isTubeHit) {
843 auto trt_b_residualR_notube_m = Monitored::Scalar<float>( "m_trt_b_residualR_notube", residualR);
844 fill(m_tools[m_trtBResidualRNoTube[side]], trt_b_residualR_notube_m);
845 auto trt_b_pullR_notube_m = Monitored::Scalar<float>( "m_trt_b_pullR_notube", pullR);
846 fill(m_tools[m_trtBPullRNoTube[side]], trt_b_pullR_notube_m);
847 }
848
849 auto trt_b_lr_m = Monitored::Scalar<float>( "m_trt_b_lr", 0.0);
850 if (LRcorrect && !isTubeHit) trt_b_lr_m = 0.5;
851 if (LRcorrect && isTubeHit) trt_b_lr_m = 1.5;
852 if (!LRcorrect && !isTubeHit) trt_b_lr_m = 2.5;
853 if (!LRcorrect && isTubeHit) trt_b_lr_m = 3.5;
854 fill(m_tools[m_trtBLR[side]], trt_b_lr_m);
855
856 auto trt_b_aveResVsTrackEta_m = Monitored::Scalar<float>( "m_trt_b_aveResVsTrackEta", trketa);
857 auto trt_b_PhiSec_m = Monitored::Scalar<float>( "m_trt_b_PhiSec", phi_module);
858 auto trt_b_lrVsPhiSec_m = Monitored::Scalar<float>( "m_trt_b_lrVsPhiSec", LRcorrect);
859 fill(m_tools[m_trtBResVsEta[side][layer_or_wheel]], trt_b_aveResVsTrackEta_m, trt_b_residualR_m);
860 fill(m_tools[m_trtBResVsPhiSec[side][layer_or_wheel]], trt_b_PhiSec_m, trt_b_residualR_m);
861 trt_b_lrVsPhiSec_m = LRcorrect;
862 fill(m_tools[m_trtBLRVsPhiSec[side][layer_or_wheel]], trt_b_PhiSec_m, trt_b_lrVsPhiSec_m);
863
864 }//Over sides
865
866 return;
867}//fillTRTBarrelHistograms
868
869void IDAlignMonResidualsAlg::fillTRTEndcapHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool LRcorrect, bool isTubeHit, float trketa, float qpT) const {
870 for (unsigned int endcap = 0; endcap < 2; ++endcap) {
871 bool doFill = false;
872 if (!endcap && barrel_ec == 2) doFill = true;
873 else if (endcap && barrel_ec == -2) doFill = true;
874
875 if (!doFill) continue;
876
877 auto trt_ec_PredictedR_m = Monitored::Scalar<float>( "m_trt_ec_PredictedR", predictR);
878 fill(m_tools[m_trtECPredictedR[endcap]], trt_ec_PredictedR_m);
879 auto trt_ec_MeasuredR_m = Monitored::Scalar<float>( "m_trt_ec_MeasuredR", hitR);
880 fill(m_tools[m_trtECMeasuredR[endcap]], trt_ec_MeasuredR_m);
881 auto trt_ec_residualR_m = Monitored::Scalar<float>( "m_trt_ec_residualR", residualR);
882 fill(m_tools[m_trtECResidualR[endcap]], trt_ec_residualR_m);
883 auto trt_ec_pullR_m = Monitored::Scalar<float>( "m_trt_ec_pullR", pullR);
884 fill(m_tools[m_trtECPullR[endcap]], trt_ec_pullR_m);
885
886 //Filling TRT 2Dprof histograms
887 auto layer_or_wheel_m = Monitored::Scalar<float>("m_layer_or_wheel", layer_or_wheel);
888 auto pT_m = Monitored::Scalar<float>( "m_pT", qpT );
889 fill(m_tools[m_trtECResVsPt_2DProf[endcap]], layer_or_wheel_m, pT_m, trt_ec_residualR_m);
890
891 if (!isTubeHit) {
892 auto trt_ec_pullR_notube_m = Monitored::Scalar<float>( "m_trt_ec_pullR_notube", pullR);
893 fill(m_tools[m_trtECPullRNoTube[endcap]], trt_ec_pullR_notube_m);
894 auto trt_ec_residualR_notube_m = Monitored::Scalar<float>( "m_trt_ec_residualR_notube", residualR);
895 fill(m_tools[m_trtECResidualRNoTube[endcap]], trt_ec_residualR_notube_m);
896 }
897
898 auto trt_ec_lr_m = Monitored::Scalar<float>( "m_trt_ec_lr", 0.0);
899 if (LRcorrect && !isTubeHit) trt_ec_lr_m = 0.5;
900 else if (LRcorrect && isTubeHit) trt_ec_lr_m = 1.5;
901 else if (!LRcorrect && !isTubeHit) trt_ec_lr_m = 2.5;
902 else if (!LRcorrect && isTubeHit) trt_ec_lr_m = 3.5;
903 fill(m_tools[m_trtECLR[endcap]], trt_ec_lr_m);
904
905 auto trt_ec_aveResVsTrackEta_m = Monitored::Scalar<float>( "m_trt_ec_aveResVsTrackEta", trketa);
906 fill(m_tools[m_trtECResVsEta[endcap]], trt_ec_aveResVsTrackEta_m, trt_ec_residualR_m);
907
908 auto trt_ec_phi_m = Monitored::Scalar<float>( "m_trt_ec_phi", phi_module);
909 fill(m_tools[m_trtECResVsPhiSec[endcap]], trt_ec_phi_m, trt_ec_residualR_m);
910 auto trt_ec_lrVsPhiSec_m = Monitored::Scalar<float>( "m_trt_ec_lrVsPhiSec", LRcorrect);
911 fill(m_tools[m_trtECLRVsPhiSec[endcap]], trt_ec_phi_m, trt_ec_lrVsPhiSec_m);
912 }
913
914 return;
915}
916
917//---------------------------------------------------------------------------------------
918std::unique_ptr <Trk::TrackParameters> IDAlignMonResidualsAlg::getUnbiasedTrackParameters(const Trk::Track* trkPnt, const Trk::TrackStateOnSurface* tsos) const
919{
920
921 std::unique_ptr <Trk::TrackParameters> TrackParams{};
922 std::unique_ptr <Trk::TrackParameters> UnbiasedTrackParams{};
923 std::unique_ptr <Trk::TrackParameters> PropagatedTrackParams{};
924 std::unique_ptr <Trk::TrackParameters> OtherSideUnbiasedTrackParams{};
925
926 //controls if the SCT residuals will be 'truly' unbiased - removing also the opposite side hit.
927 bool trueUnbiased = true;
928
929 Identifier surfaceID;
930
931
932 ATH_MSG_VERBOSE("original track parameters: " << *(tsos->trackParameters()) );
933 ATH_MSG_VERBOSE("Trying to unbias track parameters.");
934
935 const Trk::RIO_OnTrack* hitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(tsos->measurementOnTrack());
936
937 if (hitOnTrack != nullptr) surfaceID = hitOnTrack->identify();
938
939
940 // if SCT Hit and TrueUnbiased then remove other side hit first
941 if (surfaceID.is_valid() && trueUnbiased && m_idHelper->is_sct(surfaceID)) { //there's no TrueUnbiased for non-SCT (pixel) hits)
942 ATH_MSG_VERBOSE("Entering True Unbiased loop.");
943
944 // check if other module side was also hit and try to remove other hit as well
945 const Trk::TrackStateOnSurface* OtherModuleSideHit(nullptr);
946 const Identifier waferID = m_sctID->wafer_id(surfaceID);
947 const IdentifierHash waferHash = m_sctID->wafer_hash(waferID);
948 IdentifierHash otherSideHash;
949 m_sctID->get_other_side(waferHash, otherSideHash);
950 const Identifier OtherModuleSideID = m_sctID->wafer_id(otherSideHash);
951
952 for (const Trk::TrackStateOnSurface* TempTsos : *trkPnt->trackStateOnSurfaces()) {
953
954 const Trk::RIO_OnTrack* TempHitOnTrack = dynamic_cast <const Trk::RIO_OnTrack*>(TempTsos->measurementOnTrack());
955 if (TempHitOnTrack != nullptr) {
956 if (m_sctID->wafer_id(TempHitOnTrack->identify()) == OtherModuleSideID) {
957 ATH_MSG_VERBOSE("True unbiased residual. Removing OtherModuleSide Hit " << m_idHelper->show_to_string(OtherModuleSideID,nullptr,'/') );
958 OtherModuleSideHit = TempTsos;
959 }
960 }
961 }
962
963 if (OtherModuleSideHit) {
964 const Trk::TrackParameters* OMSHmeasuredTrackParameter = OtherModuleSideHit->trackParameters();
965 const AmgSymMatrix(5)* OMSHmeasuredTrackParameterCov = OMSHmeasuredTrackParameter ? OMSHmeasuredTrackParameter->covariance() : nullptr;
966
967 // check that the hit on the other module side has measuredtrackparameters, otherwise it cannot be removed from the track
968 if (OMSHmeasuredTrackParameterCov) {
969 ATH_MSG_VERBOSE("OtherSideTrackParameters: " << *(OtherModuleSideHit->trackParameters()) );
970 OtherSideUnbiasedTrackParams = m_iUpdator->removeFromState(*(OtherModuleSideHit->trackParameters()),
971 OtherModuleSideHit->measurementOnTrack()->localParameters(),
972 OtherModuleSideHit->measurementOnTrack()->localCovariance());
973
974 if (OtherSideUnbiasedTrackParams) {
975 ATH_MSG_VERBOSE("Unbiased OtherSideTrackParameters: " << *OtherSideUnbiasedTrackParams);
976
977
978 const Trk::Surface* TempSurface = &(OtherModuleSideHit->measurementOnTrack()->associatedSurface());
979
980 const Trk::MagneticFieldProperties* TempField = nullptr;
981 if (TempSurface)
982 {
983 ATH_MSG_VERBOSE("After OtherSide surface call. Surface exists");
984 if (TempSurface->associatedLayer())
985 {
986 ATH_MSG_VERBOSE("TempSurface->associatedLayer() exists");
987 if(TempSurface->associatedLayer()->enclosingTrackingVolume())
988 {
989 ATH_MSG_VERBOSE("TempSurface->associatedLayer()->enclosingTrackingVolume exists");
990
991 TempField = dynamic_cast <const Trk::MagneticFieldProperties*>(TempSurface->associatedLayer()->enclosingTrackingVolume());
992 ATH_MSG_VERBOSE("After MagneticFieldProperties cast");
993 ATH_MSG_VERBOSE("Before other side unbiased propagation");
994
995 if (TempSurface->associatedLayer() && TempField) PropagatedTrackParams = m_propagator->propagate(
996 Gaudi::Hive::currentContext(),
997 *OtherSideUnbiasedTrackParams,
999 Trk::anyDirection, false,
1000 *TempField,
1002
1003 } else {
1004 ATH_MSG_VERBOSE("TempSurface->associatedLayer()->enclosingTrackingVolume does not exist");
1005 }
1006 } else {
1007 ATH_MSG_VERBOSE("TempSurface->associatedLayer() does not exist");
1008 }
1009 } else {
1010 ATH_MSG_VERBOSE("After OtherSide surface call. Surface does not exist");
1011 }
1012
1013 ATH_MSG_VERBOSE("After other side unbiased propagation");
1014 if (PropagatedTrackParams) {
1015 ATH_MSG_VERBOSE("Propagated Track Parameters: " << *PropagatedTrackParams);
1016 } else {
1017 ATH_MSG_DEBUG("Propagation of unbiased OtherSideParameters failed");
1018 }
1019 } else {
1020 ATH_MSG_DEBUG("RemoveFromState did not work for OtherSideParameters");
1021 }
1022 } else {
1023 ATH_MSG_VERBOSE("No OtherModuleSideHit Measured Track Parameters found");
1024 }
1025 } else {
1026 ATH_MSG_VERBOSE("No OtherModuleSideHit found");
1027 }
1028 }
1029
1030 // if propagation failed or no TrueUnbiased or no SCT then use original TrackParams
1031 if (!PropagatedTrackParams) {
1032 std::unique_ptr <Trk::TrackParameters> uTrkPtr = tsos->trackParameters()->uniqueClone();
1033 PropagatedTrackParams = std::move(uTrkPtr);
1034 }
1035
1036 UnbiasedTrackParams =
1038 ->removeFromState(*PropagatedTrackParams,
1041
1042 if (UnbiasedTrackParams) {
1043 if(surfaceID.is_valid() ) ATH_MSG_VERBOSE("Unbiased residual. Removing original Hit " << m_idHelper->show_to_string(surfaceID,nullptr,'/') );
1044 ATH_MSG_VERBOSE("Unbiased Trackparameters: " << *UnbiasedTrackParams);
1045
1046 TrackParams = std::move(UnbiasedTrackParams);
1047
1048 } else { // Unbiasing went awry.
1049 ATH_MSG_WARNING("RemoveFromState did not work, using original TrackParameters");
1050
1051 std::unique_ptr <Trk::TrackParameters> uTrkPtr = tsos->trackParameters()->uniqueClone();
1052 TrackParams = std::move(uTrkPtr);
1053 }
1054
1055 return TrackParams;
1056
1057}
1058
1059//---------------------------------------------------------------------------------------
1061{
1062 //initializing tools
1063
1064 ATH_MSG_DEBUG("In setupTools()");
1065
1066 StatusCode sc;
1067 //Get the PIX manager from the detector store
1069 ATH_MSG_DEBUG("Initialized PixelManager");
1070
1071 //Get the SCT manager from the detector store
1073 ATH_MSG_DEBUG("Initialized SCTManager");
1074
1075 ATH_CHECK(detStore()->retrieve(m_pixelID, "PixelID"));
1076 ATH_MSG_DEBUG("Initialized PixelIDHelper");
1077
1078 ATH_CHECK(detStore()->retrieve(m_sctID, "SCT_ID"));
1079 ATH_MSG_DEBUG("Initialized SCTIDHelper");
1080
1081 ATH_CHECK(detStore()->retrieve(m_trtID, "TRT_ID"));
1082 ATH_MSG_DEBUG("Initialized TRTIDHelper");
1083
1084 //ID Helper
1085 ATH_CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
1086
1087 ATH_CHECK(m_iUpdator.retrieve());
1088 ATH_MSG_DEBUG("Retrieved iUpdator tool " << m_iUpdator);
1089
1090 if (m_propagator.retrieve().isFailure()) {
1091 ATH_MSG_WARNING("Can not retrieve Propagator tool of type " << m_propagator.typeAndName());
1092 return StatusCode::FAILURE;
1093 } else ATH_MSG_INFO("Retrieved tool " << m_propagator.typeAndName());
1094
1095 if (m_trackSelection.retrieve().isFailure()) {
1096 ATH_MSG_WARNING("Can not retrieve TrackSelection tool of type " << m_trackSelection.typeAndName());
1097 return StatusCode::FAILURE;
1098 } else ATH_MSG_INFO("Retrieved tool " << m_trackSelection.typeAndName());;
1099
1100 if (m_residualPullCalculator.empty()) {
1101 ATH_MSG_DEBUG("No residual/pull calculator for general hit residuals configured.");
1102 ATH_MSG_DEBUG("It is recommended to give R/P calculators to the det-specific tool handle lists then.");
1103 m_doPulls = false;
1104 ATH_CHECK(m_residualPullCalculator.retrieve( DisableTool{!m_doPulls} ));
1105 } else if (m_residualPullCalculator.retrieve().isFailure()) {
1106 ATH_MSG_WARNING("Could not retrieve "<< m_residualPullCalculator << " (to calculate residuals and pulls) ");
1107 m_doPulls = false;
1108
1109 } else {
1110 ATH_MSG_DEBUG("Generic hit residuals&pulls will be calculated in one or both available local coordinates");
1111 m_doPulls = true;
1112 }
1113
1114 if (m_hitQualityTool.empty()) {
1115 ATH_MSG_DEBUG("No hit quality tool configured - not hit quality cuts will be imposed");
1116 m_doHitQuality = false;
1117 ATH_CHECK(m_hitQualityTool.retrieve( DisableTool{!m_doHitQuality} ));
1118 } else if (m_hitQualityTool.retrieve().isFailure()) {
1119 ATH_MSG_WARNING("Could not retrieve " << m_hitQualityTool << " to apply hit quality cuts to Si hits");
1120 m_doHitQuality = false;
1121 } else {
1122 ATH_MSG_DEBUG("Hit quality tool setup - hit quality cuts will be applied to Si hits");
1123 m_doHitQuality = true;
1124 }
1125
1126
1127 return StatusCode::SUCCESS;
1128}
1129
1130//--------------------------------------------------------------------------------------------
1132{
1133
1134 // Checks to see if any of the measurements on track do not have track parameters associated
1135 // (as happens for certain track collections in e.g. ESD)
1136 // If this is the case we cannot define residuals and track needs to be refitted (return true)
1137
1138 bool refitTrack = false;
1139
1140 int nHits = 0;
1141 int nHitsNoParams = 0;
1142
1143 ATH_MSG_DEBUG("Testing track to see if requires refit...");
1144
1145 for (const Trk::TrackStateOnSurface* tsos : *track->trackStateOnSurfaces()) {
1146
1147 if(tsos == nullptr) continue;
1148
1149 //skipping outliers
1150 if(!tsos->type(Trk::TrackStateOnSurface::Measurement)) continue;
1151
1152 const Trk::MeasurementBase* mesh =tsos->measurementOnTrack();
1153 if (mesh==nullptr) continue;
1154 const Trk::RIO_OnTrack* hit = dynamic_cast <const Trk::RIO_OnTrack*>(mesh);
1155 if (hit==nullptr) continue;
1156
1157 ++nHits;
1158
1159 const Trk::TrackParameters* trackParameter = tsos->trackParameters();
1160 if(trackParameter==nullptr) ++nHitsNoParams; //if no TrackParameters for TSOS we cannot define residuals
1161
1162 }
1163
1164 ATH_MSG_DEBUG("Total nhits on track (excluding outliers) = " << nHits << ", nhits without trackparameters = " << nHitsNoParams);
1165
1166 if(nHitsNoParams>0) {
1167 refitTrack = true;
1168 ATH_MSG_DEBUG("Track Requires refit to get residuals!!!");
1169 }
1170
1171 return refitTrack;
1172}
1173
1174//--------------------------------------------------------------------------------------------
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
double charge(const T &p)
Definition AtlasPID.h:997
#define AmgSymMatrix(dim)
static Double_t sc
static const uint32_t nHits
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
This is an Identifier helper class for the TRT subdetector.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
StatusCode getSiResiduals(const Trk::Track *, const Trk::TrackStateOnSurface *, bool, double *) const
void fillTRTHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool isTubeHit, float trketa, float qpT) const
std::vector< int > m_trtBPredictedR
ToolHandle< InDet::IInDetTrackSelectionTool > m_trackSelection
const InDetDD::SCT_DetectorManager * m_SCT_Mgr
std::vector< int > m_trtBResidualRNoTube
ToolHandle< Trk::IUpdator > m_iUpdator
std::vector< int > m_sct_s1_ResidualX_2DProf
std::vector< int > m_pixResidualYvsEta
std::vector< int > m_pixResidualYvsPhi
std::vector< int > m_pixECResidualY_2DProf
std::vector< int > m_sctECC_s0_ResidualX_2DProf
std::vector< int > m_pixResidualX_2DProf
std::vector< int > m_trtECResVsPt_2DProf
std::vector< int > m_sctECC_s1_ResidualX_2DProf
virtual StatusCode initialize() override
initialize
std::vector< int > m_sctResidualXvsEta
std::vector< std::vector< int > > m_trtBLRVsPhiSec
std::vector< int > m_trtBMeasuredR
std::vector< int > m_sctResidualXvsPhi
std::vector< int > m_trtECResVsPhiSec
std::vector< int > m_pixResidualX
std::vector< int > m_pixResidualY_2DProf
std::vector< int > m_pixResidualXvsPhi
std::vector< int > m_sctECA_s0_ResidualX_2DProf
void fillTRTEndcapHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool LRcorrect, bool isTubeHit, float trketa, float qpT) const
bool trackRequiresRefit(const Trk::Track *) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
std::vector< int > m_pixResidualY
const AtlasDetectorID * m_idHelper
ToolHandle< IInDetAlignHitQualSelTool > m_hitQualityTool
std::vector< int > m_pixECCResidualX
std::vector< int > m_pixResidualXvsEta
std::vector< int > m_trtECPredictedR
std::unique_ptr< Trk::TrackParameters > getUnbiasedTrackParameters(const Trk::Track *, const Trk::TrackStateOnSurface *) const
const InDetDD::PixelDetectorManager * m_PIX_Mgr
std::vector< int > m_trtECResidualR
void fillTRTBarrelHistograms(int barrel_ec, int layer_or_wheel, int phi_module, float predictR, float hitR, float residualR, float pullR, bool LRcorrect, bool isTubeHit, float trketa) const
IDAlignMonResidualsAlg(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< int > m_sctECA_s1_ResidualX_2DProf
ToolHandle< ITRT_CalDbTool > m_trtcaldbTool
std::vector< int > m_trtECMeasuredR
std::vector< int > m_sct_s0_ResidualX_2DProf
ToolHandle< Trk::IResidualPullCalculator > m_residualPullCalculator
The residual and pull calculator tool handle.
std::vector< int > m_pixECAResidualX
ToolHandle< Trk::IPropagator > m_propagator
std::vector< int > m_pixECCResidualY
std::vector< int > m_sctECCResidualX_2DProf
std::vector< int > m_pixECAResidualY
std::vector< std::vector< int > > m_trtBResVsEta
std::vector< int > m_sctECAResidualX_2DProf
std::vector< std::vector< int > > m_trtBResVsPhiSec
std::vector< int > m_pixECResidualX_2DProf
std::vector< int > m_sctResidualX_2DProf
std::vector< int > m_trtECLRVsPhiSec
std::vector< int > m_trtECResidualRNoTube
std::vector< int > m_trtBResidualR
std::vector< int > m_sctResidualX
SG::ReadHandleKey< TrackCollection > m_tracksKey
SG::ReadHandleKey< TrackCollection > m_tracksName
std::vector< int > m_trtBPullRNoTube
std::vector< int > m_trtECResVsEta
std::vector< int > m_trtECPullRNoTube
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
Declare a monitored scalar variable.
const TrackingVolume * enclosingTrackingVolume() const
get the confining TrackingVolume
magnetic field properties to steer the behavior of the extrapolation
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
double charge() const
Returns the charge.
double pT() const
Access method for transverse momentum.
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
@ Biased
RP with track state including the hit.
@ Unbiased
RP with track state that has measurement not included.
Abstract Base Class for tracking surfaces.
const Trk::Layer * associatedLayer() const
return the associated Layer
represents the track state (measurement, material, fit parameters and quality) at a surface.
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
int lb
Definition globals.cxx:23
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
virtual float lbAverageInteractionsPerCrossing(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the average mu, i.e.
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
@ anyDirection
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ driftRadius
trt, straws
Definition ParamDefs.h:53
@ locX
Definition ParamDefs.h:37
@ locR
Definition ParamDefs.h:44
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ loc1
Definition ParamDefs.h:34
ParametersBase< TrackParametersDim, Charged > TrackParameters