132 (!(
valid & validFromValid) && !(
valid & validUntilValid)))
136 if ((
valid & validFromValid) &&
time < validFrom)
140 if ((
valid & validUntilValid) &&
time > validUntil)
154 return string(
"invalid");
163 return (type +
string(
"/") + serialNo +
string(
"/") +
171 double elev_nadir)
const
176 double pcv = getPhaseCenterVariation(freq, azim, elev_nadir);
177 Triple pco = getPhaseCenterOffset(freq);
179 double elev = elev_nadir;
182 elev = 90. - elev_nadir;
191 return (-pcv + pco[0] * cosel * cosaz + pco[1] * cosel * sinaz +
214 map<string, antennaPCOandPCVData>::const_iterator it =
215 freqPCVmap.find(freq);
216 if (it == freqPCVmap.end())
219 "Frequency " + freq +
220 " not found! System not supported or data corrupted.");
226 for (
int i = 0; i < 3; i++)
227 retval[i] = it->second.PCOvalue[i];
236 double elev_nadir)
const
243 if (elev_nadir < 0.0 || elev_nadir > 90.0)
245 Exception e(
"Invalid elevation/nadir angle");
249 double retpco, azim, zen;
253 zen = 90. - elev_nadir;
262 while (azim >= 360.0)
277 double az_lo, az_hi, zn_lo, zn_hi, pco[4];
278 map<double, zenOffsetMap>::const_iterator jt_lo, jt_hi;
280 map<string, antennaPCOandPCVData>::const_iterator it;
281 it = freqPCVmap.find(freq);
282 if (it == freqPCVmap.end())
285 " not found! System not supported or data corrupted.");
295 jt_hi = azzenmap.begin();
300 jt_hi = azzenmap.find(azim);
304 if (jt_hi != azzenmap.end())
310 evaluateZenithMap(zen, zenoffmap, zn_lo, zn_hi, pco[2], pco[0]);
317 retpco = (pco[0] * (zen - zn_lo) + pco[2] * (zn_hi - zen)) /
326 jt_lo = jt_hi = azzenmap.lower_bound(azim);
328 if (jt_lo == azzenmap.end())
331 az_lo = jt_lo->first;
332 jt_hi = azzenmap.begin();
333 az_hi = jt_hi->first + 360.;
336 else if (jt_hi == azzenmap.begin())
338 az_hi = jt_hi->first;
339 (jt_lo = azzenmap.end())--;
340 az_lo = jt_lo->first - 360.;
345 az_hi = jt_hi->first;
347 az_lo = jt_lo->first;
352 evaluateZenithMap(zen, jt_hi->second, zn_lo, zn_hi, pco[3], pco[1]);
353 evaluateZenithMap(zen, jt_lo->second, zn_lo, zn_hi, pco[2], pco[0]);
359 retpco = (pco[2] * (az_hi - azim) + pco[3] * (azim - az_lo)) /
366 retpco = (pco[0] * (az_hi - azim) * (zen - zn_lo) +
367 pco[1] * (azim - az_lo) * (zen - zn_lo) +
368 pco[2] * (az_hi - azim) * (zn_hi - zen) +
369 pco[3] * (azim - az_lo) * (zn_hi - zen)) /
370 ((az_hi - az_lo) * (zn_hi - zn_lo));
380 map<string, antennaPCOandPCVData>::const_iterator it;
381 map<double, zenOffsetMap>::const_iterator jt;
382 map<double, double>::const_iterator kt;
384 s <<
"Antenna Type/SN: [" << name() <<
"]";
387 s <<
" (Receiver)" << endl;
391 if (PRN != -1 || SVN != -1)
396 s << string(
" PRN ") +
asString(PRN);
400 s << string(
" SVN ") +
asString(SVN);
404 s <<
" code " << satCode <<
", COSPAR " << cospar << endl;
412 s <<
"Method: " << method <<
" Agency: " <<
agency
413 <<
" #Cal.Ant.s: " << noAntCalibrated <<
" Date: " <<
date << endl;
416 s <<
"Azimuth dependence, delta azimuth = " << fixed << setprecision(1)
417 << azimDelta << endl;
421 s <<
"No azimuth dependence" << endl;
423 s <<
"Elevation dependence: from " << fixed << setprecision(1)
424 << zenRange[0] <<
" to " << zenRange[1] <<
" in steps of "
425 << zenRange[2] <<
" degrees." << endl;
426 s <<
"Frequencies stored (" << nFreq <<
"): ";
428 for (it = freqPCVmap.begin(); it != freqPCVmap.end(); ++it)
429 s <<
" " << it->first;
434 :
printTime(validFrom,
"%02m/%02d/%04Y %02H:%02M:%.7s"))
438 :
printTime(validUntil,
"%02m/%02d/%04Y %02H:%02M:%.7s"))
440 if (!sinexCode.empty())
442 s <<
"SINEX code: " << sinexCode << endl;
444 for (
size_t i = 0; i < commentList.size(); i++)
447 s <<
"Comment " << setw(2) << i + 1 <<
": " << commentList[i] << endl;
452 for (it = freqPCVmap.begin(); it != freqPCVmap.end(); it++)
456 << (isRxAntenna ?
"NEU from antenna reference position"
457 :
"body XYZ from center-of-mass")
459 <<
" (freq " << it->first <<
") " << fixed << setprecision(2)
460 << setw(10) << antpco.
PCOvalue[0] <<
", " << setw(10)
468 for (it = freqPCVmap.begin(); it != freqPCVmap.end(); it++)
470 s <<
"Offset values for frequency: " << it->first <<
" ("
471 << (it->second.hasAzimuth ?
"has" :
"does not have") <<
" azimuths)"
477 << (isRxAntenna ?
"NEU from antenna reference position"
478 :
"body XYZ from center-of-mass")
479 <<
") (mm):" << fixed << setprecision(2) << setw(10)
481 <<
", " << setw(10) << antpco.
PCOvalue[2] << endl;
484 if (
valid & neuFreqRMSValid)
487 << (isRxAntenna ?
"NEU from antenna reference position"
488 :
"body XYZ from center-of-mass")
489 <<
" (mm):" << fixed << setprecision(2) << setw(10)
490 << antpco.
PCOrms[0] <<
", " << setw(10) << antpco.
PCOrms[1]
491 <<
", " << setw(10) << antpco.
PCOrms[2] << endl;
496 s << fixed << setprecision(2);
500 s <<
" PCVs follow, one azimuth per row: AZ(deg) { PCVs(EL)(mm) .. "
503 for (kt = zenoffmap.begin(); kt != zenoffmap.end(); kt++)
504 s << setw(8) << kt->first;
507 for (jt = azel.begin(); jt != azel.end(); jt++)
509 double azimuth = jt->first;
517 s << setw(9) << azimuth;
519 for (kt = zenoffmap.begin(); kt != zenoffmap.end(); kt++)
520 s << setw(8) << kt->second;
534 double& zen_hi,
double& pco_lo,
535 double& pco_hi)
const
537 map<double, double>::const_iterator kt;
540 kt = eomap.find(zen);
541 if (kt != eomap.end())
543 zen_lo = zen_hi = zen;
544 pco_lo = pco_hi = kt->second;
549 kt = eomap.lower_bound(zen);
552 if (kt == eomap.end() || kt == eomap.begin())
554 if (kt == eomap.end())
558 zen_lo = zen_hi = zen;
559 pco_lo = pco_hi = kt->second;
577 FFStreamError fse(
string(
"Cannot write invalid AntexData"));
583 map<string, antennaPCOandPCVData>::const_iterator it;
584 map<double, zenOffsetMap>::const_iterator jt;
585 map<double, double>::const_iterator kt;
589 strm << line << endl;
596 line += typeSerNumString;
604 line += methodString;
620 line += zenithString;
626 line += numFreqString;
630 if (
valid & validFromValid)
632 if (stringValidFrom.empty())
634 line = writeTime(validFrom);
638 line = stringValidFrom;
641 line += validFromString;
646 if (
valid & validUntilValid)
648 if (stringValidUntil.empty())
650 line = writeTime(validUntil);
654 line = stringValidUntil;
657 line += validUntilString;
662 if (
valid & sinexCodeValid)
665 line += sinexCodeString;
670 for (i = 0; i < commentList.size(); i++)
673 line += dataCommentString;
680 for (it = freqPCVmap.begin(); it != freqPCVmap.end(); it++)
689 line += startFreqString;
694 for (i = 0; i < 3; i++)
697 line += neuFreqString;
703 for (jt = azel.begin(); jt != azel.end(); jt++)
712 line = string(
" NOAZI");
714 for (kt = zenoffmap.begin(); kt != zenoffmap.end(); kt++)
718 strm << line << endl;
725 line += endOfFreqString;
730 if (
valid & (startFreqRMSValid | neuFreqRMSValid | endOfFreqRMSValid))
733 for (it = freqPCVmap.begin(); it != freqPCVmap.end(); it++)
741 line += startFreqRMSString;
746 for (i = 0; i < 3; i++)
749 line += neuFreqRMSString;
755 for (jt = azel.begin(); jt != azel.end(); jt++)
764 line = string(
" NOAZI");
766 for (kt = zenoffmap.begin(); kt != zenoffmap.end(); kt++)
770 strm << line << endl;
777 line += endOfFreqRMSString;
784 strm << line << endl;
805 while (!(
valid & endOfAntennaValid))
810 if (line.length() == 0)
817 ParseDataRecord(line);
819 catch (FFStreamError& e)
836 FFStreamError fse(
string(
"Records are out of order: detected at ") +
847 static bool hasAzim, foundRMS(
false);
850 string label(line, 60, 20);
852 if (label == startAntennaString)
854 throwRecordOutOfOrder(typeSerNumValid, label);
855 valid |= startAntennaValid;
857 else if (label == typeSerNumString)
859 throwRecordOutOfOrder(methodValid, label);
874 if (serialNo.length() > 1)
876 PRN =
asInt(serialNo.substr(1, 2));
882 if (satCode.length() > 1)
884 SVN =
asInt(satCode.substr(1, 3));
890 systemChar = line[20];
892 valid |= typeSerNumValid;
894 else if (label == methodString)
896 throwRecordOutOfOrder(daziValid, label);
899 noAntCalibrated =
asInt(line.substr(40, 6));
901 valid |= methodValid;
903 else if (label == daziString)
905 throwRecordOutOfOrder(zenithValid, label);
906 azimDelta =
asDouble(line.substr(2, 6));
917 else if (label == zenithString)
919 throwRecordOutOfOrder(numFreqValid, label);
920 zenRange[0] =
asDouble(line.substr(2, 6));
921 zenRange[1] =
asDouble(line.substr(8, 6));
922 zenRange[2] =
asDouble(line.substr(14, 6));
923 valid |= zenithValid;
925 else if (label == numFreqString)
927 throwRecordOutOfOrder(validFromValid | validUntilValid |
928 sinexCodeValid | dataCommentValid |
931 nFreq = (
unsigned int)(
asInt(line.substr(0, 6)));
932 valid |= numFreqValid;
934 else if (label == validFromString)
936 throwRecordOutOfOrder(validUntilValid | sinexCodeValid |
937 dataCommentValid | startFreqValid,
939 stringValidFrom = line.substr(0, 43);
940 validFrom = parseTime(line);
941 valid |= validFromValid;
943 else if (label == validUntilString)
945 throwRecordOutOfOrder(
946 sinexCodeValid | dataCommentValid | startFreqValid, label);
947 stringValidUntil = line.substr(0, 43);
948 validUntil = parseTime(line);
953 valid |= validUntilValid;
955 else if (label == sinexCodeString)
957 throwRecordOutOfOrder(dataCommentValid | startFreqValid, label);
959 valid |= sinexCodeValid;
961 else if (label == dataCommentString)
963 throwRecordOutOfOrder(startFreqValid, label);
965 commentList.push_back(str);
966 valid |= dataCommentValid;
968 else if (label == startFreqString)
971 throwRecordOutOfOrder(startFreqRMSValid | neuFreqRMSValid |
972 endOfFreqRMSValid | endOfAntennaValid,
974 freq = line.substr(3, 3);
975 valid |= startFreqValid;
977 else if (label == neuFreqString && !foundRMS)
980 throwRecordOutOfOrder(startFreqRMSValid | neuFreqRMSValid |
981 endOfFreqRMSValid | endOfAntennaValid,
983 freqPCVmap[freq].PCOvalue[0] =
asDouble(line.substr(0, 10));
984 freqPCVmap[freq].PCOvalue[1] =
asDouble(line.substr(10, 10));
985 freqPCVmap[freq].PCOvalue[2] =
asDouble(line.substr(20, 10));
986 valid |= neuFreqValid;
988 freqPCVmap[freq].hasAzimuth = hasAzim;
990 else if (label == endOfFreqString)
992 throwRecordOutOfOrder(startFreqRMSValid | neuFreqRMSValid |
993 endOfFreqRMSValid | endOfAntennaValid,
995 if (freq != line.substr(3, 3))
997 FFStreamError fse(
"START/END OF FREQ confused: " + freq +
998 " != " + line.substr(3, 3));
1001 valid |= endOfFreqValid;
1003 else if (label == startFreqRMSString)
1007 throwRecordOutOfOrder(endOfAntennaValid, label);
1008 freq = line.substr(3, 3);
1009 valid |= startFreqRMSValid;
1011 else if (label == neuFreqRMSString && foundRMS)
1014 throwRecordOutOfOrder(endOfAntennaValid, label);
1015 freqPCVmap[freq].PCOrms[0] =
asDouble(line.substr(0, 10));
1016 freqPCVmap[freq].PCOrms[1] =
asDouble(line.substr(10, 10));
1017 freqPCVmap[freq].PCOrms[2] =
asDouble(line.substr(20, 10));
1018 valid |= neuFreqRMSValid;
1020 else if (label == endOfFreqRMSString)
1023 throwRecordOutOfOrder(endOfAntennaValid, label);
1024 if (freq != line.substr(3, 3))
1026 FFStreamError fse(
"START/END OF FREQ RMS confused: " + freq +
1027 " != " + line.substr(3, 3));
1030 valid |= endOfFreqRMSValid;
1032 else if (label == endOfAntennaString)
1034 valid |= endOfAntennaValid;
1040 string noazi = line.substr(3, 5);
1041 double azim =
asDouble(line.substr(0, 8));
1042 if (!hasAzim && noazi !=
string(
"NOAZI"))
1045 "Invalid format; zero delta azimuth without NOAZI");
1050 if (noazi ==
string(
"NOAZI"))
1055 n = line.length() / 8 - 1;
1056 if (n != 1 +
int((zenRange[1] - zenRange[0]) / zenRange[2]))
1059 "Invalid format; wrong number of zenith/offset values");
1064 for (i = 1; i <= n; i++)
1066 double value =
asDouble(line.substr(8 * i, 8));
1067 double zen = zenRange[0] + (i - 1) * zenRange[2];
1068 if (
valid & neuFreqRMSValid)
1070 freqPCVmap[freq].PCVrms[azim][zen] = value;
1072 else if (
valid & neuFreqValid)
1074 freqPCVmap[freq].PCVvalue[azim][zen] = value;
1081 catch (FFStreamError& fse)
1094 if (line.substr(0, 42) ==
string(42,
' '))
1104 if ((line.substr(0, 2) !=
string(2,
' ')) ||
1105 (line.substr(6, 4) !=
string(4,
' ')) ||
1106 (line.substr(12, 4) !=
string(4,
' ')) ||
1107 (line.substr(18, 4) !=
string(4,
' ')) ||
1108 (line.substr(24, 4) !=
string(4,
' ')) || (line[43] !=
' '))
1110 FFStreamError e(
"Invalid time format");
1123 sec =
asDouble(line.substr(30, 13));
1130 catch (std::exception& e)
1132 FFStreamError
err(
"std::exception: " +
string(e.what()));
1140 FFStreamError
err(
"Exception in parseTime(): " + text);
1149 return string(43,
' ');
1156 line = string(2,
' ');
1158 line += string(4,
' ');
1160 line += string(4,
' ');
1162 line += string(4,
' ');
1164 line += string(4,
' ');