Index: /trunk/BNC/src/PPP/pppClient.cpp
===================================================================
--- /trunk/BNC/src/PPP/pppClient.cpp	(revision 11050)
+++ /trunk/BNC/src/PPP/pppClient.cpp	(revision 11051)
@@ -592,4 +592,11 @@
   catch (Exception& exc) {
     LOG << exc.what() << endl;
+    // A failed Kalman update (e.g. non-positive-definite covariance) leaves
+    // the filter state unusable and would be carried into every subsequent
+    // epoch => restart the filter, keeping ephemerides and corrections
+    // ----------------------------------------------------------------------
+    LOG << string(_epoTimeRover) << " pppClient: filter reset after exception" << endl;
+    delete _filter;
+    _filter = new t_pppFilter();
     return finish(failure, 6);
   }
Index: /trunk/BNC/src/PPP/pppFilter.cpp
===================================================================
--- /trunk/BNC/src/PPP/pppFilter.cpp	(revision 11050)
+++ /trunk/BNC/src/PPP/pppFilter.cpp	(revision 11051)
@@ -255,5 +255,11 @@
     // Kalman update step
     // ------------------
-    kalman(AA, ll, PP, _QFlt, _xFlt);
+    try {
+      kalman(AA, ll, PP, _QFlt, _xFlt);
+    }
+    catch (Exception&) {
+      logNonPosDef(_QFlt, params);
+      throw;
+    }
 
     // Check Residuals
@@ -319,4 +325,53 @@
   }
   return success;
+}
+
+// Diagnose a Variance-Covariance Matrix that failed Cholesky decomposition
+////////////////////////////////////////////////////////////////////////////
+void t_pppFilter::logNonPosDef(const SymmetricMatrix& QQ,
+                               const vector<t_pppParam*>& params) const {
+
+  string epoTimeStr = string(_epoTime);
+  int nn = QQ.Nrows();
+
+  for (int ii = 1; ii <= nn; ii++) {
+    double qq = QQ(ii,ii);
+    if (!(qq > 0.0)) {
+      LOG << epoTimeStr << " NotPosDef diag " << params[ii-1]->toString()
+          << " Q = " << scientific << qq << fixed << endl;
+    }
+  }
+
+  // Cholesky pivots: first index where the matrix stops being positive definite
+  // ---------------------------------------------------------------------------
+  Matrix LL(nn, nn); LL = 0.0;
+  for (int jj = 1; jj <= nn; jj++) {
+    double sum = QQ(jj,jj);
+    for (int kk = 1; kk < jj; kk++) {
+      sum -= LL(jj,kk) * LL(jj,kk);
+    }
+    if (!(sum > 0.0)) {
+      const t_pppParam* par = params[jj-1];
+      LOG << epoTimeStr << " NotPosDef pivot " << jj << " " << par->toString()
+          << " Q = " << scientific << QQ(jj,jj) << " pivot = " << sum
+          << fixed << " indexOld = " << par->indexOld() << endl;
+      for (int kk = 1; kk < jj; kk++) {
+        double rho = QQ(jj,kk) / sqrt(QQ(jj,jj) * QQ(kk,kk));
+        if (fabs(rho) > 0.999) {
+          LOG << epoTimeStr << " NotPosDef   corr " << params[kk-1]->toString()
+              << ' ' << setprecision(9) << rho << endl;
+        }
+      }
+      return;
+    }
+    LL(jj,jj) = sqrt(sum);
+    for (int ii = jj + 1; ii <= nn; ii++) {
+      double hlp = QQ(ii,jj);
+      for (int kk = 1; kk < jj; kk++) {
+        hlp -= LL(ii,kk) * LL(jj,kk);
+      }
+      LL(ii,jj) = hlp / LL(jj,jj);
+    }
+  }
 }
 
Index: /trunk/BNC/src/PPP/pppFilter.h
===================================================================
--- /trunk/BNC/src/PPP/pppFilter.h	(revision 11050)
+++ /trunk/BNC/src/PPP/pppFilter.h	(revision 11051)
@@ -81,4 +81,6 @@
                          const std::vector<t_pppSatObs*>& obsVector);
 
+  void logNonPosDef(const SymmetricMatrix& QQ, const std::vector<t_pppParam*>& params) const;
+
   t_irc resetAmb(t_prn prn, const std::vector<t_pppSatObs*>& obsVector, t_lc lc,
                  SymmetricMatrix* QSav = 0, ColumnVector* xSav = 0);
