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