File: parameterVector2GnssAntennaDefinition.cpp

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (187 lines) | stat: -rw-r--r-- 8,690 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/***********************************************/
/**
* @file parameterVector2GnssAntennaDefinition.cpp
*
* @brief Update antenna definition from parametrization.
*
* @author Torsten Mayer-Guerr
* @date 2012-12-05
*/
/***********************************************/

// Latex documentation
#define DOCSTRING docstring
static const char *docstring = R"(
Updates an \file{GnssAntennaDefinition file}{gnssAntennaDefinition} with estimated parameters which belongs
to the parametrization \configClass{antennaCenterVariations}{parametrizationGnssAntennaType}.
The \configFile{outfileAntennaDefinition}{gnssAntennaDefinition} contains all antennas
from \configFile{inputfileAntennaDefinition}{gnssAntennaDefinition}.
The antenna center variations representend by the \configFile{inputfileSolution}{matrix} are added
to the matching antennas.

The \file{GnssAntennaDefinition file}{gnssAntennaDefinition} can be modified to the demands before with
\program{GnssAntennaDefinitionCreate}.

The following steps are used to estimate antenna center variations:
\begin{itemize}
\item \program{GnssAntennaDefinitionCreate} or \program{GnssAntex2AntennaDefinition}
\item \program{GnssProcessing} with \config{inputfileAntennaDefinition} as apriori
      and writing \file{normal equations}{normalEquation} with
      parametrization of \configClass{antennaCenterVariations}{parametrizationGnssAntennaType}
\item \program{NormalsEliminate}: eliminate all other than antenna parameters
\item \program{NormalsAccumulate}: accumulate normals over a sufficient long period
\item \program{GnssAntennaNormalsConstraint}: constrain unsolvable parameter linear combinations
\item \program{NormalsSolverVCE}: estimate the parameter vector
\item \program{ParameterVector2GnssAntennaDefinition}: update \config{inputfileAntennaDefinition}
\end{itemize}

See also \program{ParameterVector2GnssAntennaDefinition}, \program{GnssAntennaNormalsConstraint}.
)";

/***********************************************/

#include "programs/program.h"
#include "base/string.h"
#include "files/fileMatrix.h"
#include "files/fileGnssAntennaDefinition.h"
#include "files/fileParameterName.h"
#include "classes/parametrizationGnssAntenna/parametrizationGnssAntenna.h"

/***** CLASS ***********************************/

/** @brief Update antenna definition from parametrization.
* @ingroup programsGroup */
class ParameterVector2GnssAntennaDefinition
{
public:

  void run(Config &config, Parallel::CommunicatorPtr comm);
};

GROOPS_REGISTER_PROGRAM(ParameterVector2GnssAntennaDefinition, SINGLEPROCESS, "Update antenna definition from parametrization", Gnss)
GROOPS_RENAMED_PROGRAM(GnssRepresentation2AntennaDefinition, ParameterVector2GnssAntennaDefinition, date2time(2020, 6, 26))

/***********************************************/

