Isis 3 Programmer Reference
OverlapStatistics.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "OverlapStatistics.h"
8
9#include <cfloat>
10#include <iomanip>
11
12#include "Brick.h"
13#include "Cube.h"
14#include "FileName.h"
15#include "IException.h"
16#include "MultivariateStatistics.h"
17#include "Progress.h"
18#include "Projection.h"
19#include "ProjectionFactory.h"
20#include "PvlGroup.h"
21#include "PvlKeyword.h"
22#include "PvlObject.h"
23
24using namespace std;
25namespace Isis {
26
33 init();
34 fromPvl(inStats);
35 }
36
52 QString progressMsg, double sampPercent) {
53
54 init();
55
56 // Test to ensure sampling percent in bound
57 if (sampPercent <= 0.0 || sampPercent > 100.0) {
58 string msg = "The sampling percent must be a decimal (0.0, 100.0]";
59 throw IException(IException::Programmer, msg, _FILEINFO_);
60 }
61
62 p_sampPercent = sampPercent;
63
64 // Extract filenames and band number from cubes
65 p_xFile = x.fileName();
66 p_yFile = y.fileName();
67
68 // Make sure number of bands match
69 if (x.bandCount() != y.bandCount()) {
70 QString msg = "Number of bands do not match between cubes [" +
71 p_xFile.name() + "] and [" + p_yFile.name() + "]";
72 throw IException(IException::User, msg, _FILEINFO_);
73 }
74 p_bands = x.bandCount();
75 p_stats.resize(p_bands);
76
77 //Create projection from each cube
78 Projection *projX = x.projection();
79 Projection *projY = y.projection();
80
81 // Test to make sure projection parameters match
82 if (*projX != *projY) {
83 QString msg = "Mapping groups do not match between cubes [" +
84 p_xFile.name() + "] and [" + p_yFile.name() + "]";
85 throw IException(IException::Programmer, msg, _FILEINFO_);
86 }
87
88 // Figure out the x/y range for both images to find the overlap
89 double Xmin1 = projX->ToProjectionX(0.5);
90 double Ymax1 = projX->ToProjectionY(0.5);
91 double Xmax1 = projX->ToProjectionX(x.sampleCount() + 0.5);
92 double Ymin1 = projX->ToProjectionY(x.lineCount() + 0.5);
93
94 double Xmin2 = projY->ToProjectionX(0.5);
95 double Ymax2 = projY->ToProjectionY(0.5);
96 double Xmax2 = projY->ToProjectionX(y.sampleCount() + 0.5);
97 double Ymin2 = projY->ToProjectionY(y.lineCount() + 0.5);
98
99 // Find overlap
100 if ((Xmin1 < Xmax2) && (Xmax1 > Xmin2) && (Ymin1 < Ymax2) && (Ymax1 > Ymin2)) {
101 double minX = Xmin1 > Xmin2 ? Xmin1 : Xmin2;
102 double minY = Ymin1 > Ymin2 ? Ymin1 : Ymin2;
103 double maxX = Xmax1 < Xmax2 ? Xmax1 : Xmax2;
104 double maxY = Ymax1 < Ymax2 ? Ymax1 : Ymax2;
105
106 // Find Sample range of the overlap
107 p_minSampX = (int)(projX->ToWorldX(minX) + 0.5);
108 p_maxSampX = (int)(projX->ToWorldX(maxX) + 0.5);
109 p_minSampY = (int)(projY->ToWorldX(minX) + 0.5);
110 p_maxSampY = (int)(projY->ToWorldX(maxX) + 0.5);
112
113 // Test to see if there was only sub-pixel overlap
114 if (p_sampRange <= 0) return;
115
116 // Find Line range of overlap
117 p_minLineX = (int)(projX->ToWorldY(maxY) + 0.5);
118 p_maxLineX = (int)(projX->ToWorldY(minY) + 0.5);
119 p_minLineY = (int)(projY->ToWorldY(maxY) + 0.5);
120 p_maxLineY = (int)(projY->ToWorldY(minY) + 0.5);
122
123 // Print percent processed
124 Progress progress;
125 progress.SetText(progressMsg);
126
127 int linc = (int)(100.0 / sampPercent + 0.5); // Calculate our line increment
128
129 // Define the maximum number of steps to be our line range divided by the
130 // line increment, but if they do not divide evenly, then because of
131 // rounding, we need to do an additional step for each band
132 int maxSteps = (int)(p_lineRange / linc + 0.5);
133
134 if (p_lineRange % linc != 0) maxSteps += 1;
135 maxSteps *= p_bands;
136
137
138 progress.SetMaximumSteps(maxSteps);
139 progress.CheckStatus();
140
141 // Collect and store off the overlap statistics
142 for (int band = 1; band <= p_bands; band++) {
143 Brick b1(p_sampRange, 1, 1, x.pixelType());
144 Brick b2(p_sampRange, 1, 1, y.pixelType());
145
146 int i = 0;
147 while(i < p_lineRange) {
148 b1.SetBasePosition(p_minSampX, (i + p_minLineX), band);
149 b2.SetBasePosition(p_minSampY, (i + p_minLineY), band);
150 x.read(b1);
151 y.read(b2);
152 p_stats[band-1].AddData(b1.DoubleBuffer(), b2.DoubleBuffer(), p_sampRange);
153
154 // Make sure we consider the last line
155 if (i + linc > p_lineRange - 1 && i != p_lineRange - 1) {
156 i = p_lineRange - 1;
157 progress.AddSteps(1);
158 }
159 else i += linc; // Increment the current line by our incrementer
160
161 progress.CheckStatus();
162 }
163 }
164 }
165 }
166
167
176 for (int b = 0; b < p_bands; b++) {
177 if (p_stats[b].ValidPixels() > 0) return true;
178 }
179 return false;
180 }
181
182
193 try {
194 // Empty strings are set to default value as well
195 if (name.isEmpty()) {
196 name = "OverlapStatistics";
197 }
198
199 // Add keywords for OverlapStatistics data
200 PvlObject o(name);
201 o += PvlKeyword("File1", FileNameX().name());
202 o += PvlKeyword("File2", FileNameY().name());
203 o += PvlKeyword("Width", toString(Samples()));
204 o += PvlKeyword("Height", toString(Lines()));
205 o += PvlKeyword("Bands", toString(Bands()));
206 o += PvlKeyword("SamplingPercent", toString(SampPercent()));
207 o += PvlKeyword("MinCount", toString(MinCount())); // Do we need this if EqInfo has this?
208
209 // Create group for first file of overlap
210 PvlGroup gX("File1");
211 PvlKeyword stsX("StartSample", toString(StartSampleX()));
212 PvlKeyword ensX("EndSample", toString(EndSampleX()));
213 PvlKeyword stlX("StartLine", toString(StartLineX()));
214 PvlKeyword enlX("EndLine", toString(EndLineX()));
215 PvlKeyword avgX("Average");
216 PvlKeyword stdX("StandardDeviation");
217 PvlKeyword varX("Variance");
218 for (int band = 1; band <= Bands(); band++) {
219 if (HasOverlap(band)) {
220 avgX += toString(GetMStats(band).X().Average());
221 stdX += toString(GetMStats(band).X().StandardDeviation());
222 varX += toString(GetMStats(band).X().Variance());
223 }
224 }
225 gX += stsX;
226 gX += ensX;
227 gX += stlX;
228 gX += enlX;
229 gX += avgX;
230 gX += stdX;
231 gX += varX;
232
233 // Create group for second file of overlap
234 PvlGroup gY("File2");
235 PvlKeyword stsY("StartSample", toString(StartSampleY()));
236 PvlKeyword ensY("EndSample", toString(EndSampleY()));
237 PvlKeyword stlY("StartLine", toString(StartLineY()));
238 PvlKeyword enlY("EndLine", toString(EndLineY()));
239 PvlKeyword avgY("Average");
240 PvlKeyword stdY("StandardDeviation");
241 PvlKeyword varY("Variance");
242 for (int band = 1; band <= Bands(); band++) {
243 if (HasOverlap(band)) {
244 avgY += toString(GetMStats(band).Y().Average());
245 stdY += toString(GetMStats(band).Y().StandardDeviation());
246 varY += toString(GetMStats(band).Y().Variance());
247 }
248 }
249 gY += stsY;
250 gY += ensY;
251 gY += stlY;
252 gY += enlY;
253 gY += avgY;
254 gY += stdY;
255 gY += varY;
256
257 o.addGroup(gX);
258 o.addGroup(gY);
259
260 bool isValid = false;
261 // Unserialize the MultivariateStatistics
262 for (int band = 1; band <= Bands(); band++) {
263 PvlKeyword validBand("ValidOverlap", "false");
264
265 if (HasOverlap(band)) {
266 if (IsValid(band)) {
267 validBand.setValue("true");
268 isValid = true;
269 }
270 }
271
272 QString mStatsName = "MultivariateStatistics" + toString(band);
273 PvlObject mStats(GetMStats(band).toPvl(mStatsName));
274 mStats += validBand;
275 o.addObject(mStats);
276 }
277 PvlKeyword valid("Valid", (isValid) ? "true" : "false");
278 o += valid;
279 return o;
280 }
281
282 catch (IException &e) {
283 QString msg = "Trivial overlap between [" + FileNameX().name();
284 msg += "] and [" + FileNameY().name() + "]";
285 throw IException(IException::User, msg, _FILEINFO_);
286 }
287 }
288
289
296 init();
297
298 const PvlGroup &fileX = inStats.findGroup("File1");
299 const PvlGroup &fileY = inStats.findGroup("File2");
300 p_xFile = inStats["File1"][0];
301 p_yFile = inStats["File2"][0];
302 p_sampRange = inStats["Width"];
303 p_lineRange = inStats["Height"];
304 p_bands = inStats["Bands"];
305 p_sampPercent = inStats["SamplingPercent"];
306
307 p_minSampX = fileX["StartSample"];
308 p_maxSampX = fileX["EndSample"];
309 p_minLineX = fileX["StartLine"];
310 p_maxLineX = fileX["EndLine"];
311
312 p_minSampY = fileY["StartSample"];
313 p_maxSampY = fileY["EndSample"];
314 p_minLineY = fileY["StartLine"];
315 p_maxLineY = fileY["EndLine"];
316
317 p_mincnt = inStats["MinCount"];
318
319 // unserialize the MStats
320 for (int band = 1; band <= Bands(); band++) {
321 QString name = "MultivariateStatistics" + toString(band);
322 const PvlObject &mStats = inStats.findObject(name);
323 p_stats.push_back(MultivariateStatistics(mStats));
324 }
325
326 }
327
328
333 p_sampPercent = 0.0;
334 p_bands = 0;
335 p_sampRange = 0;
336 p_lineRange = 0;
337 p_minSampX = 0;
338 p_maxSampX = 0;
339 p_minSampY = 0;
340 p_maxSampY = 0;
341 p_minLineX = 0;
342 p_maxLineX = 0;
343 p_minLineY = 0;
344 p_maxLineY = 0;
345 p_mincnt = 0;
346 }
347
348
357 std::ostream &operator<<(std::ostream &os, Isis::OverlapStatistics &stats) {
358 PvlObject p = stats.toPvl();
359 os << p << endl;
360 return os;
361 }
362
363}
364
Functor for reduce using average functionality.
Definition Reduce.h:107
Buffer for containing a three dimensional section of an image.
Definition Brick.h:45
IO Handler for Isis Cubes.
Definition Cube.h:168
int lineCount() const
Definition Cube.cpp:1740
int sampleCount() const
Definition Cube.cpp:1813
PixelType pixelType() const
Definition Cube.cpp:1764
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition Cube.cpp:813
virtual QString fileName() const
Returns the opened cube's filename.
Definition Cube.cpp:1569
Projection * projection()
Definition Cube.cpp:1800
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition Cube.cpp:1416
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition FileName.cpp:162
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Container of multivariate statistics.
Calculates statistics in the area of overlap between two projected cubes.
int p_minLineX
Starting Line of overlap in X cube.
Isis::FileName FileNameY() const
Returns the filename of the second cube.
double SampPercent() const
Returns the percentage of cube lines sampled.
int p_minSampY
Starting Sample of overlap in Y cube.
int EndSampleX() const
Returns the ending sample position of the overlap in the first cube.
int Bands() const
Returns the number of bands both cubes have.
int StartSampleY() const
Returns the starting sample position of the overlap in the second cube.
bool HasOverlap() const
Checks all bands of the cubes for an overlap, and will only return false if none of the bands overlap...
void fromPvl(const PvlObject &inStats)
Unserialize overlap statistics from a Pvl.
int StartLineX() const
Returns the starting line position of the overlap in the first cube.
std::vector< Isis::MultivariateStatistics > p_stats
Multivariate Stats object for overlap data from both cubes.
int p_minSampX
Starting Sample of overlap in X cube.
Isis::MultivariateStatistics GetMStats(int band) const
Returns the MultivariateStatistics object containing all the data from both cubes in the overlapping ...
double p_sampPercent
Percentage of lines sampled.
int EndLineX() const
Returns the ending line position of the overlap in the first cube.
int p_sampRange
Sample range of overlap.
int p_mincnt
Minimum valid pixels to be valid overlap.
Isis::FileName FileNameX() const
Returns the filename of the first cube.
int p_maxSampY
Ending Sample of overlap in Y cube.
int p_maxLineX
Ending Line of overlap in X cube.
int Lines() const
Returns the number of lines in the overlapping area.
int StartLineY() const
Returns the starting line position of the overlap in the second cube.
void init()
Reset member variables to default values.
OverlapStatistics(Isis::Cube &x, Isis::Cube &y, QString progressMsg="Gathering Overlap Statistics", double sampPercent=100.0)
Constructs an OverlapStatistics object.
int p_maxSampX
Ending Sample of overlap in X cube.
int EndLineY() const
Returns the ending line position of the overlap in the second cube.
int p_lineRange
Line range of overlap.
int p_bands
Number of bands.
bool IsValid(unsigned int band) const
Returns whether the overlap meets the minimum valid pixel requirement.
Isis::FileName p_yFile
FileName of Y cube.
int Samples() const
Returns the number of samples in the overlapping area.
Isis::FileName p_xFile
FileName of X cube.
int EndSampleY() const
Returns the ending sample position of the overlap in the second cube.
PvlObject toPvl(QString name="OverlapStatistics") const
Creates a Pvl containing the following Overlap Statistics information File1 File2 Width Height Bands ...
int StartSampleX() const
Returns the starting sample position of the overlap in the first cube.
int p_minLineY
Starting Line of overlap in Y cube.
int p_maxLineY
Ending Line of overlap in Y cube.
Program progress reporter.
Definition Progress.h:42
void AddSteps(const int steps)
If the initial step size was a guess, it can be modified using this method.
Definition Progress.cpp:199
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
Base class for Map Projections.
Definition Projection.h:155
Contains multiple PvlContainers.
Definition PvlGroup.h:41
A single keyword-value pair.
Definition PvlKeyword.h:87
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
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
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.
Namespace for the standard library.