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