ATLAS Offline Software
Loading...
Searching...
No Matches
InDetBeamSpotVertex.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/ITHistSvc.h"
10#include <random>
11#include <cmath>
12#include <algorithm>
13#include <mutex>
14#include <stdexcept>
15
16using namespace InDet;
17
18namespace BeamSpot {
19 std::mutex mutex;
20 const std::vector< BeamSpot::VrtHolder > * vertexData ATLAS_THREAD_SAFE;
21 void myFCN_LLsolver( Int_t &, Double_t *, Double_t &, Double_t *, Int_t); // FCN for LL
22 void myFCN_LLsolverNorm( Int_t &, Double_t *, Double_t &, Double_t *, Int_t); // FCN for LL
23 double norm_xMin(-1e8), norm_xMax(1e8), norm_yMin(-1e8), norm_yMax(1e8) , norm_zMin(-1e8), norm_zMax(1e8);
24 double pdfxy(double *x, double *p);
25}
26
28{
29 double m_median;
30
31public:
33
34 bool operator()(double a , double b) const {
35 return std::abs(a - m_median) < std::abs(b -m_median);
36 }
37};
38
39
41 const std::string& name,
42 const IInterface* parent):
43 AthAlgTool(type,name,parent),
44 m_x(4),m_cov(4,0),m_z(0.),m_zErr(0.),
45 m_p(4), m_V(4,0),
46 m_zSolved(0.), m_zErrSolved(0.),
48 m_vertexCount(0),m_getLLres(false),
50
51{
52 declareInterface<IInDetBeamSpotTool>(this);
53 declareProperty("UseLikelihood",m_useLL = true);
54
55 //Fit initial parameter setup
56 declareProperty("InitParX", m_init_x =0.0);
57 declareProperty("InitParY", m_init_y =0.0);
58 declareProperty("InitParZ", m_init_z =0.0);
59 declareProperty("InitParAx", m_init_ax=0.0);
60 declareProperty("InitParAy", m_init_ay=0.0);
61 declareProperty("InitParSigmaX", m_init_sx=0.01);
62 declareProperty("InitParSigmaY", m_init_sy=0.01);
63 declareProperty("InitParSigmaZ", m_init_sz=56.0);
64 declareProperty("InitParK", m_init_k =1.0);
65 declareProperty("InitParRhoXY", m_init_rhoxy=0.0);
66 declareProperty("MinuitMaxIterations", m_minuit_maxIter=2000);
67 declareProperty("InitParMinX", m_init_min_x =0.0);
68 declareProperty("InitParMinY", m_init_min_y =0.0);
69 declareProperty("InitParMinZ", m_init_min_z =0.0);
70 declareProperty("InitParMinAx", m_init_min_ax=0.0);
71 declareProperty("InitParMinAy", m_init_min_ay=0.0);
72 declareProperty("InitParMinSigmaX", m_init_min_sx=0.0001);
73 declareProperty("InitParMinSigmaY", m_init_min_sy=0.0001);
74
75 declareProperty("InitParMinSigmaZ", m_init_min_sz=0.0);
76 declareProperty("InitParMinK", m_init_min_k =0);
77 declareProperty("InitParMinRhoXY", m_init_min_rhoxy=-1.0);
78
79 declareProperty("InitParMaxX", m_init_max_x =0.0);
80 declareProperty("InitParMaxY", m_init_max_y =0.0);
81 declareProperty("InitParMaxZ", m_init_max_z =0.0);
82 declareProperty("InitParMaxAx", m_init_max_ax=0.0);
83 declareProperty("InitParMaxAy", m_init_max_ay=0.0);
84 declareProperty("InitParMaxSigmaX", m_init_max_sx=2.0);
85 declareProperty("InitParMaxSigmaY", m_init_max_sy=2.0);
86 declareProperty("InitParMaxSigmaZ", m_init_max_sz=3000.);
87 declareProperty("InitParMaxK", m_init_max_k =10.);
88 declareProperty("InitParMaxRhoXY", m_init_max_rhoxy=1.0);
89
90 declareProperty("DefaultX0", m_def_x0=0.0);
91 declareProperty("DefaultY0", m_def_y0=0.0);
92 declareProperty("DefaultZ", m_def_z=0.0);
93 declareProperty("DefaultTiltX", m_def_ax=0.0);
94 declareProperty("DefaultTiltY", m_def_ay=0.0);
95 //these are used when returning a chi2 value
96 declareProperty("DefaultSigmaX", m_def_sx=0.0);
97 declareProperty("DefaultSigmaY", m_def_sy=0.0);
98 declareProperty("DefaultSigmaZ", m_def_sz=0.0);
99
100
101 // selections
102 declareProperty("MaxSigmaTr", m_sigTr=20.);
103 declareProperty("MaxVtxErrTr", m_maxVtxErTr=100.); // in mm
104 declareProperty("OutlierChi2Tr", m_outlierChi2Tr=20.);
105 declareProperty("MaxOutlierLoops",m_maxOutlierLoops = 30);
106 declareProperty("OutlierMaxRejection",m_singleIterationMax=30);
107 declareProperty("OutlierWidthFail", m_widthFail=5.1e-3); // in mm
108 declareProperty("OutlierRhoFail", m_rhoFail=0.8);
109
110 declareProperty("OutlierKFailMin", m_kMinFail = 0);
111 declareProperty("OutlierKFailMax", m_kMaxFail = 9.9);
112
113 declareProperty("DoFitSanityCheck", m_doFitSanityCheck=true);
114 declareProperty("DoChi2OnlyOutlierRemoval",m_doChi2OutlierRemoval=false);
115 // declareProperty( "MinVertexProb", m_minVtxProb=0.001); // min prob(chi2,ndf)
116
117 declareProperty( "FixParK" , m_fixInputK = false);
118 declareProperty( "UseLLNorm" , m_useLLNorm = false);
119 declareProperty( "FixWidth", m_fixWidth = false);
120
121 declareProperty("TruncatedRMS", m_truncatedRMS = true);
122 declareProperty("RMSFraction", m_fractionRMS = 0.95);
123 declareProperty("SetInitialRMS", m_setInitialRMS = false);
124
125}
126
128 IInDetBeamSpotTool(rhs),
129 AthAlgTool(rhs.type(), rhs.name(), rhs.parent()),
130 m_x(4),m_cov(4,0),m_z(0.),m_zErr(0.),
131 m_p(4), m_V(4,0),
132 m_zSolved(0.), m_zErrSolved(0.),
133 m_NPARS(10), m_pLL(m_NPARS,0),m_VLL(m_NPARS,0),
134 m_vertexCount(0),m_getLLres(false),
136{
137 m_useLL = rhs.m_useLL;
138 m_init_x = rhs.m_init_x;
139 m_init_y = rhs.m_init_y;
140 m_useLL = rhs.m_useLL;
141
142 m_init_x = rhs.m_init_x;
143 m_init_y = rhs.m_init_y;
144 m_init_z = rhs.m_init_z;
145 m_init_sx = rhs.m_init_sx;
146 m_init_sy = rhs.m_init_sy;
147 m_init_sz = rhs.m_init_sz;
148 m_init_ax = rhs.m_init_ax;
149 m_init_ay = rhs.m_init_ay;
150 m_init_k = rhs.m_init_k;
152
163
174
175 m_def_x0 = rhs.m_def_x0;
176 m_def_y0 = rhs.m_def_y0;
177 m_def_z = rhs.m_def_z;
178 m_def_ax = rhs.m_def_ax;
179 m_def_ay = rhs.m_def_ay;
180 m_def_sx = rhs.m_def_sx;
181 m_def_sy = rhs.m_def_sy;
182 m_def_sz = rhs.m_def_sz;
183
184 m_sigTr = rhs.m_sigTr;
186
187
189
194 m_rhoFail = rhs.m_rhoFail;
197
200
204
209}
210
212 ATH_MSG_DEBUG( "In initialize" );
213 return StatusCode::SUCCESS;
214}
215
217 ATH_MSG_DEBUG( "In finalize" );
218 clear(); // clear the data;
219
220 return StatusCode::SUCCESS;
221}
222
224 //reset the data information;
225
226 m_x *= 0.;
227 m_p *= 0.;
228
229 m_cov *= 0.;
230 m_V *= 0.;
231 m_z=0.;
232 m_zErr =0.;
233 m_zSolved =0.;
234 m_zErrSolved =0.;
235
236 m_vertexCount =0;
238
239 m_vertexData.clear();
240
241 m_nUsed = 0;
242}
243
244InDetBeamSpotVertex::FitStatus InDetBeamSpotVertex::fit(std::vector< BeamSpot::VrtHolder > &vtxData){
245 //get solution from current data;
246 //Note, even if doing LL, use the chi2 information
247 m_vertexData = vtxData;
248 m_vertexCount = vtxData.size();
249
250
251 bool chi2Result = solveChi2();
252 m_getLLres = false;
253 bool llResult = false;
254 if (m_useLL) {
255 applyOutlierRemoval(); // Apply a final selection
256 m_getLLres = true; //set system to use these results
257 llResult = solveLL();
258 if (!llResult) {
259 ATH_MSG_WARNING( "Log-likelihood fit failed: Reverting to chi2 solution" );
260 m_getLLres = false;
261 chi2Result = solveChi2(); //unfortunately need to resolve, to set correct fit parameters
262 }
263 }
264
265 if (m_useLL) {
266 m_getLLres = true; //set system to use these results
267 bool printOut = true;
268 llResult = solveLL(printOut);
269 if (!llResult) {
270 ATH_MSG_WARNING( "Log-likelihood fit failed: Reverting to chi2 solution" );
271 m_getLLres = false;
272 chi2Result = solveChi2(); //unfortunately need to resolve, to set correct fit parameters
273 }
274 } // if use LL
275
276
277
278 if (m_getLLres)
279 m_fitStatus = (llResult ? successful : failed);
280 else
281 m_fitStatus = (chi2Result ? successful : failed);
282 m_nUsed+=std::count_if(m_vertexData.begin(),m_vertexData.end(),[](const BeamSpot::VrtHolder & v){return v.valid;});
283
284 //display results
285 ATH_MSG_INFO( "Fit result was: " << ( m_fitStatus == successful ? "Successful" : "Failure")
286 << " using Vertex " << (m_getLLres ? "Log-likelihood":"Chi2") << " method" );
287 ATH_MSG_INFO( "Number of vertices: " << m_vertexCount );
288 ATH_MSG_INFO( "x(z=0) = " << getX(0.) << " +- " << getErrX(0) );
289 ATH_MSG_INFO( "y(z=0) = " << getY(0.) << " +- " << getErrY(0) );
290 ATH_MSG_INFO( "z = " << getZ() << " +- " << getErrZ() );
291 double z = getZ();
292 ATH_MSG_INFO( "x(z) = " << getX(z) << " +- " << getErrX(z) );
293 ATH_MSG_INFO( "y(z) = " << getY(z) << " +- " << getErrY(z) );
294
295 ATH_MSG_INFO( "TiltX = " << getTiltX() << " +- " << getErrTiltX() );
296 ATH_MSG_INFO( "TiltY = " << getTiltY() << " +- " << getErrTiltY() );
297
298 ATH_MSG_INFO( "SigmaX(z=0) = " << getSigmaX(0.) << " +- " << getErrSigmaX(0.) );
299 ATH_MSG_INFO( "SigmaY(z=0) = " << getSigmaY(0.) << " +- " << getErrSigmaY(0.) );
300 ATH_MSG_INFO( "SigmaZ = " << getSigmaZ() << " +- " << getErrSigmaZ() );
301
302 ATH_MSG_INFO( "rhoXY = " << getRhoXY() << " +- " << getErrRhoXY() );
303 ATH_MSG_INFO( "K = " << getK() << " +- " << getErrK() );
304
305 return m_fitStatus;
306}
307
308
309CLHEP::HepSymMatrix InDetBeamSpotVertex::getCov(double z) const { //x(z),y(z),tiltx,tilty
310 CLHEP::HepSymMatrix c(4,0);
311
312 if ( m_getLLres ) {
313 //maximum likelihood
314 c(1,1) = m_VLL(1,1) + 2*z*m_VLL(3,1) + z*z*m_VLL(3,3);
315 c(2,2) = m_VLL(2,2) + 2*z*m_VLL(4,2) + z*z*m_VLL(4,4);
316 c(3,3) = m_VLL(3,3);
317 c(4,4) = m_VLL(4,4);
318
319 c(2,1) = m_VLL(2,1) + z*m_VLL(2,3) + z*m_VLL(4,1)+z*z*m_VLL(4,3);
320 c(3,1) = m_VLL(3,1) + z*m_VLL(3,3);
321 c(4,1) = m_VLL(4,1) + z*m_VLL(3,4);
322
323 c(3,2) = m_VLL(2,3) + z*m_VLL(4,3);
324 c(4,2) = m_VLL(4,2) + z*m_VLL(4,4);
325
326 c(4,3) = m_VLL(4,3);
327
328 } else {
329 //chi2
330 c(1,1) = m_V(1,1) + 2*z*m_V(2,1) + z*z*m_V(2,2);
331 c(2,2) = m_V(3,3) + 2*z*m_V(4,3) + z*z*m_V(4,4);
332 c(3,3) = m_V(2,2);
333 c(4,4) = m_V(4,4);
334
335 c(2,1) = m_V(3,1) + z*m_V(3,2) + z*m_V(4,1)+z*z*m_V(4,2);
336 c(3,1) = m_V(2,1) + z*m_V(2,2);
337 c(4,1) = m_V(4,1) + z*m_V(4,2);
338
339 c(3,2) = m_V(3,2) + z*m_V(4,2);
340 c(4,2) = m_V(4,3) + z*m_V(4,4);
341
342 c(4,3) = m_V(4,2);
343
344 }
345
346 return c;
347}
348
349
350bool InDetBeamSpotVertex::solveLL(bool printOut) {
351 ATH_MSG_DEBUG( "In solveLL" );
352
353 TMinuit * minuit = new TMinuit(m_NPARS);
354 //setInitialPars( minuit);
355
356 //Set Minuit output level
357 if (msg().level() < MSG::DEBUG) {
358 printOut = true;
359 minuit->SetPrintLevel(1);
360 } else if (msg().level() == MSG::DEBUG) {
361 printOut = true;
362 minuit->SetPrintLevel(0);
363 } else {
364 minuit->SetPrintLevel(-1);
365 }
366
367 setParsFromChi2(minuit);
368
369 minuit->SetErrorDef(0.5); // for Log-Likeihood: 0.5
370
371 int errFlag =0;
372 //SET STRategy for calculating second derivs.
373 double arglist[1];
374 arglist[0] = 2;
375 minuit->mnexcm("SET STR",arglist,1,errFlag);
376
377 std::lock_guard<std::mutex> lock(BeamSpot::mutex); // To protect global BeamSpot::vertexData
378 // Insert the likelihood function
379 // need to make the data accessible to it
380 BeamSpot::vertexData = &m_vertexData;
381 if ( !m_useLLNorm)
382 minuit->SetFCN(BeamSpot::myFCN_LLsolver);
383 else {
384 minuit->SetFCN(BeamSpot::myFCN_LLsolverNorm);
385 }
386
387 std::pair<int, std::string> status; // fit status
388 //standard fit
389 bool goodFit = false;
390
391 //tried this approach - we want to succeed, so if fail, try another approach
392 if (!goodFit) {
393 doFit2(minuit,printOut);
394 successfulFit(minuit, status);
395 if ( status.first == 3 && ( status.second == "SUCCESSFUL" ||
396 status.second == "CONVERGED " ||
397 status.second == "CONVERGED") ){
398 goodFit = true;
399 } else {
400 goodFit = false;
401 }
402 }
403
404 if (goodFit){
405 ATH_MSG_INFO( "Successful fit" );
406 setOutput( minuit);
407 } else {
408 ATH_MSG_DEBUG( "No LL fit convergence" );
409 }
410
411 delete minuit;
412
413 return goodFit;
414}
415
416bool InDetBeamSpotVertex::setOutput( TMinuit * minuit) {
417 //set the LL fitted parameters to the output.
418 //output
419 double t;
420 for (int i =0; i<m_NPARS; ++i) {
421 minuit->GetParameter(i, m_pLL(i+1) ,t);
422 }//for
423
424 double * cov = new double[m_NPARS*m_NPARS];
425 minuit->mnemat(cov,m_NPARS);
426 for (int i =0; i<m_NPARS; ++i) {
427 for ( int j=i; j<m_NPARS; ++j) {
428 m_VLL(i+1,j+1) = cov[ i*m_NPARS + j];
429 }//for j
430 }//for i
431 delete[] cov;
432
433 return true;
434}
435
436
437
439 // use results of a chi2 fit to override some initial paramters
440 int errFlag;
441 minuit->mnparm(0,"X0",m_p(1) ,1e-5,m_init_min_x,m_init_max_x, errFlag);
442 minuit->mnparm(1,"Y0",m_p(3) ,1e-5,m_init_min_y,m_init_max_y, errFlag);
443 minuit->mnparm(2,"Ax",m_p(2) ,1e-6,m_init_min_ax,m_init_max_ax, errFlag);
444 minuit->mnparm(3,"Ay",m_p(4) ,1e-6,m_init_min_ay,m_init_max_ay, errFlag);
445 minuit->mnparm(4,"#sigma(x)",m_init_sx, 1e-5,m_init_min_sx,m_init_max_sx, errFlag);
446 minuit->mnparm(5,"#sigma(y)",m_init_sy, 1e-5,m_init_min_sy,m_init_max_sy, errFlag);
447 minuit->mnparm(6,"#rhoxy",m_init_rhoxy,1e-5,m_init_min_rhoxy,m_init_max_rhoxy, errFlag);
448 minuit->mnparm(7,"k",m_init_k, 1e-5,m_init_min_k,m_init_max_k, errFlag);
449 minuit->mnparm(8,"z0",m_zSolved, 1e-3,m_init_min_z,m_init_max_z, errFlag);
450 minuit->mnparm(9,"#sigma(z)",m_init_sz, 1e-3,m_init_min_sz,m_init_max_sz, errFlag);
451
452 minuit->SetMaxIterations(m_minuit_maxIter);
453
454 return errFlag;
455}
456
458 int errFlag;
459 //Set initial Parameters
460 minuit->mnparm(0,"X0",m_init_x ,1e-5,m_init_min_x,m_init_max_x, errFlag);
461 minuit->mnparm(1,"Y0",m_init_y ,1e-5,m_init_min_y,m_init_max_y, errFlag);
462 minuit->mnparm(2,"Ax",m_init_ax ,1e-6,m_init_min_ax,m_init_max_ax, errFlag);
463 minuit->mnparm(3,"Ay",m_init_ay ,1e-6,m_init_min_ay,m_init_max_ay, errFlag);
464 minuit->mnparm(4,"#sigma(x)",m_init_sx, 1e-5,m_init_min_sx,m_init_max_sx, errFlag);
465 minuit->mnparm(5,"#sigma(y)",m_init_sy, 1e-5,m_init_min_sy,m_init_max_sy, errFlag);
466 minuit->mnparm(6,"#rhoxy",m_init_rhoxy,1e-5,m_init_min_rhoxy,m_init_max_rhoxy, errFlag);
467 minuit->mnparm(7,"k",m_init_k, 1e-5,m_init_min_k,m_init_max_k, errFlag);
468 minuit->mnparm(8,"z0",m_init_z, 1e-3,m_init_min_z,m_init_max_z, errFlag);
469 minuit->mnparm(9,"#sigma(z)",m_init_sz, 1e-3,m_init_min_sz,m_init_max_sz, errFlag);
470
471 minuit->SetMaxIterations(m_minuit_maxIter);
472
473 return errFlag;
474}
475
477 ATH_MSG_DEBUG( "Attempting to solve " );
478
479 //calulate a solution for the current set of data
480 if (m_vertexCount == 0) {
481 ATH_MSG_DEBUG( "No vertices stored for solve" );
483 return false;
484 }
485
486
487 //invert matrix
488 int fail;
489 m_V = m_cov;
490 ATH_MSG_DEBUG( "Matrix prior to inversion\n" << m_V);
491
492 m_V.invert(fail); //replaces the matrix with inverse
493 if (fail != 0) {
494 return false;
495 }
496 ATH_MSG_DEBUG( "Matrix post inversion\n" << m_V);
497
498
499 m_p = m_V*m_x; // calculate parameter estimates
500 m_zSolved = m_z / m_zErr; // weighted
501 m_zErrSolved = 1./std::sqrt(m_zErr);
502
503
504 ATH_MSG_DEBUG( "Fit solved succesfully from " << m_vertexCount << " vertices");
505 ATH_MSG_DEBUG( "Chi2 Solution:\n"<<m_p <<"\n" << "Covariance: \n" << m_V );
506
507 return true;
508}
509
510
511
513 ATH_MSG_DEBUG( "In Outlier removal" );
514 // apply selection using results of a chi2 fit (eg. displacement)
515 if (!m_vertexData.size()) {
516 ATH_MSG_INFO( "No vertices found" );
517 return false;
518 }
519
520
521 // determine simple means
522 double meanx(0.),meany(0.), meanz(0.);
523 double meanxSqr(0.),meanySqr(0.), meanzSqr(0.);
524 double rmsX(0.),rmsY(0.), rmsZ(0.);
525
526 // for use in median determination
527 std::vector<double> vx,vy,vz;
528
529 int count(0);
530 for ( std::vector< BeamSpot::VrtHolder >::iterator it =
531 m_vertexData.begin();
532 it != m_vertexData.end(); ++it) {
533 if (!it->valid) continue;
534
535 if (!m_truncatedRMS) {
536 meanx += it->x;
537 meanxSqr += (it->x)*(it->x);
538 meany += it->y;
539 meanySqr += (it->y)*(it->y);
540 meanz += it->z;
541 meanzSqr += (it->z)*(it->z);
542
543 ++count;
544 }
545
546 vx.push_back(it->x);
547 vy.push_back(it->y);
548 vz.push_back(it->z);
549 }
550
551 // sort the vectors
552 std::sort(vx.begin(),vx.end());
553 std::sort(vy.begin(),vy.end());
554 std::sort(vz.begin(),vz.end());
555
556 // get the median values -- don't worry about extrapolating betweeen even sized entries
557 double medianx = (vx.size() > 1 ? vx.at(vx.size()/2) : 0.);
558 double mediany = (vy.size() > 1 ? vy.at(vy.size()/2) : 0.);
559 double medianz = (vz.size() > 1 ? vz.at(vz.size()/2) : 0.);
560
561 ATH_MSG_DEBUG( "Median: x: " << medianx
562 << " y: " << mediany
563 << " z: " << medianz );
564
565 if (m_truncatedRMS) {
566
567 ATH_MSG_DEBUG( "Truncating RMS ... " );
568 // Only use the fraction (95%) of tracks closest to the median position to determin the RMS
569 int nvtx(vx.size());
570 std::sort(vx.begin(), vx.end(), SortDistToMedian(medianx));
571 vx.erase(vx.begin()+int(m_fractionRMS*nvtx), vx.end());
572
573 std::sort(vy.begin(), vy.end(), SortDistToMedian(mediany));
574 vy.erase(vy.begin()+int(m_fractionRMS*nvtx), vy.end());
575
576 std::sort(vz.begin(), vz.end(), SortDistToMedian(medianz));
577 vz.erase(vz.begin()+int(m_fractionRMS*nvtx), vz.end());
578
579 ATH_MSG_DEBUG( "... using " << int(m_fractionRMS*nvtx) << " from " << nvtx << " vertices" );
580
581 for (unsigned int ivtx(0); ivtx < vx.size(); ++ivtx) {
582 double x = vx.at(ivtx);
583 double y = vy.at(ivtx);
584 double z = vz.at(ivtx);
585
586 meanx += x;
587 meanxSqr += x*x;
588 meany += y;
589 meanySqr += y*y;
590 meanz += z;
591 meanzSqr += z*z;
592
593 ++count;
594 }
595 }
596
597 if (count) {
598 meanx /= count;
599 meanxSqr /=count;
600 rmsX = std::sqrt( std::abs(meanxSqr - meanx*meanx));
601 meany /= count;
602 meanySqr /=count;
603 rmsY = std::sqrt( std::abs(meanySqr - meany*meany));
604 meanz /=count;
605 meanzSqr /=count;
606 rmsZ = std::sqrt( std::abs(meanzSqr - meanz*meanz));
607 }
608
609 if(m_setInitialRMS){
610 rmsX = m_init_sx;
611 rmsY = m_init_sy;
612 // should we include z here too??
613
614 ATH_MSG_DEBUG( "Setting RMS in x to " << rmsX );
615 ATH_MSG_DEBUG( "Setting RMS in y to " << rmsY );
616
617 }
618
619 ATH_MSG_DEBUG( "mean, RMS; x: " << meanx << " " << rmsX
620 << " " << ", y: " << meany << " " << rmsY << ", z: " << meanz << " " << rmsZ );
621
622
623 // varivables to hold the new chi2 and weighted z-mean values
624 CLHEP::HepVector chi2Pos(4);
625 CLHEP::HepSymMatrix chi2Cov(4);
626 double zpos(0), zerr(0);
627
628
629 // use simple mean and RMS to eliminate any vertices too far from centroid
630 // also redetermine a new chi2 value, based on passed vertices
631 long failCount(0);
632 for ( std::vector< BeamSpot::VrtHolder >::iterator it =
633 m_vertexData.begin();
634 it != m_vertexData.end(); ++it) {
635 if (!it->valid) continue;
636 int fail=0;
637
638 if ( std::abs( medianx - it->x ) > m_sigTr *rmsX) fail += 4;
639 if ( std::abs( mediany - it->y ) > m_sigTr *rmsY) fail += 8;
640 if ( std::abs( medianz - it->z ) > 10*rmsZ) fail += 16;
641 if ((rmsX == 0.) or (rmsY == 0.))[[unlikely]]{
642 throw std::runtime_error("InDetBeamSpotVertex::solveChi2: rmsX or rmsY is zero!");
643 }
644
645 if ( (medianx - it->x)*(medianx-it->x)/rmsX/rmsX + (mediany-it->y)*(mediany-it->y)/rmsY/rmsY > m_sigTr*m_sigTr) {
646 ATH_MSG_DEBUG( "Vertex info: extended past radial extent: sig."
647 << std::sqrt((medianx - it->x)*(medianx-it->x)/rmsX/rmsX + (mediany-it->y)*(mediany-it->y)/rmsY/rmsY) << " > "
648 << std::sqrt( m_sigTr*m_sigTr ) << "." );
649 fail += 128;
650 }
651
652 //and in Z?
653
654 if (fail) { // TBD only allow failed vertices here to be removed on every nth iteration (to aid stability)
655 ATH_MSG_DEBUG( "Vertex reject from simple mean; reason: " << fail << " : x,y,z: "
656 << it->x << " " << it->y << " " << it->z
657 << " , sigma(x,y,z): " << std::sqrt(it->vxx) << " " << std::sqrt(it->vyy)
658 << " " << std::sqrt(it->vzz)
659 );
660
661 it->valid = false;
662 ++failCount;
663 } else {
664 // still valid, so add into chi2
665
666 chi2Pos(1) += it->x * it->vxx + it->y*it->vxy;
667 chi2Pos(2) += it->x*it->vxx*it->z + it->y*it->vxy*it->z;
668 chi2Pos(3) += it->y*it->vyy + it->x*it->vxy;
669 chi2Pos(4) += it->y*it->vyy*it->z + it->x*it->vxy*it->z;
670
671
672 chi2Cov.fast(1,1) += it->vxx;
673 chi2Cov.fast(2,1) += it->vxx*it->z;
674 chi2Cov.fast(2,2) += it->vxx*it->z*it->z;
675 chi2Cov.fast(3,1) += it->vxy;
676 chi2Cov.fast(3,2) += it->vxy*it->z;
677 chi2Cov.fast(3,3) += it->vyy;
678 chi2Cov.fast(4,1) += it->vxy*it->z;
679 chi2Cov.fast(4,2) += it->vxy*it->z*it->z;
680 chi2Cov.fast(4,3) += it->vyy*it->z;
681 chi2Cov.fast(4,4) += it->vyy*it->z*it->z;
682
683 zpos += it->z/it->vzz; //weighted
684 zerr += 1./it->vzz;
685 }// end of valid vertex
686
687 }// for
688 ATH_MSG_DEBUG( "Removed: " << failCount << " vertices from simple mean,RMS." );
689
690
691 // update the new global chi2 - need to do this after the invert has been successful though !!!
692 m_cov = chi2Cov;
693 m_x = chi2Pos;
694 m_z = zpos;
695 m_zErr =zerr;
696 // attempt to solve the new chi2 solution
697 int invFail(0);
698 chi2Cov.invert(invFail);
699 chi2Pos = chi2Cov*chi2Pos;
700 if (zerr == 0.)[[unlikely]]{
701 throw std::runtime_error("InDetBeamSpotVertex::applyOutlierRemoval: zerr is zero.");
702 }
703 zpos = zpos / zerr;
704 zerr = 1./std::sqrt(zerr);
705
706
707
708
709 // make comparisons of old chi2, new mean and new chi2 values
710 if (msgLvl(MSG::DEBUG) ) {
711 ATH_MSG_DEBUG( "Mean position: x,y,z " << meanx << " " << meany << " " << meanz );
712 ATH_MSG_DEBUG( " RMS: x,y,z " << rmsX << " " << rmsY << " " << rmsZ );
713
714 ATH_MSG_DEBUG( "Original chi2:" << m_p << "\n" << m_V << "\n" << m_zSolved << " " << m_zErrSolved );
715
716 ATH_MSG_DEBUG( "New chi2:" << chi2Pos << "\n" << chi2Cov << "\n" << zpos << " " << zerr );
717
718 } // debug statement
719
720 m_V = chi2Cov;
721 m_p = chi2Pos;
722 m_zSolved = zpos;
723 m_zErrSolved = zerr;
724
725
726
727
728 //Dubious - !!! TBD: move this into the general LL solve area and do it properly!
729
730 m_init_sz = rmsZ;
731
732 // perform LL fit?
733 bool llSolve(false);
734 m_getLLres = false;
735 if (m_useLL) {
736 llSolve = solveLL();
737 m_getLLres = llSolve; // allow the log-likelihood accessor values to returned, if sucessful
738 }
739
740 if ( llSolve and m_rCount > 0 ) {
741 ATH_MSG_INFO( "Log-Likelihood fit converged in outlier removal. Exiting outlier removal." );
742 return true;
743 }
744
745 CLHEP::HepSymMatrix bsCov(2); // for individual chi2 values
746 double xbar = 0.;
747 double ybar = 0.;
748 double ax = 0.;
749 double ay = 0.;
750
751
752
753 if ( llSolve == false || getSigmaX(0.) < m_widthFail || getSigmaY(0.) < m_widthFail || std::abs(getRhoXY()) > m_rhoFail ) {
754 // ll solution not used, or not trusted
755 // set a wide solution
756 m_getLLres = false;
757 ATH_MSG_INFO( ": removeOutliers: LL fit not use/converged/trusted - " <<
758 "using chi2 for mean and simple RMS for width values " );
759 ATH_MSG_DEBUG( llSolve << " " << getSigmaX(0.) << " " << getSigmaY(0.) << " " << getRhoXY() );
760 xbar = getX(0.);
761 ybar = getY(0.);
762 ax = getTiltX();
763 ay = getTiltY();
764
765 bsCov(1,1) = rmsX*rmsX;
766 bsCov(2,2) = rmsY*rmsY;
767 bsCov(2,1) = 0.;
768
769 } else { // ll fit succeeded
770 xbar = getX(0.);
771 ybar = getY(0.);
772 ax = getTiltX();
773 ay = getTiltY();
774
775
776 bsCov(1,1) = getSigmaX(0.)*getSigmaX(0.);
777 bsCov(2,2) = getSigmaY(0.)*getSigmaY(0.);
778 bsCov(2,1) = getSigmaX(0.)*getSigmaY(0.) * getRhoXY();
779
780 } //
781
782 // loop over all vertices and populate a map with the chi2 values of the vertices
783 std::multimap<double, BeamSpot::VrtHolder*> chi2map;
784 int fail(0);
785 long fCount(0);
786 for ( std::vector< BeamSpot::VrtHolder >::iterator it = m_vertexData.begin();
787 it != m_vertexData.end(); ++it) {
788 if ( !it->valid) continue; // ignore vertices set to invalid
789 fail = 0; // reset the fail value variable
790
791 // selections
792 if ( std::abs(it->x - (xbar + it->z*ax)) > m_sigTr * rmsX) fail += 1;
793 if ( std::abs(it->y - (ybar + it->z*ay)) > m_sigTr * rmsY) fail += 2;
794
795 if ( it->vxx > m_maxVtxErTr*m_maxVtxErTr || it->vyy > m_maxVtxErTr*m_maxVtxErTr) fail += 4;
796
797 if ( std::abs(it->z - meanz) > m_sigTr * rmsZ) fail += 8;
798
799 // add all other selections above here:
800 double increaseChi2(0);
801 if (fail) {
802 increaseChi2 = fail * 1e5;
803 }
804
805
806 // chi2 value in transversve plane
807 CLHEP::HepSymMatrix b(2);
808 // TEST TBD !!!
809
810 b(1,1) = it->vxx + bsCov(1,1);
811 b(2,2) = it->vyy + bsCov(2,2);
812 b(2,1) = it->vxy + bsCov(2,1);
813
814 int failInv =0;
815 b.invert(failInv);
816 if (failInv) continue;
817 double ch = (it->x - (xbar + it->z*ax)) * b(1,1) * (it->x - (xbar + it->z*ax))
818 + (it->y - (ybar + it->z*ay)) * b(2,2) * (it->y - (ybar + it->z*ay))
819 + 2*(it->x - (xbar + it->z*ax)) *b(2,1) * (it->y - (ybar + it->z*ay));
820
821 //if (ch > m_outlierChi2Tr ) fail += 128; fail is never used after this
822
823 // if vertex fails selection based on [1,2,4] add a large artificial chi2 value to make sure is removed.
824 ch += increaseChi2;
825
826 chi2map.insert(std::make_pair(ch, &(*it))); // add to list
827
828 } // end for
829
830 // from the map remove the largest chi2 values, up to some maximum number of vertices
831 fCount = 0;
832 for (std::multimap<double, BeamSpot::VrtHolder*>::reverse_iterator vit = chi2map.rbegin(); vit != chi2map.rend(); ++vit) {
833 if ( !vit->second) continue; // no valid pointer ...
834 if ( !vit->second->valid) continue; // ignore vertices set to invalid - shouldn't happen here though
835 if ( fCount >= m_singleIterationMax && m_singleIterationMax != -1) {
836 ATH_MSG_DEBUG( " removeOutlier: Reached max number of vertex rejections for this iteration.\n"
837 << "\tNeed to recalculate mean positions." );
838 break;
839 } // if reached max iterations for this round
840
841 ATH_MSG_VERBOSE( "Vertex chi2: " << vit->first );
842
843
844
845 if ( vit->first < m_outlierChi2Tr ) {
846 if (msgLvl(MSG::DEBUG)) {
847 ATH_MSG_DEBUG( " No more 'bad' vertices found in this iteration." );
848 if (fCount == 0) {
849 ATH_MSG_DEBUG( " No futher vertices removed - moving to final iteration" );
850 } else {
851 ATH_MSG_DEBUG( " Moving to next iteration of outlier removal." );
852 }
853 }
854 break;
855 } // if
856
857 // any vertex that is found here should be removed
858 ++fCount;
859 vit->second->valid = false;
860 // vit->second->outlierRemoved = true;
861 ATH_MSG_DEBUG( "Vertex rejected; chi2: " << vit->first <<". pos(x,y,z): "
862 << vit->second->x << " " << vit->second->y << " " << vit->second->z
863 << " , sigma(x,y,z): " << sqrt(vit->second->vxx) << " " << sqrt(vit->second->vyy)
864 << " " << sqrt(vit->second->vzz)
865 );
866
867 } // for
868
869 // if no vertices removed and ll fit still fails, then we continue to have a problem ...
870 if (fCount == 0 && m_useLL && !llSolve && m_rCount !=0 ) { // if first iteration, we have another iteration later.
871 ATH_MSG_WARNING( "No vertices removed and fit still fails - most likely final result will fail" );
872
873 // this is our 'last-ditch approach'. Split the collection of vertices into two 'random' sets and solve for each.
874 // if both successful, then compare (and be a little confused). If only one, compare to chi2 and take if ok.
875 // if none, then really have to give up. No valid solution possible.
876
877 // m_vertexData // key holder.
878 // copy the original values
879 std::vector< BeamSpot::VrtHolder > vertexTemp(m_vertexData);
880 // muddle up the original
881 std::random_device rng;
882 std::mt19937 urng(rng());
883 std::shuffle(m_vertexData.begin(), m_vertexData.end(), urng);
884 // divide the sample into two
885 std::vector< BeamSpot::VrtHolder > vertex1,vertex2;
886 std::copy(m_vertexData.begin() + m_vertexData.size()/2, m_vertexData.end(), back_inserter(vertex2)) ;
887 std::copy(m_vertexData.begin(), m_vertexData.begin() + m_vertexData.size()/2, back_inserter(vertex1)) ;
888
889 bool goodFit1(false), goodFit2(false);
890
891 ATH_MSG_DEBUG( "Attempting fit with vextex half: 1");
892 m_vertexData = vertex1;
893 llSolve = solveLL();
894 m_getLLres = true;
895 ATH_MSG_WARNING( "Fit using \"vertex1\" " << ( llSolve ? "Successful": "Failed") );
896 if (llSolve) {
897 goodFit1 = true;
898
899
900 ATH_MSG_DEBUG( "x: " << getX(0) << " +- " << getErrX(0) );
901 ATH_MSG_DEBUG( "y: " << getY(0) << " +- " << getErrY(0) );
902 ATH_MSG_DEBUG( "z: " << getZ() << " +- " << getErrZ() );
903 ATH_MSG_DEBUG( "sx: " << getSigmaX(0) << " +- " << getErrSigmaX(0) );
904 ATH_MSG_DEBUG( "sy: " << getSigmaY(0) << " +- " << getErrSigmaY(0) );
905 ATH_MSG_DEBUG( "sz: " << getSigmaZ() << " +- " << getErrSigmaZ() );
906 ATH_MSG_DEBUG( "ax: " << getTiltX() << " +- " << getErrTiltX() );
907 ATH_MSG_DEBUG( "ay: " << getTiltY() << " +- " << getErrTiltY() );
908 ATH_MSG_DEBUG( "sxy:" << getSigmaXY(0) << " +- " << getErrSigmaXY(0) );
909 ATH_MSG_DEBUG( "rh: " << getRhoXY() << " +- " << getErrRhoXY() );
910 ATH_MSG_DEBUG( "k: " << getK() << " +- " << getErrK() );
911
912
913 } // good fit
914
915 ATH_MSG_DEBUG( "Attempting fit with vextex half: 2");
916 m_vertexData = vertex2;
917 llSolve = solveLL();
918 m_getLLres = true;
919 ATH_MSG_WARNING( "Fit using \"vertex2\" " << ( llSolve ? "Successful": "Failed") );
920 if (llSolve) {
921 goodFit2 = true;
922
923 ATH_MSG_DEBUG( "x: " << getX(0) << " +- " << getErrX(0) );
924 ATH_MSG_DEBUG( "y: " << getY(0) << " +- " << getErrY(0) );
925 ATH_MSG_DEBUG( "z: " << getZ() << " +- " << getErrZ() );
926 ATH_MSG_DEBUG( "sx: " << getSigmaX(0) << " +- " << getErrSigmaX(0) );
927 ATH_MSG_DEBUG( "sy: " << getSigmaY(0) << " +- " << getErrSigmaY(0) );
928 ATH_MSG_DEBUG( "sz: " << getSigmaZ() << " +- " << getErrSigmaZ() );
929 ATH_MSG_DEBUG( "ax: " << getTiltX() << " +- " << getErrTiltX() );
930 ATH_MSG_DEBUG( "ay: " << getTiltY() << " +- " << getErrTiltY() );
931 ATH_MSG_DEBUG( "sxy:" << getSigmaXY(0) << " +- " << getErrSigmaXY(0) );
932 ATH_MSG_DEBUG( "rh: " << getRhoXY() << " +- " << getErrRhoXY() );
933 ATH_MSG_DEBUG( "k: " << getK() << " +- " << getErrK() );
934
935
936 }
937
938 // what now ? ...
939 ATH_MSG_WARNING( "Fit was " << ( goodFit2 || goodFit1 ? "Successful ": "Unsuccessful ")
940 <<" using a subset of the available vertices" );
941 if (( goodFit2 || goodFit1) )
942 ATH_MSG_WARNING( "Using these subset data for final result!!! " );
943 ATH_MSG_WARNING( "FIT HALFVERTX" );
944
945 if (goodFit1) {
946 m_vertexData = std::move(vertex1);
947 } else if (goodFit2) {
948 m_vertexData = std::move(vertex2);
949 } else {
950 m_vertexData = std::move(vertexTemp); // give up and go home...
951 }
952
953 } // last solution
954
955
956
957 // recursive mode
958 ATH_MSG_DEBUG( " Recursive debug: Loop: " << m_rCount << ". Number of failed vertices: " << fCount );
959
960 ++m_rCount;
961 if ( fCount > 0 || ( fCount == 0 && m_rCount == 1 && !llSolve)) { // if failed vertices or, no failed, first iteration, and no succesful fit
963 ATH_MSG_WARNING( "OutlierRemoval: Reached maximum number of recursive loops: " << m_rCount
964 << ". No more iterations performed." );
965 } else {
966 ATH_MSG_DEBUG( "OutlierRemoval: Entering recursive loop: " << m_rCount );
968 } // if entering loop
969 } // if fails > 0
970 --m_rCount;
971 return true;
972} // outlier removal
973
974
976 std::pair<int, std::string> & status) {
977 if (!minuit) return false;
978 //This should be called directly after the fit
979 std::string sRes = minuit->fCstatu.Data();
980
981 Double_t fmin{}, fedm{}, errdef{};
982 Int_t npari{},nparx{},istat{};
983 minuit->mnstat(fmin, fedm, errdef,npari,nparx,istat);
984
985 ATH_MSG_DEBUG( "Fit reports status: " << istat << " and " << sRes );
986
987 status.first = istat;
988 status.second = std::move(sRes);
989
990 bool sanityPassed(true);
991 if ( m_doFitSanityCheck) {
992 double x(0), ex(0);
993 minuit->GetParameter(6,x,ex); // rhoxy
994 if ( std::abs(x) > m_rhoFail){
995 sanityPassed = false;
996 ATH_MSG_DEBUG( "Fit Failed with rhoxy: " << x << " > " << m_rhoFail );
997 }
998 minuit->GetParameter(4,x,ex); // sigma x
999 if ( std::abs(x) < m_widthFail ){
1000 sanityPassed = false;
1001 ATH_MSG_DEBUG( "Fit Failed with sigmaX:" << x << " > " << m_widthFail );
1002 }
1003 minuit->GetParameter(5,x,ex); // sigma y
1004 if ( std::abs(x) < m_widthFail ){
1005 sanityPassed = false;
1006 ATH_MSG_DEBUG( "Fit Failed with sigmaY: " << x << " > " <<m_widthFail );
1007 }
1008
1009 minuit->GetParameter(7,x,ex); // k
1010 if ( std::abs(x) < m_kMinFail || std::abs(x) > m_kMaxFail ){
1011 sanityPassed = false;
1012 ATH_MSG_DEBUG( "Fit Failed with k: " << x << " > " << m_kMaxFail
1013 << ", or " << x << " < " << m_kMinFail );
1014 }
1015
1016
1017
1018 } // sanity check
1019 if (!sanityPassed) {
1020 status.first = 99;
1021 status.second = "FAILED BEAMSPOT SANITY CHECK";
1022 }
1023 ATH_MSG_DEBUG( "Fit " << ( sanityPassed ? "Passed": "Failed") << " sanity check: " );
1024
1025 if ( istat != 3) return false;
1026
1027
1028 return true;
1029}
1030
1031
1032void BeamSpot::myFCN_LLsolver( Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t) {
1033 constexpr double Pi = M_PI;
1034 //par[*]
1035 //0, 1, 2, 3, 4, 5, 6, 7, 8 9
1036 //X0, Y0, Ax. Ay, sx, sy, rhoxy, k z0 sigma(z)
1037
1038 f = 0;
1039
1040 using Vertices = std::vector<BeamSpot::VrtHolder>;
1041 Vertices::const_iterator vit = BeamSpot::vertexData->begin();
1042
1043 double temp =0;
1044 double x=0,y=0,z=0;
1045 double vxx,vyy, vxy;
1046 double covXX,covYY,covXY;
1047 double det,k2;
1048
1049 // ln L = Sum[ ln(F) ]
1050 for ( ; vit != vertexData->end(); ++vit) {
1051 if (!vit->valid) continue; // don't use non-valid vertices
1052 temp =0;
1053 x = vit->x;
1054 y = vit->y;
1055 z = vit->z;
1056 vxx = vit->vxx;
1057 vxy = vit->vxy;
1058 vyy = vit->vyy;
1059
1060
1061 k2 = par[7]*par[7];
1062
1063 covXX = k2 *vxx + par[4]*par[4];
1064 covYY = k2 *vyy + par[5]*par[5];
1065 covXY = k2 *vxy + par[6] *par[4]* par[5];
1066
1067 det = covXX * covYY - covXY*covXY;
1068 double recDet = 1./det;
1069
1070 //temp = TMath::Log(2*Pi * sqrt(std::abs(det)));
1071 temp = 2*TMath::Log(2*Pi);
1072 temp += TMath::Log(det);
1073
1074 covXY = -covXY * recDet;
1075 double t = covXX *recDet;
1076 covXX = covYY *recDet;
1077 covYY = t;
1078
1079 temp += (
1080 ( x - par[0] - par[2]*z) * covXX * ( x - par[0] - par[2]*z)
1081 + ( y - par[1] - par[3]*z) * covYY * ( y - par[1] - par[3]*z)
1082 + 2*( x - par[0] - par[2]*z) * covXY * ( y - par[1] - par[3]*z)
1083 );
1084
1085 temp += TMath::Log( 2*Pi * par[9]*par[9] ) + ( z - par[8]) * (z-par[8]) / (par[9] * par[9] );
1086 f+= 0.5*temp;
1087 }//for
1088
1089
1090}//myFCN
1091
1092double BeamSpot::pdfxy(double *, double *) {
1093
1094 return 0; // TBD dlete
1095}
1096
1097
1098
1099void BeamSpot::myFCN_LLsolverNorm( Int_t &, Double_t *, Double_t & /*f*/, Double_t * /*par*/, Int_t) {
1100
1101}
1102
1103
1104
1105
1106void InDetBeamSpotVertex::doFit2( TMinuit * minuit, bool printOut) {
1107 //second attempt to fit in a controlled way.
1108 //reset initial values
1109 setParsFromChi2(minuit);
1110
1111 //fix k, and rho,
1112 minuit->FixParameter(6);
1113 minuit->FixParameter(7);
1114
1115 //fix x0,y0,ax,ay
1116 minuit->FixParameter(0);
1117 minuit->FixParameter(1);
1118 minuit->FixParameter(2);
1119 minuit->FixParameter(3);
1120
1121 if(m_fixWidth){
1122 minuit->FixParameter(4);
1123 minuit->FixParameter(5);
1124 }
1125
1126 minuit->Migrad();
1127 minuit->Migrad();
1128 //release k,rho
1129 if ( !m_fixInputK){
1130 minuit->Release(7);
1131 minuit->Migrad();
1132 }
1133
1134 if(!m_fixWidth){
1135 minuit->Release(6);
1136 minuit->Migrad();
1137 }
1138
1139 minuit->Release(0);
1140 minuit->Release(1);
1141 minuit->Release(2);
1142 minuit->Release(3);
1143 minuit->Migrad();
1144 if(printOut) minuit->SetPrintLevel(0);
1145 minuit->Migrad();
1146 //look at fit status from calling function
1147}
1148
1149
1150std::map<std::string,double> InDetBeamSpotVertex::getCovMap() const {
1151
1152 //Note: all the off-diagonal elements are errors calculated at (0,0,0).
1153 //While the diagonal elements are calculated at the z centroid
1154 //In practice, this should make little difference, but it is important to note for now.
1155
1156 std::map<std::string,double> covMap;
1157 std::vector<double> covVector;
1158 covVector.resize(55);
1159
1160 //This is the method that was used before to put the covariance matrix in the required order
1161 //We don't want to mess with this, because no one knows the original order
1162
1163 int map[] = {1,2,9,3,4,5,6,10,7,8};
1164 if(m_fixInputK){
1165 int map2[] = {1,2,8,3,4,5,6,9,7,10};
1166 for(int i=0; i < 10; ++i){
1167 map[i] = map2[i];
1168 }
1169 } else if (m_fixWidth) {
1170 int map2[] = {1,2,6,3,4,8,9,7,10,5};
1171 for(int i=0; i < 10; ++i){
1172 map[i] = map2[i];
1173 }
1174 }
1175
1176 int temp = 0;
1177 for (int i=0;i<10;++i) {
1178 for (int j=i;j<10;++j) {
1179 if( m_fixInputK && (i == 9 || j ==9 )){
1180 covVector[temp++] = 0;
1181 } else if ( m_fixWidth && ( i == 5 || i == 6 || i == 8 || j == 5 || j == 6 || j == 8 ) ){
1182 covVector[temp++] = 0;
1183 }else{
1184 covVector[temp++] = m_VLL( map[i], map[j] );
1185 }
1186 }
1187 }
1188
1189 //This array is in the order required from the original ntuple format
1190
1191 const std::string keyArr[] = {"posXErr","covXY","covXZ","covXTiltX","covXTiltY","covXSx","covXSy","covXSz","covXRhoXY","covXk",
1192 "posYErr","covYZ","covYTiltX","covYTiltY","covYSx","covYSy","covYSz","covYRhoXY","covYk",
1193 "posZErr","covZTiltX","covZTiltY","covZSx","covZSy","covZSz","covZRhoXY","covZk",
1194 "tiltXErr","covTiltXTiltY","covTiltXSx","covTiltXSy","covTiltXSz","covTiltXRhoXY","covTiltXk",
1195 "tiltYErr","covTiltYSx","covTiltYSy","covTiltYSz","covTiltYRhoXY","covTiltYk",
1196 "sigmaXErr","covSxSy","covSxSz","covSxRhoXY","covSxk",
1197 "sigmaYErr","covSySz","covSyRhoXY","covSyk",
1198 "sigmaZErr","covSzRhoXY","covSzk",
1199 "rhoXYErr","covRhoXYk",
1200 "kErr"};
1201
1202
1203 //Now that everything should be in the right order, it's simple to set the covariance matrix map correctly:
1204
1205
1206 for(int i = 0; i < 55; i++){
1207 covMap[keyArr[i]] = covVector[i];
1208 //std::cout << keyArr[i] << " " << covVector[i] << std::endl;
1209 //covMap[keyArr2[i]]= covVector[i];
1210 }
1211
1212 covMap[ keyArr[0] ] = sqrt(covVector[0]);
1213 covMap[ keyArr[10] ] = sqrt(covVector[10]);
1214 covMap[ keyArr[19] ] = sqrt(covVector[19]);
1215 covMap[ keyArr[27] ] = sqrt(covVector[27]);
1216 covMap[ keyArr[34] ] = sqrt(covVector[34]);
1217 covMap[ keyArr[40] ] = sqrt(covVector[40]);
1218 covMap[ keyArr[45] ] = sqrt(covVector[45]);
1219 covMap[ keyArr[49] ] = sqrt(covVector[49]);
1220 covMap[ keyArr[52] ] = sqrt(covVector[52]);
1221 covMap[ keyArr[54] ] = sqrt(covVector[54]);
1222
1223
1224 //The errors on these 5 parameters were calculated at (0,0,0). This is how we convert them to be
1225 //at the centroid
1226
1227 double z = getZ();
1228 CLHEP::HepSymMatrix covc = getCov(z);
1229
1230 covMap["posXErr"] = sqrt( covc(1,1) ); //xcxc
1231 covMap["posYErr"] = sqrt( covc(2,2) ); //ycyc
1232 covMap["tiltXErr"] = sqrt( covc(3,3) ); //axcaxc
1233 covMap["tiltYErr"] = sqrt( covc(4,4) ); //aycayc
1234 covMap["sigmaXErr"] = sqrt( getErrSigmaX(z)*getErrSigmaX(z) ); //sxcsxc
1235 covMap["sigmaYErr"] = sqrt( getErrSigmaY(z)*getErrSigmaY(z) ); //sycsyc
1236
1237 return covMap;
1238
1239
1240}
1241std::map<std::string,double> InDetBeamSpotVertex::getParamMap() const {
1242 double z = getZ();
1243
1244 std::map<std::string,double> paramMap;
1245 paramMap["tiltX"] = (m_getLLres ? m_pLL(3) : m_p(2));
1246 paramMap["tiltY"] = (m_getLLres ? m_pLL(4) : m_p(4));
1247 paramMap["k"] = (m_getLLres ? m_pLL(8) : 0.);
1248 paramMap["posX"] = (m_getLLres ? m_pLL(1) + m_pLL(3)*z : m_p(1) + m_p(2)*z);
1249 paramMap["posY"] = (m_getLLres ? m_pLL(2) + m_pLL(4)*z : m_p(3) + m_p(4)*z);
1250 paramMap["posZ"] = (m_getLLres ? m_pLL(9) : m_zSolved);
1251 paramMap["sigmaX"] = (m_getLLres ? m_pLL(5) : m_def_sx);
1252 paramMap["sigmaY"] = (m_getLLres ? m_pLL(6) : m_def_sy);
1253 paramMap["sigmaZ"] = (m_getLLres ? m_pLL(10) : m_def_sz);
1254 paramMap["rhoXY"] = (m_getLLres ? m_pLL(7) : 0.);
1255 paramMap["nUsed"] = m_nUsed;
1256
1257 return paramMap;
1258}
#define M_PI
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static const double Pi
static Double_t a
#define y
#define x
#define z
Define macros for attributes used to control the static checker.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Abstract class for all beamspot determination algorithms.
FitStatus
Internally used enum for fit status.
double getErrX(double z) const
double getSigmaY(double) const
double getErrY(double z) const
double getSigmaX(double) const
void doFit2(TMinuit *, bool printOut=false)
virtual StatusCode finalize()
Standard finalize.
double getX(double z) const
bool solveLL(bool printOut=false)
double getSigmaXY(double z) const
int setInitialPars(TMinuit *minuit)
virtual StatusCode initialize()
Standard initialize.
virtual FitStatus fit(std::vector< BeamSpot::VrtHolder > &)
Attempt a to find a solution of the beamspot.
virtual std::map< std::string, double > getParamMap() const
bool successfulFit(TMinuit *, std::pair< int, std::string > &)
double getErrSigmaY(double) const
double getErrSigmaXY(double z) const
double getErrSigmaX(double) const
double getY(double z) const
std::vector< BeamSpot::VrtHolder > m_vertexData
virtual std::map< std::string, double > getCovMap() const
int setParsFromChi2(TMinuit *minuit)
CLHEP::HepSymMatrix getCov(double z) const
InDetBeamSpotVertex(const std::string &type, const std::string &name, const IInterface *parent)
bool operator()(double a, double b) const
SortDistToMedian(double median)
STL class.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
double norm_zMin(-1e8)
double norm_xMax(1e8)
const std::vector< BeamSpot::VrtHolder > *vertexData ATLAS_THREAD_SAFE
void myFCN_LLsolverNorm(Int_t &, Double_t *, Double_t &, Double_t *, Int_t)
double norm_yMin(-1e8)
double norm_zMax(1e8)
double pdfxy(double *x, double *p)
void myFCN_LLsolver(Int_t &, Double_t *, Double_t &, Double_t *, Int_t)
double norm_yMax(1e8)
double norm_xMin(-1e8)
Primary Vertex Finder.
float median(std::vector< float > &Vec)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void shuffle(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, UniformRandom &g)
Specialization of shuffle for DataVector/List.
#define unlikely(x)