Isis 3 Programmer Reference
ControlNetDiff.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "ControlNetDiff.h"
10
11#include <QMap>
12#include <QSet>
13#include <QString>
14
15#include "ControlMeasure.h"
16#include "ControlNet.h"
17#include "ControlNetVersioner.h"
18#include "ControlPoint.h"
19#include "FileName.h"
20#include "Pvl.h"
21#include "PvlContainer.h"
22#include "PvlGroup.h"
23#include "PvlKeyword.h"
24#include "PvlObject.h"
25
26namespace Isis {
27
34
35
42 init();
43 addTolerances(diffFile);
44 }
45
46
51 delete m_tolerances;
52 m_tolerances = NULL;
53
54 delete m_ignoreKeys;
55 m_ignoreKeys = NULL;
56 }
57
58
67 if (diffFile.hasGroup("Tolerances")) {
68 PvlGroup tolerances = diffFile.findGroup("Tolerances");
69 for (int i = 0; i < tolerances.keywords(); i++)
70 m_tolerances->insert(tolerances[i].name(),
71 toDouble(tolerances[i][0]));
72 }
73
74 if (diffFile.hasGroup("IgnoreKeys")) {
75 PvlGroup ignoreKeys = diffFile.findGroup("IgnoreKeys");
76 for (int i = 0; i < ignoreKeys.keywords(); i++)
77 m_ignoreKeys->insert(ignoreKeys[i].name());
78 }
79 }
80
81
91 Pvl results;
92 PvlObject report("Differences");
93
94 diff("Filename", net1Name.name(), net2Name.name(), report);
95
96 ControlNetVersioner cnv1(net1Name);
97 ControlNetVersioner cnv2(net2Name);
98
99 BigInt net1NumPts = cnv1.numPoints();
100 BigInt net2NumPts = cnv2.numPoints();
101 diff("Points", toString(net1NumPts), toString(net2NumPts), report);
102
103 diff("NetworkId", cnv1.netId(), cnv2.netId(), report);
104 diff("TargetName", cnv1.targetName(), cnv2.targetName(), report);
105
106 Pvl net1Pvl = cnv1.toPvl();
107 Pvl net2Pvl = cnv2.toPvl();
108
109 PvlObject &net1Obj = net1Pvl.findObject("ControlNetwork");
110 PvlObject &net2Obj = net2Pvl.findObject("ControlNetwork");
111
112 QMap< QString, QMap<int, PvlObject> > pointMap;
113
114 for (int p = 0; p < net1NumPts; p++) {
115 PvlObject &point = net1Obj.object(p);
116 pointMap[point.findKeyword("PointId")[0]].insert(
117 0, point);
118 }
119
120 for (int p = 0; p < net2NumPts; p++) {
121 PvlObject &point = net2Obj.object(p);
122 pointMap[point.findKeyword("PointId")[0]].insert(
123 1, point);
124 }
125
126 QList<QString> pointNames = pointMap.keys();
127
128 for (int i = 0; i < pointNames.size(); i++) {
129 QMap<int, PvlObject> idMap = pointMap[pointNames[i]];
130 if (idMap.size() == 2) {
131 compare(idMap[0], idMap[1], report);
132 }
133 else if (idMap.contains(0)) {
134 addUniquePoint("PointId", idMap[0].findKeyword("PointId")[0], "N/A", report);
135 }
136 else if (idMap.contains(1)) {
137 addUniquePoint("PointId", "N/A", idMap[1].findKeyword("PointId")[0], report);
138 }
139 }
140
141 results.addObject(report);
142 return results;
143 }
144
145
155 void ControlNetDiff::compare(PvlObject &point1Pvl, PvlObject &point2Pvl, PvlObject &report) {
156 PvlObject pointReport("Point");
157
158 QString id1 = point1Pvl.findKeyword("PointId")[0];
159 QString id2 = point2Pvl.findKeyword("PointId")[0];
160 pointReport.addKeyword(makeKeyword("PointId", id1, id2));
161
162 int p1Measures = point1Pvl.groups();
163 int p2Measures = point2Pvl.groups();
164 diff("Measures", toString(p1Measures), toString(p2Measures), pointReport);
165
166 compareGroups(point1Pvl, point2Pvl, pointReport);
167
168 QMap< QString, QMap<int, PvlGroup> > measureMap;
169 for (int m = 0; m < p1Measures; m++) {
170 PvlGroup &measure = point1Pvl.group(m);
171 measureMap[measure.findKeyword("SerialNumber")[0]].insert(
172 0, measure);
173 }
174
175 for (int m = 0; m < p2Measures; m++) {
176 PvlGroup &measure = point2Pvl.group(m);
177 measureMap[measure.findKeyword("SerialNumber")[0]].insert(
178 1, measure);
179 }
180
181 QList<QString> measureNames = measureMap.keys();
182 for (int i = 0; i < measureNames.size(); i++) {
183 QMap<int, PvlGroup> idMap = measureMap[measureNames[i]];
184 if (idMap.size() == 2) {
185 compareGroups(idMap[0], idMap[1], pointReport);
186 }
187 else if (idMap.contains(0)) {
188 addUniqueMeasure("SerialNumber", idMap[0].findKeyword("SerialNumber")[0], "N/A", pointReport);
189 }
190 else if (idMap.contains(1)) {
191 addUniqueMeasure("SerialNumber", "N/A", idMap[1].findKeyword("SerialNumber")[0], pointReport);
192 }
193 }
194
195 if (pointReport.keywords() > 2 || pointReport.groups() > 0)
196 report.addObject(pointReport);
197 }
198
199
213 PvlGroup measureReport("Measure");
214 if (g1.hasKeyword("SerialNumber")) {
215 QString sn1 = g1.findKeyword("SerialNumber")[0];
216 QString sn2 = g1.findKeyword("SerialNumber")[0];
217 measureReport.addKeyword(makeKeyword("SerialNumber", sn1, sn2));
218 }
219 PvlContainer &groupReport = g1.hasKeyword("SerialNumber") ?
220 (PvlContainer &) measureReport : (PvlContainer &) report;
221
222 QMap< QString, QMap<int, PvlKeyword> > keywordMap;
223 for (int k = 0; k < g1.keywords(); k++)
224 keywordMap[g1[k].name()].insert(0, g1[k]);
225 for (int k = 0; k < g2.keywords(); k++)
226 keywordMap[g2[k].name()].insert(1, g2[k]);
227
228 QList<QString> keywordNames = keywordMap.keys();
229 for (int i = 0; i < keywordNames.size(); i++) {
230 QMap<int, PvlKeyword> idMap = keywordMap[keywordNames[i]];
231 if (idMap.size() == 2) {
232 compare(idMap[0], idMap[1], groupReport);
233 }
234 else if (idMap.contains(0)) {
235 QString name = idMap[0].name();
236 if (!m_ignoreKeys->contains(name))
237 diff(name, idMap[0][0], "N/A", groupReport);
238 }
239 else if (idMap.contains(1)) {
240 QString name = idMap[1].name();
241 if (!m_ignoreKeys->contains(name))
242 diff(name, "N/A", idMap[1][0], groupReport);
243 }
244 }
245
246 if (measureReport.keywords() > 1) report.addGroup(measureReport);
247 }
248
249
265 QString name = k1.name();
266 if (m_tolerances->contains(name))
267 diff(name, toDouble(k1[0]), toDouble(k2[0]), (*m_tolerances)[name], report);
268 else
269 diff(name, k1[0], k2[0], report);
270 }
271
272
283 void ControlNetDiff::diff(QString name, PvlObject &o1, PvlObject &o2, PvlContainer &report) {
284 QString v1 = o1[name][0];
285 QString v2 = o2[name][0];
286 diff(name, v1, v2, report);
287 }
288
289
301 void ControlNetDiff::diff(QString name, QString v1, QString v2, PvlContainer &report) {
302 if (!m_ignoreKeys->contains(name)) {
303 if (v1 != v2) report.addKeyword(makeKeyword(name, v1, v2));
304 }
305 }
306
307
317 PvlKeyword ControlNetDiff::makeKeyword(QString name, QString v1, QString v2) {
318 PvlKeyword keyword(name);
319 keyword.addValue(v1);
320 if (v1 != v2) keyword.addValue(v2);
321 return keyword;
322 }
323
324
338 void ControlNetDiff::diff(QString name, double v1, double v2, double tol, PvlContainer &report) {
339 if (!m_ignoreKeys->contains(name)) {
340 if (fabs(v1 - v2) > tol) report.addKeyword(makeKeyword(name, v1, v2, tol));
341 }
342 }
343
344
356 PvlKeyword ControlNetDiff::makeKeyword(QString name, double v1, double v2, double tol) {
357 PvlKeyword keyword(name);
358 keyword.addValue(toString(v1));
359 if (fabs(v1 - v2) > tol) {
360 keyword.addValue(toString(v2));
361 keyword.addValue(toString(tol));
362 }
363 return keyword;
364 }
365
366
376 void ControlNetDiff::addUniquePoint(QString label, QString v1, QString v2, PvlObject &parent) {
377 PvlObject point("Point");
378
379 PvlKeyword keyword(label);
380 keyword.addValue(v1);
381 keyword.addValue(v2);
382 point.addKeyword(keyword);
383
384 parent.addObject(point);
385 }
386
387
398 void ControlNetDiff::addUniqueMeasure(QString label, QString v1, QString v2, PvlObject &parent) {
399 PvlGroup measure("Measure");
400
401 PvlKeyword keyword(label);
402 keyword.addValue(v1);
403 keyword.addValue(v2);
404 measure.addKeyword(keyword);
405
406 parent.addGroup(measure);
407 }
408
409
416 m_tolerances = NULL;
417 m_ignoreKeys = NULL;
418
419 m_tolerances = new QMap<QString, double>;
420 m_ignoreKeys = new QSet<QString>;
421
422 m_ignoreKeys->insert("DateTime");
423 }
424}
void diff(QString name, PvlObject &o1, PvlObject &o2, PvlContainer &report)
Add a new difference keyword to the given report if the PvlObjects have different values for the keyw...
void addTolerances(Pvl &diffFile)
Add the given ignore keys and tolerances to the persisent collections of such values.
QMap< QString, double > * m_tolerances
The map of tolerances going from keyword name to tolerance value.
void addUniquePoint(QString label, QString v1, QString v2, PvlObject &parent)
Add a new keyword for the given point to the parent object.
ControlNetDiff()
Create a ControlNetDiff without any tolerances.
void init()
Initialize the persistent structures used to maintain the state of this instance: its ignore keys and...
void addUniqueMeasure(QString label, QString v1, QString v2, PvlObject &parent)
Add a new keyword for the given measure to the parent object.
QSet< QString > * m_ignoreKeys
The set of keywords to ignore by name.
PvlKeyword makeKeyword(QString name, QString v1, QString v2)
Create a new keyword with the given label name and the given values.
void compareGroups(PvlContainer &g1, PvlContainer &g2, PvlObject &report)
Compare two collections, or groupings, of PvlKeywords.
virtual ~ControlNetDiff()
Destroy the ControlNetDiff.
Pvl compare(FileName &net1Name, FileName &net2Name)
Compare two Control Networks given their file names, and return their differences.
Handle various control network file format versions.
File name manipulation and expansion.
Definition FileName.h:100
Contains more than one keyword-value pair.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString name() const
Returns the container name.
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
void addValue(QString value, QString unit="")
Adds a value with units.
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition PvlObject.h:276
PvlObject & object(const int index)
Return the object at the specified index.
void addObject(const PvlObject &object)
Add a PvlObject.
Definition PvlObject.h:309
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition PvlObject.h:186
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
long long int BigInt
Big int.
Definition Constants.h:49
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149