Index: trunk/BNC/src/PPP/pppClient.cpp
===================================================================
--- trunk/BNC/src/PPP/pppClient.cpp	(revision 10369)
+++ trunk/BNC/src/PPP/pppClient.cpp	(revision 10373)
@@ -67,4 +67,5 @@
     }
   }
+  _offGps = 0.0;
   _offGlo = 0.0;
   _offGal = 0.0;
@@ -255,5 +256,30 @@
                                   ColumnVector& xyzc, bool print) {
   t_lc::type tLC = t_lc::dummy;
+  char sysBancroft = 'G';
   int  numBancroft = obsVector.size();
+
+  _usedSystems['G'] = _usedSystems['R'] = _usedSystems['E'] = _usedSystems['C'] = 0;
+  for (unsigned jj = 0; jj < obsVector.size(); jj++) {
+    const t_pppSatObs* satObs = obsVector[jj];
+    char sys = satObs->prn().system();
+    _usedSystems[sys]++;
+  }
+
+  if      ((numBancroft = _usedSystems.value('G')) >= _opt->_minObs) {
+    sysBancroft = 'G';
+  }
+  else if ((numBancroft = _usedSystems.value('E')) >= _opt->_minObs) {
+    sysBancroft = 'E';
+  }
+  else if ((numBancroft = _usedSystems.value('C')) >= _opt->_minObs) {
+    sysBancroft = 'C';
+  }
+  else if ((numBancroft = _usedSystems.value('R')) >= _opt->_minObs) {
+    sysBancroft = 'R';
+  }
+  else {
+    LOG << "t_pppClient::cmpBancroft not enough observations: " << endl;
+    return failure;
+  }
 
   while (_running) {
@@ -262,4 +288,5 @@
     for (unsigned ii = 0; ii < obsVector.size(); ii++) {
       const t_pppSatObs* satObs = obsVector.at(ii);
+      if (satObs->prn().system() == sysBancroft) {
       if (tLC == t_lc::dummy) {
         if (satObs->isValid(t_lc::cIF)) {
@@ -282,4 +309,5 @@
       }
     }
+    }
     if (iObs + 1 < _opt->_minObs) {
       LOG << "t_pppClient::cmpBancroft not enough observations: " << iObs + 1 << endl;
@@ -300,5 +328,7 @@
     for (unsigned ii = 0; ii < obsVector.size(); ii++) {
       const t_pppSatObs* satObs = obsVector.at(ii);
-      if (satObs->isValid() && (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
+      char sys = satObs->prn().system();
+      if (satObs->isValid() && sys == sysBancroft &&
+          (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
         ColumnVector rr = satObs->xc().Rows(1,3) - xyzc.Rows(1,3);
         double res = rr.NormFrobenius() - satObs->obsValue(tLC)
@@ -316,5 +346,5 @@
         if (!_epoTimeRover.undef()) LOG << string(_epoTimeRover);
         LOG << "\n---------------------------------------------------------------\n";
-        LOG << string(epoTime) << " BANCROFT "  << ": "
+        LOG << string(epoTime) << " BANCROFT " <<   sysBancroft << ": "
             << setw(14) << setprecision(3) << xyzc[0] << ' '
             << setw(14) << setprecision(3) << xyzc[1] << ' '
@@ -334,4 +364,56 @@
 
   return success;
+}
+// Compute A Priori Gps Clock Offset
+//////////////////////////////////////////////////////////////////////////////
+double t_pppClient::cmpOffGps(vector<t_pppSatObs*>& obsVector) {
+
+  t_lc::type tLC   = t_lc::dummy;
+  double     offGps = 0.0;
+
+  if (_opt->useSystem('G')) {
+    while (obsVector.size() > 0) {
+      offGps = 0.0;
+      double   maxRes      = 0.0;
+      int      maxResIndex = -1;
+      unsigned nObs        = 0;
+      t_prn    maxResPrn;
+      for (unsigned ii = 0; ii < obsVector.size(); ii++) {
+        const t_pppSatObs* satObs = obsVector.at(ii);
+        if (satObs->prn().system() == 'G') {
+          if (tLC == t_lc::dummy) {
+            tLC = satObs->isValid(t_lc::cIF) ? t_lc::cIF : t_lc::c1;
+          }
+          if (satObs->isValid(tLC) && (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle)) {
+            double ll = satObs->obsValue(tLC) - satObs->cmpValue(tLC);
+            ++nObs;
+            offGps += ll;
+            if (fabs(ll) > fabs(maxRes)) {
+              maxRes      = ll;
+              maxResIndex = ii;
+              maxResPrn   = satObs->prn();
+            }
+          }
+        }
+      }
+
+      if (nObs > 0) {
+        offGps = offGps / nObs;
+      }
+      else {
+        offGps = 0.0;
+      }
+
+      if (fabs(maxRes) > 100.0) {
+        LOG << "t_pppClient::cmpOffGps outlier " << maxResPrn.toString() << " " << maxRes << endl;
+        delete obsVector.at(maxResIndex);
+        obsVector.erase(obsVector.begin() + maxResIndex);
+      }
+      else {
+        break;
+      }
+    }
+  }
+  return offGps;
 }
 
@@ -636,4 +718,5 @@
     }
 
+    _offGps = cmpOffGps(_obsRover);
     _offGlo = cmpOffGlo(_obsRover);
     _offGal = cmpOffGal(_obsRover);
Index: trunk/BNC/src/PPP/pppClient.h
===================================================================
--- trunk/BNC/src/PPP/pppClient.h	(revision 10369)
+++ trunk/BNC/src/PPP/pppClient.h	(revision 10373)
@@ -36,10 +36,13 @@
   const bncAntex*     antex() const {return _antex;}
   const t_pppStation* staRover() const {return _staRover;}
+  double              offGps() const {return _offGps;}
   double              offGlo() const {return _offGlo;}
   double              offGal() const {return _offGal;}
   double              offBds() const {return _offBds;}
+  void                resetOffGps() {_offGps = 0.0;}
   void                resetOffGlo() {_offGlo = 0.0;}
   void                resetOffGal() {_offGal = 0.0;}
   void                resetOffBds() {_offBds = 0.0;}
+
 
   std::ostringstream& log() {return *_log;}
@@ -63,4 +66,5 @@
   t_irc cmpBancroft(const bncTime& epoTime, std::vector<t_pppSatObs*>& obsVector,
                     ColumnVector& xyzc, bool print);
+  double cmpOffGps(std::vector<t_pppSatObs*>& obsVector);
   double cmpOffGlo(std::vector<t_pppSatObs*>& obsVector);
   double cmpOffGal(std::vector<t_pppSatObs*>& obsVector);
@@ -75,4 +79,5 @@
   bncAntex*                 _antex;
   t_pppFilter*              _filter;
+  double                    _offGps;
   double                    _offGlo;
   double                    _offGal;
Index: trunk/BNC/src/PPP/pppFilter.cpp
===================================================================
--- trunk/BNC/src/PPP/pppFilter.cpp	(revision 10369)
+++ trunk/BNC/src/PPP/pppFilter.cpp	(revision 10373)
@@ -76,5 +76,5 @@
   string epoTimeStr = string(_epoTime);
 
-  const QList<char> &usedSystems = _parlist->usedSystems();
+  const QMap<char, int> &usedSystems = _parlist->usedSystems();
 
   // Set Parameters
@@ -92,7 +92,7 @@
   // Process Satellite Systems separately
   // ------------------------------------
-  for (int iSys = 0; iSys < usedSystems.size(); iSys++) {
-    char sys = usedSystems[iSys];
-    unsigned int num = 0;
+  for (auto it = usedSystems.begin(); it != usedSystems.end(); ++it) {
+    char     sys = it.key();
+    unsigned num = 0;
     vector<t_pppSatObs*> obsVector;
     for (unsigned jj = 0; jj < allObs.size(); jj++) {
@@ -185,4 +185,8 @@
             AA[iObs][iPar] = par->partial(_epoTime, obs, tLC);
           }
+          double offGps = 0.0;
+          if (sys == 'G' && tLC != t_lc::MW) {
+            offGps = PPP_CLIENT->offGps();
+          }
           double offGlo = 0.0;
           if (sys == 'R' && tLC != t_lc::MW) {
@@ -197,5 +201,5 @@
             offBds = PPP_CLIENT->offBds();
           }
-          ll[iObs] = obs->obsValue(tLC) - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
+          ll[iObs] = obs->obsValue(tLC) -offGps - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
           PP[iObs] = 1.0 / (obs->sigma(tLC) * obs->sigma(tLC));
         }
@@ -229,4 +233,8 @@
               AA[iObs][iPar] = par->partial(_epoTime, obs, tLC);
             }
+            double offGps = 0.0;
+            if (sys == 'G' && tLC != t_lc::MW) {
+              offGps = PPP_CLIENT->offGps();
+            }
             double offGlo = 0.0;
             if (sys == 'R' && tLC != t_lc::MW) {
@@ -241,5 +249,5 @@
               offBds = PPP_CLIENT->offBds();
             }
-            ll[iObs] = obs->obsValue(tLC) - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
+            ll[iObs] = obs->obsValue(tLC) -offGps - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
             PP[iObs] = 1.0 / (obs->sigma(tLC) * obs->sigma(tLC));
           }
@@ -375,5 +383,5 @@
 
         // Check Pre-Fit Residuals
-        /* -----------------------
+        // -----------------------
         else {
           ColumnVector AA(params.size());
@@ -382,4 +390,8 @@
             AA[iPar] = par->partial(_epoTime, obs, tLC);
           }
+          double offGps = 0.0;
+          if (sys == 'G' && tLC != t_lc::MW) {
+            offGps = PPP_CLIENT->offGps();
+          }
           double offGlo = 0.0;
           if (sys == 'R' && tLC != t_lc::MW) {
@@ -394,5 +406,5 @@
             offBds = PPP_CLIENT->offBds();
           }
-          double ll = obs->obsValue(tLC) - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA);
+          double ll = obs->obsValue(tLC) -offGps - offGlo - offGal - offBds  - obs->cmpValue(tLC) - DotProduct(_x0, AA);
           double vv = DotProduct(AA, _xFlt) - ll;
 
@@ -402,5 +414,5 @@
             resetAmb(obs->prn(), obsVector, tLC);
           }
-        }*/
+        }
       }
     }
Index: trunk/BNC/src/PPP/pppParlist.cpp
===================================================================
--- trunk/BNC/src/PPP/pppParlist.cpp	(revision 10369)
+++ trunk/BNC/src/PPP/pppParlist.cpp	(revision 10373)
@@ -74,4 +74,8 @@
          const t_pppSatObs* obs = obsVector->at(ii);
          if (obs->prn() == _prn) {
+           double offGps = 0.0;
+           if (_prn.system() == 'G' && tLC != t_lc::MW) {
+             offGps = PPP_CLIENT->offGps();
+           }
            double offGlo = 0.0;
            if (_prn.system() == 'R' && tLC != t_lc::MW) {
@@ -86,9 +90,14 @@
              offBds = PPP_CLIENT->offBds();
            }
-           _x0 = floor((obs->obsValue(tLC) - offGlo - offGal - offBds - obs->cmpValue(tLC)) / obs->lambda(tLC) + 0.5);
+           _x0 = floor((obs->obsValue(tLC) - offGps - offGlo - offGal - offBds - obs->cmpValue(tLC)) / obs->lambda(tLC) + 0.5);
            break;
          }
        }
      }
+     break;
+   case offGps:
+     _epoSpec = true;
+     _sigma0  = OPT->_aprSigClkOff;
+     _x0      = PPP_CLIENT->offGps();
      break;
    case offGlo:
@@ -171,4 +180,7 @@
     if (tLC == t_lc::GIM) {return 0.0;}
     return 1.0;
+  case offGps:
+    if (tLC == t_lc::GIM) {return 0.0;}
+    return (obs->prn().system() == 'G') ? 1.0 : 0.0;
   case offGlo:
     if (tLC == t_lc::GIM) {return 0.0;}
@@ -299,4 +311,7 @@
     ss << "REC_CLK     ";
     break;
+  case offGps:
+    ss << "OFF_GPS     ";
+    break;
   case offGlo:
     ss << "OFF_GLO     ";
@@ -345,5 +360,4 @@
 ////////////////////////////////////////////////////////////////////////////
 t_pppParlist::~t_pppParlist() {
-  _usedSystems.clear();
 
   for (unsigned ii = 0; ii < _params.size(); ii++) {
@@ -396,11 +410,9 @@
   // check which systems have observations
   // -------------------------------------
-  _usedSystems.clear();
+  _usedSystems['G'] = _usedSystems['R'] = _usedSystems['E'] = _usedSystems['C'] = 0;
   for (unsigned jj = 0; jj < obsVector.size(); jj++) {
     const t_pppSatObs* satObs = obsVector[jj];
     char sys = satObs->prn().system();
-    if (!_usedSystems.contains(sys)) {
-      _usedSystems.append(sys);
-    }
+    _usedSystems[sys]++;
   }
 
@@ -438,5 +450,5 @@
                 par->type() == t_pppParam::cBiasG2 ||
                 par->type() == t_pppParam::pBiasG1 ||
-                par->type() == t_pppParam::pBiasG2) && !usedSystems().contains('G')) {
+                par->type() == t_pppParam::pBiasG2) && !_usedSystems.value('G')) {
 #ifdef BNC_DEBUG_PPP
        //LOG << "remove1 " << par->toString() << std::endl;
@@ -448,5 +460,5 @@
                 par->type() == t_pppParam::cBiasR2 ||
                 par->type() == t_pppParam::pBiasR1 ||
-                par->type() == t_pppParam::pBiasR2) && !usedSystems().contains('R')) {
+                par->type() == t_pppParam::pBiasR2) && !_usedSystems.value('R')){
 #ifdef BNC_DEBUG_PPP
         //LOG << "remove1 " << par->toString() << std::endl;
@@ -458,5 +470,5 @@
                 par->type() == t_pppParam::cBiasE2 ||
                 par->type() == t_pppParam::pBiasE1 ||
-                par->type() == t_pppParam::pBiasE2) && !usedSystems().contains('E')) {
+                par->type() == t_pppParam::pBiasE2) && !_usedSystems.value('E')) {
 #ifdef BNC_DEBUG_PPP
         //LOG << "remove1 " << par->toString() << std::endl;
@@ -468,5 +480,5 @@
                 par->type() == t_pppParam::cBiasC2 ||
                 par->type() == t_pppParam::pBiasC1 ||
-                par->type() == t_pppParam::pBiasC2) && !usedSystems().contains('C')) {
+                par->type() == t_pppParam::pBiasC2) && !_usedSystems.value('C')) {
 #ifdef BNC_DEBUG_PPP
         //LOG << "remove1 " << par->toString() << std::endl;
@@ -497,18 +509,38 @@
   // GLONASS Clock Offset
   // --------------------
-  if (OPT->useSystem('R')) {
+  if ( _usedSystems.value('R')  &&
+      (_usedSystems.value('G') || _usedSystems.value('E') || _usedSystems.value('C'))) {
     required.push_back(new t_pppParam(t_pppParam::offGlo, t_prn(), t_lc::dummy));
+  }
+  else {
+    PPP_CLIENT->resetOffGlo();
   }
 
   // Galileo Clock Offset
   // --------------------
-  if (OPT->useSystem('E')) {
+  if (_usedSystems.value('E') && _usedSystems.value('G') && _usedSystems.value('G') >= OPT->_minObs) {
     required.push_back(new t_pppParam(t_pppParam::offGal, t_prn(), t_lc::dummy));
+  }
+  else {
+    PPP_CLIENT->resetOffGal();
+  }
+
+  // GPS Clock Offset
+  // --------------------
+  if (_usedSystems.value('E') && _usedSystems.value('G') && _usedSystems.value('G') < OPT->_minObs) {
+    required.push_back(new t_pppParam(t_pppParam::offGps, t_prn(), t_lc::dummy));
+  }
+  else {
+    PPP_CLIENT->resetOffGps();
   }
 
   // BDS Clock Offset
   // ----------------
-  if (OPT->useSystem('C')) {
+  if (_usedSystems.contains('C')  &&
+      (_usedSystems.contains('G') || _usedSystems.contains('E'))) {
     required.push_back(new t_pppParam(t_pppParam::offBds, t_prn(), t_lc::dummy));
+  }
+  else {
+    PPP_CLIENT->resetOffBds();
   }
 
Index: trunk/BNC/src/PPP/pppParlist.h
===================================================================
--- trunk/BNC/src/PPP/pppParlist.h	(revision 10369)
+++ trunk/BNC/src/PPP/pppParlist.h	(revision 10373)
@@ -14,5 +14,5 @@
 class t_pppParam {
  public:
-  enum e_type {crdX, crdY, crdZ, rClk, offGlo, offGal, offBds, trp, ion, amb,
+  enum e_type {crdX, crdY, crdZ, rClk, offGps, offGlo, offGal, offBds, trp, ion, amb,
                cBiasG1, cBiasR1, cBiasE1, cBiasC1, pBiasG1, pBiasR1, pBiasE1, pBiasC1,
                cBiasG2, cBiasR2, cBiasE2, cBiasC2, pBiasG2, pBiasR2, pBiasE2, pBiasC2};
@@ -104,5 +104,5 @@
   const std::vector<t_pppParam*>& params() const {return _params;}
   std::vector<t_pppParam*>& params() {return _params;}
-  const QList<char>& usedSystems() const {return _usedSystems;}
+  const QMap<char, int>& usedSystems() const {return _usedSystems;}
   void printResult(const bncTime& epoTime, const SymmetricMatrix& QQ,
                    const ColumnVector& xx) const;
@@ -111,5 +111,5 @@
  private:
   std::vector<t_pppParam*> _params;
-  QList<char>              _usedSystems;
+  QMap<char, int>          _usedSystems;
 };
 
Index: trunk/BNC/src/PPP/pppSatObs.cpp
===================================================================
--- trunk/BNC/src/PPP/pppSatObs.cpp	(revision 10369)
+++ trunk/BNC/src/PPP/pppSatObs.cpp	(revision 10373)
@@ -660,4 +660,8 @@
   for (unsigned ii = 0; ii < OPT->LCs(sys).size(); ii++) {
     t_lc::type tLC = OPT->LCs(sys)[ii];
+    double offGps = 0.0;
+    if (_prn.system() == 'G' && tLC != t_lc::MW) {
+      offGps = PPP_CLIENT->offGps();
+    }
     double offGlo = 0;
     if (sys == 'R' && tLC != t_lc::MW) {
@@ -675,5 +679,5 @@
         << setw(12) << setprecision(3) << obsValue(tLC) << " "
         << setw(12) << setprecision(3) << cmpValue(tLC) << " "
-        << setw(12) << setprecision(3) << obsValue(tLC) - offGlo - offGal - offBds  - cmpValue(tLC) << endl;
+        << setw(12) << setprecision(3) << obsValue(tLC) - offGps - offGlo - offGal - offBds  - cmpValue(tLC) << endl;
   }
 }
