Index: trunk/BNC/src/satObs.cpp
===================================================================
--- trunk/BNC/src/satObs.cpp	(revision 11008)
+++ trunk/BNC/src/satObs.cpp	(revision 11037)
@@ -493,4 +493,99 @@
 //
 ////////////////////////////////////////////////////////////////////////////
+void t_satAntenna::writeEpoch(ostream* out, const QList<t_satAntenna>& antList) {
+  if (!out || antList.size() == 0) {
+    return;
+  }
+  out->setf(ios::fixed);
+  bncTime epoTime;
+  QListIterator<t_satAntenna> it(antList);
+  while (it.hasNext()) {
+    const t_satAntenna& satAntenna = it.next();
+    if (!epoTime.valid()) {
+      epoTime = satAntenna._time;
+      *out << "> SAT_ANTENNA " << epoTime.datestr(' ') << ' ' << epoTime.timestr(1, ' ') << " "
+        << 0 << " " << antList.size() << ' ' << satAntenna._staID << endl;
+    }
+    // header fields are genuinely per system (e.g. GPS/GLONASS/Galileo carry
+    // different maximumOffNadirAngle), so they are written per satellite
+    // rather than once per epoch like t_satPhaseBias's metadata line
+    *out << satAntenna._prn.toString() << ' '
+      << setw(4) << satAntenna._ssrProviderID << ' '
+      << setw(2) << satAntenna._satelliteAntennaIOD << ' '
+      << setw(1) << satAntenna._phaseCenterInfoInd << ' '
+      << setw(1) << satAntenna._groupDelayInfoInd << ' '
+      << setw(1) << satAntenna._nadirAngleDependentCorrInd << ' '
+      << setw(2) << satAntenna._maximumOffNadirAngle << ' '
+      << setw(2) << satAntenna._nadirAngleRangeExtension << "   "
+      << setw(2) << satAntenna._freq.size();
+    for (unsigned ii = 0; ii < satAntenna._freq.size(); ii++) {
+      const t_frqAntenna& frqAntenna = satAntenna._freq[ii];
+      *out << "   " << frqAntenna._freqIndex << ' '
+        << frqAntenna._nadirCorrectionIndicator << ' '
+        << setw(10) << setprecision(4) << frqAntenna._nadirCorrection;
+      for (unsigned jj = 0; jj < frqAntenna._nadirAngleCorrection.size(); jj++) {
+        *out << ' ' << setw(9) << setprecision(4) << frqAntenna._nadirAngleCorrection[jj];
+      }
+    }
+    *out << endl;
+  }
+  out->flush();
+}
+
+//
+////////////////////////////////////////////////////////////////////////////
+void t_satAntenna::readEpoch(const string& epoLine, istream& inStream, QList<t_satAntenna>& antList) {
+  bncTime epoTime;
+  unsigned int updateInt;
+  int numSat;
+  string staID;
+  if (t_corrSSR::readEpoLine(epoLine, epoTime, updateInt, numSat, staID) != t_corrSSR::satAntenna) {
+    return;
+  }
+  for (int ii = 0; ii < numSat; ii++) {
+    t_satAntenna satAntenna;
+    satAntenna._time = epoTime;
+    satAntenna._staID = staID;
+
+    string line;
+    getline(inStream, line);
+    istringstream in(line.c_str());
+
+    int numFreq;
+    in >> satAntenna._prn
+       >> satAntenna._ssrProviderID
+       >> satAntenna._satelliteAntennaIOD
+       >> satAntenna._phaseCenterInfoInd
+       >> satAntenna._groupDelayInfoInd
+       >> satAntenna._nadirAngleDependentCorrInd
+       >> satAntenna._maximumOffNadirAngle
+       >> satAntenna._nadirAngleRangeExtension
+       >> numFreq;
+
+    char sys = satAntenna._prn.system();
+    int num = satAntenna._prn.number();
+    int flag = t_corrSSR::getSsrNavTypeFlag(sys, num);
+    satAntenna._prn.setFlag(flag);
+
+    unsigned int numAngles = satAntenna._nadirAngleDependentCorrInd ?
+                              satAntenna._maximumOffNadirAngle + 1 : 0;
+
+    for (int jj = 0; jj < numFreq; jj++) {
+      t_frqAntenna frqAntenna;
+      in >> frqAntenna._freqIndex >> frqAntenna._nadirCorrectionIndicator >> frqAntenna._nadirCorrection;
+      for (unsigned kk = 0; kk < numAngles; kk++) {
+        double val;
+        in >> val;
+        frqAntenna._nadirAngleCorrection.push_back(val);
+      }
+      satAntenna._freq.push_back(frqAntenna);
+    }
+
+    antList.push_back(satAntenna);
+  }
+}
+
+//
+////////////////////////////////////////////////////////////////////////////
 void t_metaData::write(ostream* out, const t_metaData& md) {
   if (!out || md._entries.size() == 0) {
@@ -582,4 +677,7 @@
     else if (typeString == "META_DATA") {
       return metaData;
+    }
+    else if (typeString == "SAT_ANTENNA") {
+      return satAntenna;
     }
   }
