6 #include "GaudiKernel/ITHistSvc.h" 
   15 using namespace InDet;
 
   20   void myFCN_LLsolver( Int_t &, Double_t *, Double_t &, Double_t *, Int_t); 
 
   23   double pdfxy(
double *
x, 
double *
p);
 
   34     return std::abs(
a - m_median) < std::abs(
b -m_median);
 
   40               const std::string& 
name, 
 
   43   m_x(4),m_cov(4,0),m_z(0.),m_zErr(0.),
 
   45   m_zSolved(0.), m_zErrSolved(0.),
 
   46   m_NPARS(10), m_pLL(m_NPARS,0),m_VLL(m_NPARS,0),
 
   47   m_vertexCount(0),m_getLLres(false),
 
   48   m_fitStatus(unsolved),m_minVtxProb{},m_nUsed(0)
 
   51   declareInterface<IInDetBeamSpotTool>(
this);
 
   52   declareProperty(
"UseLikelihood",m_useLL = 
true);
 
   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);
 
   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);
 
   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);
 
   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);
 
   95   declareProperty(
"DefaultSigmaX",  m_def_sx=0.0);
 
   96   declareProperty(
"DefaultSigmaY",  m_def_sy=0.0);
 
   97   declareProperty(
"DefaultSigmaZ",  m_def_sz=0.0);
 
  101   declareProperty(
"MaxSigmaTr", m_sigTr=20.); 
 
  102   declareProperty(
"MaxVtxErrTr", m_maxVtxErTr=100.); 
 
  103   declareProperty(
"OutlierChi2Tr", m_outlierChi2Tr=20.);
 
  104   declareProperty(
"MaxOutlierLoops",m_maxOutlierLoops = 30);
 
  105   declareProperty(
"OutlierMaxRejection",m_singleIterationMax=30);
 
  106   declareProperty(
"OutlierWidthFail", m_widthFail=5.1
e-3); 
 
  107   declareProperty(
"OutlierRhoFail", m_rhoFail=0.8); 
 
  109   declareProperty(
"OutlierKFailMin", m_kMinFail = 0);
 
  110   declareProperty(
"OutlierKFailMax", m_kMaxFail = 9.9);
 
  112   declareProperty(
"DoFitSanityCheck", m_doFitSanityCheck=
true); 
 
  113   declareProperty(
"DoChi2OnlyOutlierRemoval",m_doChi2OutlierRemoval=
false);
 
  116   declareProperty( 
"FixParK" ,   m_fixInputK = 
false);
 
  117   declareProperty( 
"UseLLNorm" , m_useLLNorm = 
false);
 
  118   declareProperty( 
"FixWidth",   m_fixWidth  = 
false); 
 
  120   declareProperty(
"TruncatedRMS", m_truncatedRMS = 
true); 
 
  121   declareProperty(
"RMSFraction", m_fractionRMS = 0.95); 
 
  122   declareProperty(
"SetInitialRMS", m_setInitialRMS = 
false);
 
  129   m_x(4),m_cov(4,0),m_z(0.),m_zErr(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),
 
  134   m_fitStatus(unsolved),m_nUsed(0)
 
  212   return StatusCode::SUCCESS;
 
  219   return StatusCode::SUCCESS;
 
  252   bool llResult = 
false;
 
  258       ATH_MSG_WARNING( 
"Log-likelihood fit failed: Reverting to chi2 solution" );
 
  266     bool printOut = 
true;
 
  269       ATH_MSG_WARNING( 
"Log-likelihood fit failed: Reverting to chi2 solution" );
 
  285      << 
" using Vertex " << (
m_getLLres ? 
"Log-likelihood":
"Chi2") << 
" method" );
 
  309   CLHEP::HepSymMatrix 
c(4,0);
 
  352   TMinuit * minuit = 
new TMinuit(
m_NPARS);
 
  358     minuit->SetPrintLevel(1);
 
  361     minuit->SetPrintLevel(0);
 
  363     minuit->SetPrintLevel(-1);
 
  368   minuit->SetErrorDef(0.5); 
 
  374   minuit->mnexcm(
"SET STR",arglist,1,errFlag);
 
  386   std::pair<int, std::string>  
status; 
 
  388   bool goodFit = 