void ParameterVector2GnssAntennaDefinition::run(Config &config, Parallel::CommunicatorPtr /*comm*/)
{
  try
  {
    FileName fileNameAntennaOut;
    FileName fileNameAntennaIn, fileNameSolution, fileNameParameterNames;
    ParametrizationGnssAntennaPtr parametrization;

    readConfig(config, "outfileAntennaDefinition",   fileNameAntennaOut,     Config::MUSTSET, "", "all apriori antennas");
    readConfig(config, "inputfileAntennaDefinition", fileNameAntennaIn,      Config::MUSTSET, "", "apriori antennas");
    readConfig(config, "antennaCenterVariations",    parametrization,        Config::MUSTSET, "", "");
    readConfig(config, "inputfileSolution",          fileNameSolution,       Config::MUSTSET, "", "");
    readConfig(config, "inputfileParameterNames",    fileNameParameterNames, Config::MUSTSET, "", "");
    if(isCreateSchema(config)) return;

    // ============================

    logStatus<<"read antenna definitions <"<<fileNameAntennaIn<<">"<<Log::endl;
    std::vector<GnssAntennaDefinitionPtr> antennas;
    readFileGnssAntennaDefinition(fileNameAntennaIn, antennas);

    logStatus<<"read solution vector <"<<fileNameSolution<<">"<<Log::endl;
    Vector solution;
    readFileMatrix(fileNameSolution, solution);

    logStatus<<"read parameter names <"<<fileNameParameterNames<<">"<<Log::endl;
    std::vector<ParameterName> parameterNames;
    readFileParameterName(fileNameParameterNames, parameterNames);

    std::vector<ParameterName> parametrizationNames;
    parametrization->parameterName(parametrizationNames);

    // ============================

    // sort parameters into antenna, gnssType
    // --------------------------------------
    std::map<std::string, std::map<std::string, Vector>> solutions; // antenna, gnsType, solution
    for(UInt i=0; i<parameterNames.size(); i++)
    {
      UInt idx = std::distance(parametrizationNames.begin(),
                               std::find_if(parametrizationNames.begin(), parametrizationNames.end(), [&](const auto &name)
                               {
                                 auto pos = parameterNames.at(i).type.rfind('.');
                                 return parameterNames.at(i).type.substr(0, pos) == name.type;
                               }));
      if(idx >= parametrization->parameterCount())
        continue;

      // extract GnssType
      auto pos = parameterNames.at(i).type.rfind('.');
      if((pos == std::string::npos) || (pos+1 == parameterNames.at(i).type.size()))
        throw(Exception(parameterNames.at(i).str() + ": GnssType not found in parameter name"));
      std::string typeName = parameterNames.at(i).type.substr(pos+1);

      if(!solutions[parameterNames.at(i).object][typeName].size())
        solutions[parameterNames.at(i).object][typeName] = Vector(parametrization->parameterCount());
      solutions[parameterNames.at(i).object][typeName](idx) = solution(i);
    }

    // add parametrization to all machting patterns
    // -------------------------------------------
    for(auto &solutionsAntenna : solutions)
    {
      // check antenna name
      // ------------------
      std::vector<std::string> parts = String::split(solutionsAntenna.first, GnssAntennaDefinition::sep);
      auto antenna = GnssAntennaDefinition::find(antennas, parts.at(0), parts.at(1), parts.at(2));
      if(!antenna)
        throw(Exception("antenna not found in list: "+solutionsAntenna.first));

      for(auto &solutionsAntennaType : solutionsAntenna.second)
      {
        GnssType type(solutionsAntennaType.first);
        Bool found = FALSE;
        for(auto &pattern : antenna->patterns)
          if(type == pattern.type)
          {
            logInfo<<antenna->str()<<": add parametrization of "<<type.str()<<" to "<<pattern.type.str()<<Log::endl;
            found = TRUE;

            Vector x = solutionsAntennaType.second;
            for(UInt k=0; k<x.rows(); k++)
            {
              if(String::startsWith(parametrizationNames.at(k).type, "antennaCenter.x")) {pattern.offset.x() += x(k); x(k) = 0;}
              if(String::startsWith(parametrizationNames.at(k).type, "antennaCenter.y")) {pattern.offset.y() += x(k); x(k) = 0;}
              if(String::startsWith(parametrizationNames.at(k).type, "antennaCenter.z")) {pattern.offset.z() += x(k); x(k) = 0;}
            }
            if(!isStrictlyZero(x))
              for(UInt i=0; i<pattern.pattern.rows(); i++)
                for(UInt k=0; k<pattern.pattern.columns(); k++)
                  pattern.pattern(i,k) += inner(parametrization->designMatrix(Angle(2*PI*i/pattern.pattern.rows()), Angle(PI/2-k*Double(pattern.dZenit))).trans(), x);

            // type cannot match further patterns (all wildcards in type are already catched)?
            if((!type.hasWildcard(GnssType::PRN)       || pattern.type.hasWildcard(GnssType::PRN)      ) &&
               (!type.hasWildcard(GnssType::SYSTEM)    || pattern.type.hasWildcard(GnssType::SYSTEM)   ) &&
               (!type.hasWildcard(GnssType::FREQUENCY) || pattern.type.hasWildcard(GnssType::FREQUENCY)) &&
               (!type.hasWildcard(GnssType::TYPE)      || pattern.type.hasWildcard(GnssType::TYPE)     ) &&
               (!type.hasWildcard(GnssType::ATTRIBUTE) || pattern.type.hasWildcard(GnssType::ATTRIBUTE)) &&
               (!type.hasWildcard(GnssType::FREQ_NO)   || pattern.type.hasWildcard(GnssType::FREQ_NO)  ))
              break;
          }

        if(!found)
          logWarning<<antenna->str()<<" has no pattern for "<<type.str()<<Log::endl;
      }
    }

    // ============================

    if(!fileNameAntennaOut.empty())
    {
      logStatus<<"write antenna definition <"<<fileNameAntennaOut<<">"<<Log::endl;
      writeFileGnssAntennaDefinition(fileNameAntennaOut, antennas);
    }
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/