diff --git a/docs/documentation.pdf b/docs/documentation.pdf index 82dd76fb..f6a69455 100644 Binary files a/docs/documentation.pdf and b/docs/documentation.pdf differ diff --git a/docs/html/GnssReceiver2RinexObservation.html b/docs/html/GnssReceiver2RinexObservation.html new file mode 100644 index 00000000..194d81de --- /dev/null +++ b/docs/html/GnssReceiver2RinexObservation.html @@ -0,0 +1,96 @@ + + + + + GROOPS - GnssReceiver2RinexObservation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+

GnssReceiver2RinexObservation

+ +Converts a inputfileGnssReceiver into a +RINEX observation file. +The inputfileStationInfo contains the antenna +and receiver information for the RINEX header. +The useType and ignoreType can be used to filter +the observation types that will be exported. +

+ + + + + + + + + + +
NameTypeAnnotation
outputfileRinexObservation
filenameRINEX observation file
inputfileGnssReceiver
filenameGNSS instrument file
inputfileStationInfo
filenameantenna and receiver info
comment
stringwrite comments at begin of header
observer
stringheader information
angency
stringheader information
useType
gnssTypeonly use observations that match any of these patterns
ignoreType
gnssTypeignore observations that match any of these patterns
+ +
+
+ + diff --git a/docs/html/documentationSearchIndex.js b/docs/html/documentationSearchIndex.js index d2bcf77e..34196ad0 100644 --- a/docs/html/documentationSearchIndex.js +++ b/docs/html/documentationSearchIndex.js @@ -237,6 +237,7 @@ var documents = { 'GnssIonex2GriddedDataTimeSeries': { 'name': 'GnssIonex2GriddedDataTimeSeries', 'key': 'GnssIonex2GriddedDataTimeSeries', 'description': 'Converts TEC maps from IGS to GROOPS gridded data time series format. Currently only supports 2D TEC maps. See also GnssGriddedDataTimeSeries2Ionex , Converts TEC maps from IGS .', 'config_table': 'outputfileGriddedDataTimeSeries filename inputfileIonex filename', 'display_text': 'Converts TEC maps from IGS IONEX file format to GROOPS gridded data time series format.

Currently only supports 2D TEC maps.

See also GnssGriddedDataTimeSeries2Ionex, IonosphereMap.'}, 'GnssNormals2Sinex': { 'name': 'GnssNormals2Sinex', 'key': 'GnssNormals2Sinex', 'description': 'Write GNSS data/metadata and normal equations to . Normal equations usually come from GnssProcessing (e.g. from GNSS satellite orbit determination and station network analysis ). Metadata input files include Write GNSS data/metadata and , Write GNSS data/metadata and , and Write GNSS data/metadata and , see GnssAntex2AntennaDefinition . See also Sinex2Normals and NormalsSphericalHarmonics2Sinex .', 'config_table': 'outputfileSinexNormals filename full SINEX file including normal equations outputfileSinexCoordinates filename SINEX file without normal equations (station coordinates file) inputfileNormals filename normal equation matrix inputfileSolution filename parameter vector inputfileSigmax filename standard deviations of the parameters (sqrt of the diagonal of the inverse normal equation) inputfileApriori filename apriori parameter vector inputfileAprioriSigma filename constraint sigmas for apriori parameter vector inputfileAprioriMatrix filename normal equation matrix of applied constraints transmitterConstellation sequence transmitter constellation metadata inputfileTransmitterList filename transmitter PRNs used in solution inputfileTransmitterInfo filename transmitter info file template inputfileAntennaDefinition filename transmitter phase centers and variations (ANTEX) variablePrn string loop variable for PRNs from transmitter list stations sequence inputfileStationList filename stations contained in normal equations inputfileStationInfo filename station info file template inputfileAntennaDefinition filename station phase centers and variations (ANTEX) variableStationName string loop variable for station names from station list observationTimeStart time start time for which solution has observations observationTimeEnd time end time for which solution has observations time time reference time for parameters sampling double [seconds] observation sampling antennaCalibrationModel string e.g. IGS14_WWWW (WWWW = ANTEX release GPS week) sinexHeader sequence agencyCode string identify the agency providing the data timeStart time start time of the data timeEnd time end time of the data observationCode string technique used to generate the SINEX solution constraintCode string 0: tight constraint, 1: siginficant constraint, 2: unconstrained solutionContent string solution types contained in the SINEX solution (S O E T C A) description string organizitions gathering/alerting the file contents contact string Address of the relevant contact. e-mail output string Description of the file contents input string Brief description of the input used to generate this solution software string Software used to generate the file hardware string Computer hardware on which above software was run inputfileComment filename comments in the comment block from a file (truncated at 80 characters) comment string comments in the comment block', 'display_text': 'Write GNSS data/metadata and normal equations to SINEX format.

Normal equations usually come from GnssProcessing (e.g. from GNSS satellite orbit determination and station network analysis). Metadata input files include stationInfo/transmitterInfo, antennaDefinition, and stationList/transmitterList, see GnssAntex2AntennaDefinition.

See also Sinex2Normals and NormalsSphericalHarmonics2Sinex.'}, 'GnssOrbex2StarCamera': { 'name': 'GnssOrbex2StarCamera', 'key': 'GnssOrbex2StarCamera', 'description': 'Converts GNSS satellite attitude from (quaternions) to instrument file (STARCAMERA) . The resulting star camera files contain the rotation from satellite body frame to TRF, or to CRF in case Converts GNSS satellite attitude from is provided. See also GnssAttitude2Orbex .', 'config_table': 'outputfileStarCamera filename rotation from body frame to TRF/CRF, identifier is appended to each file inputfileOrbex filename identifier string (empty = all) satellite identifier, e.g. G23 or E05 earthRotation earthRotationType rotation from TRF to CRF', 'display_text': 'Converts GNSS satellite attitude from ORBEX file format (quaternions) to instrument file (STARCAMERA). The resulting star camera files contain the rotation from satellite body frame to TRF, or to CRF in case earthRotation is provided.

See also GnssAttitude2Orbex.'}, +'GnssReceiver2RinexObservation': { 'name': 'GnssReceiver2RinexObservation', 'key': 'GnssReceiver2RinexObservation', 'description': 'Converts a Converts a into a observation file. The Converts a contains the antenna and receiver information for the RINEX header. The Converts a and Converts a can be used to filter the observation types that will be exported.', 'config_table': 'outputfileRinexObservation filename RINEX observation file inputfileGnssReceiver filename GNSS instrument file inputfileStationInfo filename antenna and receiver info comment string write comments at begin of header observer string header information angency string header information useType gnssType only use observations that match any of these patterns ignoreType gnssType ignore observations that match any of these patterns', 'display_text': 'Converts a inputfileGnssReceiver into a RINEX observation file. The inputfileStationInfo contains the antenna and receiver information for the RINEX header. The useType and ignoreType can be used to filter the observation types that will be exported.'}, 'GnssRinexNavigation2OrbitClock': { 'name': 'GnssRinexNavigation2OrbitClock', 'key': 'GnssRinexNavigation2OrbitClock', 'description': 'Evaluates orbit and clock parameters from (version 2, 3, and 4) navigation file inputfileRinex at epochs given by Evaluates orbit and clock parameters from and writes them to Evaluates orbit and clock parameters from and Evaluates orbit and clock parameters from , respectively. Orbits are rotated from TRF (as broadcasted) to CRF via Evaluates orbit and clock parameters from , but system-specific TRFs (WGS84, PZ-90, etc.) are not aligned to a common TRF. If messageType is set (e.g., to LNAV, CNAV, or other types defined in the RINEX 4 standard), only navigation records of this type are used. Otherwise, if multiple records are defined for the same epoch, the first one is used. See also OrbitAddVelocityAndAcceleration .', 'config_table': 'outputfileOrbit filename PRN is appended to file name outputfileClock filename PRN is appended to file name inputfileRinex filename RINEX navigation file timeSeries timeSeriesType orbit and clock evaluation epochs earthRotation earthRotationType for rotation from TRF to CRF usePrn string only export these PRNs instead of all messageType string (RINEX4) only use this navigation message (LNAV, CNAV, ...)', 'display_text': 'Evaluates orbit and clock parameters from RINEX (version 2, 3, and 4) navigation file inputfileRinex at epochs given by timeSeries and writes them to outputfileOrbit and outputfileClock, respectively.

Orbits are rotated from TRF (as broadcasted) to CRF via earthRotation, but system-specific TRFs (WGS84, PZ-90, etc.) are not aligned to a common TRF.

If messageType is set (e.g., to LNAV, CNAV, or other types defined in the RINEX 4 standard), only navigation records of this type are used. Otherwise, if multiple records are defined for the same epoch, the first one is used.

See also OrbitAddVelocityAndAcceleration.'}, 'GnssSignalBias2SinexBias': { 'name': 'GnssSignalBias2SinexBias', 'key': 'GnssSignalBias2SinexBias', 'description': 'Convert GNSS signal biases from GROOPS format to . Biases can be provided via transmitterBiases and/or receiverBiases . Phase biases without attribute (e.g. L1* ) are automatically expanded so each code bias has a corresponding phase bias (Example: C1C , C1W , L1* are converted to C1C , C1W , L1C , L1W ). Time-variable biases (e.g. GPS L5 satellite phase bias) can be provided via timeVariableBias . Their time span will be based on the provided epochs ( ). The slope of the bias can be optionally provided in the second data column. If GLONASS receiver biases depend on frequency number, those must be defined in Convert to get the correct PRN/SVN assignment to the biases. See IGS SINEX Bias format description for further details on header information. See also GnssSinexBias2SignalBias and GnssBiasClockAlignment .', 'config_table': 'outputfileSinexBias filename inputfileTransmitterInfo filename one file per satellite transmitterBiases sequence one element per satellite inputfileSignalBias filename signal bias file timeVariableBias sequence one entry per time variable bias type inputfileSignalBias filename columns: mjd, bias [m], (biasSlope [m/s]) type gnssType bias type identifier string PRN or station name (e.g. G23 or wtzz) receiverBiases sequence one element per station inputfileSignalBias filename signal bias file timeVariableBias sequence one entry per time variable bias type inputfileSignalBias filename columns: mjd, bias [m], (biasSlope [m/s]) type gnssType bias type identifier string PRN or station name (e.g. G23 or wtzz) agencyCode string identify the agency providing the data fileAgencyCode string identify the agency creating the file timeStart time start time of the data timeEnd time end time of the data biasMode choice absolute or relative bias estimates absolute relative observationSampling uint [seconds] intervalLength uint [seconds] interval for bias parameter representation determinationMethod string determination method used to generate the bias results (see SINEX Bias format description) receiverClockReferenceGnss string (G, R, E, C) reference GNSS used for receiver clock estimation satelliteClockReferenceObservables string one per system, reference code observable on first and second frequency (RINEX3 format) description string organizition gathering/altering the file contents contact string contact name and/or email address input string brief description of the input used to generate this solution output string description of the file contents software string software used to generate the file hardware string computer hardware on which above software was run comment string comments in the comment block', 'display_text': 'Convert GNSS signal biases from GROOPS format to IGS SINEX Bias format. Biases can be provided via transmitterBiases and/or receiverBiases. Phase biases without attribute (e.g. L1*) are automatically expanded so each code bias has a corresponding phase bias (Example: C1C, C1W, L1* are converted to C1C, C1W, L1C, L1W).

Time-variable biases (e.g. GPS L5 satellite phase bias) can be provided via timeVariableBias. Their time span will be based on the provided epochs ($t \\pm \\Delta t / 2$). The slope of the bias can be optionally provided in the second data column.

If GLONASS receiver biases depend on frequency number, those must be defined in inputfileTransmitterInfo to get the correct PRN/SVN assignment to the biases.

See IGS SINEX Bias format description for further details on header information.

See also GnssSinexBias2SignalBias and GnssBiasClockAlignment.'}, 'GnssSinexBias2SignalBias': { 'name': 'GnssSinexBias2SignalBias', 'key': 'GnssSinexBias2SignalBias', 'description': 'Converts GNSS signal biases from to GnssSignalBias format . Only satellite observable-specific signal biases (OSB) are supported at the moment. If multiple entries exist for the same bias, the weighted average (based on time span) of all entries is used. Time-variable biases are not supported at the moment. See also GnssSignalBias2SinexBias .', 'config_table': 'outputfileSignalBias filename identifier is appended to file name inputfileSinexBias filename inputfileGlonassSignalDefinition filename GLONASS frequency number mapping identifier string (empty = all) satellite PRN, e.g. G23 or E05', 'display_text': 'Converts GNSS signal biases from IGS SINEX Bias format to GnssSignalBias format.

Only satellite observable-specific signal biases (OSB) are supported at the moment. If multiple entries exist for the same bias, the weighted average (based on time span) of all entries is used. Time-variable biases are not supported at the moment.

See also GnssSignalBias2SinexBias.'}, diff --git a/docs/html/programType.html b/docs/html/programType.html index 4da57f80..9f2a28d0 100644 --- a/docs/html/programType.html +++ b/docs/html/programType.html @@ -341,6 +341,7 @@

Conversion

  • GnssIonex2GriddedDataTimeSeries
  • GnssNormals2Sinex
  • GnssOrbex2StarCamera
  • +
  • GnssReceiver2RinexObservation
  • GnssRinexNavigation2OrbitClock
  • GnssSignalBias2SinexBias
  • GnssSinexBias2SignalBias
  • diff --git a/docs/latex/programs.auto.tex b/docs/latex/programs.auto.tex index 7339d419..5aa8efcc 100644 --- a/docs/latex/programs.auto.tex +++ b/docs/latex/programs.auto.tex @@ -7596,6 +7596,33 @@ \subsection{GnssOrbex2StarCamera}\label{GnssOrbex2StarCamera} \hline \end{tabularx} +\clearpage +%================================== +\subsection{GnssReceiver2RinexObservation}\label{GnssReceiver2RinexObservation} +Converts a \configFile{inputfileGnssReceiver}{instrument} into a +\href{https://files.igs.org/pub/data/format/rinex_4.00.pdf}{RINEX} observation file. +The \configFile{inputfileStationInfo}{platform} contains the antenna +and receiver information for the RINEX header. +The \configClass{useType}{gnssType} and \configClass{ignoreType}{gnssType} can be used to filter +the observation types that will be exported. + + +\keepXColumns +\begin{tabularx}{\textwidth}{N T A} +\hline +Name & Type & Annotation\\ +\hline +\hfuzz=500pt\includegraphics[width=1em]{element-mustset.pdf}~outputfileRinexObservation & \hfuzz=500pt filename & \hfuzz=500pt RINEX observation file\\ +\hfuzz=500pt\includegraphics[width=1em]{element-mustset.pdf}~inputfileGnssReceiver & \hfuzz=500pt filename & \hfuzz=500pt GNSS instrument file\\ +\hfuzz=500pt\includegraphics[width=1em]{element-mustset.pdf}~inputfileStationInfo & \hfuzz=500pt filename & \hfuzz=500pt antenna and receiver info\\ +\hfuzz=500pt\includegraphics[width=1em]{element-unbounded.pdf}~comment & \hfuzz=500pt string & \hfuzz=500pt write comments at begin of header\\ +\hfuzz=500pt\includegraphics[width=1em]{element.pdf}~observer & \hfuzz=500pt string & \hfuzz=500pt header information\\ +\hfuzz=500pt\includegraphics[width=1em]{element.pdf}~angency & \hfuzz=500pt string & \hfuzz=500pt header information\\ +\hfuzz=500pt\includegraphics[width=1em]{element-unbounded.pdf}~useType & \hfuzz=500pt \hyperref[gnssType]{gnssType} & \hfuzz=500pt only use observations that match any of these patterns\\ +\hfuzz=500pt\includegraphics[width=1em]{element-unbounded.pdf}~ignoreType & \hfuzz=500pt \hyperref[gnssType]{gnssType} & \hfuzz=500pt ignore observations that match any of these patterns\\ +\hline +\end{tabularx} + \clearpage %================================== \subsection{GnssRinexNavigation2OrbitClock}\label{GnssRinexNavigation2OrbitClock} diff --git a/groops.xsd b/groops.xsd index 92bb13e3..e6d59680 100644 --- a/groops.xsd +++ b/groops.xsd @@ -20508,6 +20508,58 @@ + + + Converts GnssReceiver Instrument file to RINEX. + tag: Conversion + tag: Gnss + tag: Instrument + + + + + + RINEX observation file + + + + + GNSS instrument file + + + + + antenna and receiver info + + + + + write comments at begin of header + + + + + header information + + + + + header information + + + + + only use observations that match any of these patterns + + + + + ignore observations that match any of these patterns + + + + + Convert RINEX navigation file (e.g. broadcast ephemeris) to orbit and clock files. diff --git a/source/programs/conversion/gnss/gnssReceiver2RinexObservation.cpp b/source/programs/conversion/gnss/gnssReceiver2RinexObservation.cpp new file mode 100644 index 00000000..69375fa4 --- /dev/null +++ b/source/programs/conversion/gnss/gnssReceiver2RinexObservation.cpp @@ -0,0 +1,243 @@ +/***********************************************/ +/** +* @file gnssReceiver2RinexObservation.cpp +* +* @brief Converts GnssReceiver Instrument file to RINEX. +* +* @author Torsten Mayer-Guerr +* @date 2023-03-05 +*/ +/***********************************************/ + +// Latex documentation +#define DOCSTRING docstring +static const char *docstring = R"( +Converts a \configFile{inputfileGnssReceiver}{instrument} into a +\href{https://files.igs.org/pub/data/format/rinex_4.00.pdf}{RINEX} observation file. +The \configFile{inputfileStationInfo}{platform} contains the antenna +and receiver information for the RINEX header. +The \configClass{useType}{gnssType} and \configClass{ignoreType}{gnssType} can be used to filter +the observation types that will be exported. +)"; + +/***********************************************/ + +#include "programs/program.h" +#include "base/string.h" +#include "inputOutput/file.h" +#include "inputOutput/system.h" +#include "files/filePlatform.h" +#include "files/fileInstrument.h" + +/***** CLASS ***********************************/ + +/** @brief Converts GnssReceiver Instrument file to RINEX. +* @ingroup programsConversionGroup */ +class GnssReceiver2RinexObservation +{ +public: + void run(Config &config, Parallel::CommunicatorPtr comm); +}; + +GROOPS_REGISTER_PROGRAM(GnssReceiver2RinexObservation, SINGLEPROCESS, "Converts GnssReceiver Instrument file to RINEX.", Conversion, Gnss, Instrument) + +/***********************************************/ + +void GnssReceiver2RinexObservation::run(Config &config, Parallel::CommunicatorPtr /*comm*/) +{ + try + { + FileName fileNameOut, fileNameObs, fileNamePlatform; + std::string observer, angency; + std::vector comments; + std::vector useType, ignoreType; + + readConfig(config, "outputfileRinexObservation", fileNameOut, Config::MUSTSET, "", "RINEX observation file"); + readConfig(config, "inputfileGnssReceiver", fileNameObs, Config::MUSTSET, "", "GNSS instrument file"); + readConfig(config, "inputfileStationInfo", fileNamePlatform, Config::MUSTSET, "", "antenna and receiver info"); + readConfig(config, "comment", comments, Config::OPTIONAL, "", "write comments at begin of header"); + readConfig(config, "observer", observer, Config::OPTIONAL, "TUG", "header information"); + readConfig(config, "angency", angency, Config::OPTIONAL, "TUG", "header information"); + readConfig(config, "useType", useType, Config::OPTIONAL, "", "only use observations that match any of these patterns"); + readConfig(config, "ignoreType", ignoreType, Config::OPTIONAL, "", "ignore observations that match any of these patterns"); + if(isCreateSchema(config)) return; + + logStatus<<"read instrument file <"<"<> types; // types per system + std::set glonass; // GLONASS frequencyNumbers + for(auto &epoch : arc) + for(GnssType satType : epoch.satellite) + for(UInt idType = GnssType::index(epoch.obsType, satType); (idType < epoch.obsType.size()) && (epoch.obsType.at(idType) == satType); idType++) + if((!useType.size() || (epoch.obsType.at(idType)+satType).isInList(useType)) && !(epoch.obsType.at(idType)+satType).isInList(ignoreType)) + { + types[satType & GnssType::SYSTEM].insert(epoch.obsType.at(idType)); + if(satType == GnssType::GLONASS) + glonass.insert(satType); + } + + logStatus<<"read platform file <"<"<(timeStart); + if(!antenna) + throw(Exception(platform.markerName+"."+platform.markerNumber+": no antenna definition found at "+timeStart.dateTimeStr())); + auto receiver = platform.findEquipment(timeStart); + + auto fixedSize = [](const std::string &str, UInt size) + { + return (str+std::string(size, ' ')).substr(0, size); + }; + + // header + // ------ + logStatus<<"write RINEX file <"<"<serial, 20)<name, 20)<version, 20)<<"REC # / TYPE / VERS "<serial, 20)<name, 16)<radome, 4)<<" ANT # / TYPE "<position.z()%"%14.4f"s<position.y()%"%14.4f"s<position.x()%"%14.4f ANTENNA: DELTA H/E/N"s<position.x()%"%14.4f"s<position.y()%"%14.4f"s<position.z()%"%14.4f ANTENNA: DELTA X/Y/Z"s<local2antennaFrame.inverseTransform(Vector3d(0,0,1)); + const Vector3d zerodir = antenna->local2antennaFrame.inverseTransform(Vector3d(1,0,0)); + file<= 1e-4) + file< 13) // continuation line? + { + count = 1; + file<<" SYS / # / OBS TYPES "< 8) // continuation line? + { + count = 1; + file<<"GLONASS SLOT / FRQ #"<(epoch.time)) + { + antenna = platform.findEquipment(epoch.time); + if(!antenna) + throw(Exception(platform.markerName+"."+platform.markerNumber+": no antenna definition found at "+epoch.time.dateTimeStr())); + file<<"> "<timeStart%"%y %m %d %H %M%11.7S 4 5"s<serial, 20)<name, 16)<radome, 4)<<" ANT # / TYPE "<position.z()%"%14.4f"s<position.y()%"%14.4f"s<position.x()%"%14.4f ANTENNA: DELTA H/E/N"s<position.x()%"%14.4f"s<position.y()%"%14.4f"s<position.z()%"%14.4f ANTENNA: DELTA X/Y/Z"s<local2antennaFrame.inverseTransform(Vector3d(0,0,1)); + const Vector3d zerodir = antenna->local2antennaFrame.inverseTransform(Vector3d(1,0,0)); + file<(epoch.time)) + { + receiver = platform.findEquipment(epoch.time); + if(receiver) + { + file<<"> "<timeStart%"%y %m %d %H %M%11.7S 4 1"s<serial, 20)<name, 20)<version, 20)<<"REC # / TYPE / VERS "<= 1e-4) + { + com = platform.referencePoint(epoch.time); + file<<"> "< "< down - antennaRinex.position.x() = readOptionalDouble(line,14,14); - antennaRinex.position.y() = readOptionalDouble(line,28,14); + antennaRinex.position.z() = readOptionalDouble(line, 0,14); + antennaRinex.position.y() = readOptionalDouble(line,14,14); + antennaRinex.position.x() = readOptionalDouble(line,28,14); } // ==================================== else if(testLabel(label, "ANTENNA: DELTA X/Y/Z")) @@ -316,6 +316,14 @@ void RinexObservation2GnssReceiver::readHeader(InFile &file, UInt lineCount) { } // ==================================== + else if(testLabel(label, "ANTENNA: ZERODIR AZI ")) + { + } + // ==================================== + else if(testLabel(label, "ANTENNA: ZERODIR XYZ")) + { + } + // ==================================== else if(testLabel(label, "CENTER OF MASS: XYZ")) { } diff --git a/source/sourcesCXX.txt b/source/sourcesCXX.txt index 6719f241..cfaa0df9 100644 --- a/source/sourcesCXX.txt +++ b/source/sourcesCXX.txt @@ -464,6 +464,7 @@ programs/conversion/gnss/gnssGriddedDataTimeSeries2Ionex.cpp programs/conversion/gnss/gnssIonex2GriddedDataTimeSeries.cpp programs/conversion/gnss/gnssNormals2Sinex.cpp programs/conversion/gnss/gnssOrbex2StarCamera.cpp +programs/conversion/gnss/gnssReceiver2RinexObservation.cpp programs/conversion/gnss/gnssRinexNavigation2OrbitClock.cpp programs/conversion/gnss/gnssSignalBias2SinexBias.cpp programs/conversion/gnss/gnssSinexBias2SignalBias.cpp