false;
 
  394     if ( 
status.first == 3 && ( 
status.second == 
"SUCCESSFUL" ||
 
  395         status.second == 
"CONVERGED " ||
 
  396         status.second == 
"CONVERGED") ){
 
  420     minuit->GetParameter(
i, 
m_pLL(
i+1)  ,
t);
 
  521   double meanx(0.),meany(0.), meanz(0.);
 
  522   double meanxSqr(0.),meanySqr(0.), meanzSqr(0.);
 
  523   double rmsX(0.),rmsY(0.), rmsZ(0.);
 
  526   std::vector<double> vx,vy,vz;
 
  532     if (!
it->valid) 
continue;
 
  536       meanxSqr += (
it->x)*(
it->x);
 
  538       meanySqr += (
it->y)*(
it->y); 
 
  540       meanzSqr += (
it->z)*(
it->z);
 
  551   std::sort(vx.begin(),vx.end());
 
  552   std::sort(vy.begin(),vy.end());
 
  553   std::sort(vz.begin(),vz.end());
 
  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.);
 
  562             <<  
" z: " << medianz );
 
  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);
 
  599     rmsX = std::sqrt( std::abs(meanxSqr - meanx*meanx));
 
  602     rmsY = std::sqrt( std::abs(meanySqr - meany*meany));
 
  605     rmsZ = std::sqrt( std::abs(meanzSqr - meanz*meanz));
 
  619     << 
"   "  << 
", y: " << meany << 
" " << rmsY <<  
", z: " << meanz << 
" " << rmsZ );
 
  623   CLHEP::HepVector chi2Pos(4);
 
  624   CLHEP::HepSymMatrix chi2Cov(4);
 
  625   double  zpos(0), zerr(0);
 
  634     if (!
it->valid) 
continue;
 
  639     if ( std::abs( medianz - 
it->z ) > 10*rmsZ) 
fail += 16;
 
  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) << 
" > " 
  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) 
 
  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;
 
  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;
 
  680       zpos += 
it->z/
it->vzz; 
 
  685   ATH_MSG_DEBUG( 
"Removed: " << failCount << 
" vertices from simple mean,RMS." );
 
  695   chi2Cov.invert(invFail);
 
  696   chi2Pos = chi2Cov*chi2Pos;
 
  698   zerr    = 1./std::sqrt(zerr);
 
  705     ATH_MSG_DEBUG( 
"Mean position: x,y,z " << meanx << 
"  " << meany << 
"  " << meanz );
 
  706     ATH_MSG_DEBUG( 
"     RMS:      x,y,z " << rmsX  << 
"  " << rmsY  << 
"  " << rmsZ  );
 
  710     ATH_MSG_DEBUG( 
"New      chi2:" << chi2Pos << 
"\n" << chi2Cov << 
"\n" << zpos << 
"  " << zerr );
 
  735     ATH_MSG_INFO( 
"Log-Likelihood fit converged in outlier removal. Exiting outlier removal." );
 
  739   CLHEP::HepSymMatrix bsCov(2); 
 
  751     ATH_MSG_INFO( 
": removeOutliers: LL fit not use/converged/trusted - " <<
 
  752       "using chi2 for mean and simple RMS for width values " );
 
  759     bsCov(1,1) = rmsX*rmsX;
 
  760     bsCov(2,2) = rmsY*rmsY;
 
  777   std::multimap<double, BeamSpot::VrtHolder*> chi2map;
 
  782     if ( !
it->valid) 
continue; 
 
  794     double increaseChi2(0);
 
  796       increaseChi2 = 
fail * 1e5;
 
  801     CLHEP::HepSymMatrix 
b(2);
 
  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);
 
  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));
 
  820     chi2map.insert(std::make_pair(
ch, &(*
it))); 
 
  826   for (std::multimap<double, BeamSpot::VrtHolder*>::reverse_iterator vit =  chi2map.rbegin(); vit != chi2map.rend(); ++vit) {
 
  827     if ( !vit->second) 
continue; 
 
  828     if ( !vit->second->valid) 
continue; 
 
  830       ATH_MSG_DEBUG( 
" removeOutlier: Reached max number of vertex rejections for this iteration.\n"  
  831         << 
"\tNeed to recalculate mean positions." );
 
  841         ATH_MSG_DEBUG( 
" No more 'bad' vertices found in this iteration."  );
 
  843           ATH_MSG_DEBUG( 
" No futher vertices removed - moving to final iteration" );
 
  845           ATH_MSG_DEBUG( 
" Moving to next iteration of outlier removal." );
 
  853     vit->second->valid = 
false;
 
  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) 
 
  865     ATH_MSG_WARNING( 
"No vertices removed and fit still fails - most likely final result will fail"  );
 
  873     std::vector< BeamSpot::VrtHolder > vertexTemp(
m_vertexData);
 
  875     std::random_device 
rng;
 
  876     std::mt19937 urng(
rng());
 
  879     std::vector< BeamSpot::VrtHolder > vertex1,vertex2;
 
  883     bool goodFit1(
false), goodFit2(
false);
 
  889     ATH_MSG_WARNING( 
"Fit using \"vertex1\"  " << ( llSolve ? 
"Successful": 
"Failed") );
 
  913     ATH_MSG_WARNING( 
"Fit using \"vertex2\"  " << ( llSolve ? 
"Successful": 
"Failed") );
 
  933     ATH_MSG_WARNING( 
"Fit was " <<  ( goodFit2 || goodFit1 ? 
"Successful ": 
"Unsuccessful ") 
 
  934             <<
"  using a subset of the available vertices" );
 
  935     if (( goodFit2 || goodFit1) )
 
  941     } 
else if (goodFit2) {
 
  952   ATH_MSG_DEBUG( 
" Recursive debug: Loop: " << 
m_rCount << 
". Number of failed vertices: " << fCount );
 
  955   if ( fCount > 0 || ( fCount == 0 && 
m_rCount == 1 && !llSolve)) { 
 
  958         << 
". No more iterations performed." );
 
  970                std::pair<int, std::string> & 
status)  {
 
  971   if (!minuit) 
return false;
 
  973   std::string sRes = minuit->fCstatu.Data();
 
  975   Double_t fmin, fedm, errdef;
 
  976   Int_t npari,nparx,istat;
 
  977   minuit->mnstat(fmin, fedm, errdef,npari,nparx,istat);
 
  979   ATH_MSG_DEBUG( 
"Fit reports status: " << istat << 
" and " << sRes );
 
  984   bool sanityPassed(
true);
 
  987     minuit->GetParameter(6,
x,ex); 
 
  989       sanityPassed = 
false;
 
  992     minuit->GetParameter(4,
x,ex); 
 
  994       sanityPassed = 
false;
 
  997     minuit->GetParameter(5,
x,ex); 
 
  999       sanityPassed = 
false;
 
 1003     minuit->GetParameter(7,
x,ex); 
 
 1005       sanityPassed = 
false;
 
 1013   if (!sanityPassed) {
 
 1015     status.second = 
"FAILED BEAMSPOT SANITY CHECK";
 
 1017   ATH_MSG_DEBUG( 
"Fit " << ( sanityPassed ? 
"Passed": 
"Failed") << 
" sanity check: " );
 
 1019   if ( istat != 3) 
return false;
 
 1027   constexpr 
double Pi = 
M_PI;
 
 1034   using Vertices = std::vector<BeamSpot::VrtHolder>;
 
 1035   Vertices::const_iterator vit = BeamSpot::vertexData->begin();
 
 1040   double covXX,covYY,covXY;
 
 1044   for ( ; vit != vertexData->end(); ++vit) {
 
 1045     if (!vit->valid) 
continue; 
 
 1061     det = covXX * covYY - covXY*covXY;
 
 1062     double recDet = 1./
det;
 
 1065     temp  =  2*TMath::Log(2*Pi);
 
 1068     covXY = -covXY * recDet;
 
 1069     double t = covXX *recDet;
 
 1070     covXX = covYY *recDet;
 
 1106   minuit->FixParameter(6);
 
 1107   minuit->FixParameter(7);
 
 1110   minuit->FixParameter(0);
 
 1111   minuit->FixParameter(1);
 
 1112   minuit->FixParameter(2);
 
 1113   minuit->FixParameter(3);
 
 1116     minuit->FixParameter(4);
 
 1117     minuit->FixParameter(5);
 
 1138   if(printOut) minuit->SetPrintLevel(0);
 
 1150   std::map<std::string,double> covMap;
 
 1151   std::vector<double> covVector;
 
 1152   covVector.resize(55);
 
 1157   int map[] = {1,2,9,3,4,5,6,10,7,8};
 
 1159     int map2[] = {1,2,8,3,4,5,6,9,7,10};
 
 1160     for(
int i=0; 
i < 10; ++
i){
 
 1164     int map2[] = {1,2,6,3,4,8,9,7,10,5};
 
 1165     for(
int i=0; 
i < 10; ++
i){
 
 1171   for (
int i=0;
i<10;++
i) {
 
 1172     for (
int j=
i;j<10;++j) {
 
 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;
 
 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",
 
 1200   for(
int i = 0; 
i < 55; 
i++){
 
 1201     covMap[keyArr[
i]] = covVector[
i];
 
 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]);
 
 1222   CLHEP::HepSymMatrix covc = 
getCov(
z);
 
 1224   covMap[
"posXErr"]    = sqrt( covc(1,1) ); 
 
 1225   covMap[
"posYErr"]    = sqrt( covc(2,2) ); 
 
 1226   covMap[
"tiltXErr"]   = sqrt( covc(3,3) ); 
 
 1227   covMap[
"tiltYErr"]   = sqrt( covc(4,4) ); 
 
 1238   std::map<std::string,double> paramMap;