6 #include <geos/algorithm/ConvexHull.h>
7 #include <geos/geom/CoordinateSequence.h>
8 #include <geos/geom/CoordinateArraySequence.h>
9 #include <geos/geom/Envelope.h>
10 #include <geos/geom/Geometry.h>
11 #include <geos/geom/GeometryFactory.h>
12 #include <geos/geom/Polygon.h>
20 #include "CubeManager.h"
34 QString
sPointType [] = {
"Fixed",
"Constrained",
"Free" };
48 ControlNetStatistics::ControlNetStatistics(
ControlNet *pCNet,
const QString &psSerialNumFile,
56 mProgress = pProgress;
59 GetPointDoubleStats();
73 mProgress = pProgress;
76 GetPointDoubleStats();
84 ControlNetStatistics::~ControlNetStatistics() {
93 void ControlNetStatistics::InitSerialNumMap() {
94 int numSn = mSerialNumList.size();
96 for (
int i=0; i<numSn; i++) {
97 QString sn = mSerialNumList.serialNumber(i);
98 mSerialNumMap[sn] =
false;
112 void ControlNetStatistics::GenerateControlNetStats(
PvlGroup &pStatsGrp) {
113 pStatsGrp =
PvlGroup(
"ControlNetSummary");
114 int numSN = mSerialNumList.size();
123 pStatsGrp +=
PvlKeyword(
"IgnoredPoints",
toString(mCNet->GetNumPoints() - NumValidPoints()));
132 pStatsGrp +=
PvlKeyword(
"EditLockMeasures",
toString(mCNet->GetNumEditLockMeasures()));
134 double dValue = GetAverageResidual();
137 dValue = GetMinimumResidual();
140 dValue = GetMaximumResidual();
143 dValue = GetMinLineResidual();
146 dValue = GetMaxLineResidual();
149 dValue = GetMinSampleResidual();
152 dValue = GetMaxSampleResidual();
156 dValue = GetMinLineShift();
159 dValue = GetMaxLineShift();
162 dValue = GetMinSampleShift();
165 dValue = GetMaxSampleShift();
168 dValue = GetAvgPixelShift();
171 dValue = GetMinPixelShift();
174 dValue = GetMaxPixelShift();
177 dValue = mPointDoubleStats[minGFit];
180 dValue = mPointDoubleStats[maxGFit];
183 dValue = mPointDoubleStats[minEccentricity];
186 dValue = mPointDoubleStats[maxEccentricity];
189 dValue = mPointDoubleStats[minPixelZScore];
192 dValue = mPointDoubleStats[maxPixelZScore];
196 if (mSerialNumList.size()) {
197 dValue = mConvexHullRatioStats.Minimum();
200 dValue = mConvexHullRatioStats.Maximum();
203 dValue = mConvexHullRatioStats.Average();
216 void ControlNetStatistics::GenerateImageStats() {
217 geos::geom::GeometryFactory geosFactory;
222 mCubeGraphNodes = mCNet->GetCubeGraphNodes();
224 if (mProgress != NULL) {
225 mProgress->SetText(
"Generating Image Stats.....");
226 mProgress->SetMaximumSteps(mCubeGraphNodes.size());
227 mProgress->CheckStatus();
231 geos::geom::CoordinateSequence * ptCoordinates =
232 new geos::geom::CoordinateArraySequence();
235 vector<double> imgStats(numImageStats, 0);
238 QString sn = node->getSerialNumber();
239 Cube *cube = cubeMgr.
OpenCube(mSerialNumList.fileName(sn));
241 mSerialNumMap[sn] =
true;
246 double cubeArea = imgStats[imgSamples] * imgStats[imgLines];
251 if (!measures.isEmpty()) {
254 imgStats[imgTotalPoints]++;
255 if (parentPoint->IsIgnored()) {
256 imgStats[imgIgnoredPoints]++;
258 if (parentPoint->
GetType() == ControlPoint::Fixed) {
259 imgStats[imgFixedPoints]++;
261 if (parentPoint->
GetType() == ControlPoint::Constrained) {
262 imgStats[imgConstrainedPoints]++;
264 if (parentPoint->
GetType() == ControlPoint::Free) {
265 imgStats[imgFreePoints]++;
267 if (parentPoint->IsEditLocked()) {
268 imgStats[imgLockedPoints]++;
271 imgStats[imgLocked]++;
273 ptCoordinates->add(geos::geom::Coordinate(measure->GetSample(),
274 measure->GetLine()));
277 ptCoordinates->add(geos::geom::Coordinate(measures[0]->GetSample(),
278 measures[0]->GetLine()));
281 if (ptCoordinates->size() >= 4) {
287 geos::geom::Geometry * convexHull = geosFactory.createPolygon(
288 geosFactory.createLinearRing(ptCoordinates), 0)->convexHull();
291 imgStats[imgConvexHullArea] = convexHull->getArea();
292 imgStats[imgConvexHullRatio] = imgStats[imgConvexHullArea] / cubeArea;
296 mConvexHullStats.AddData(imgStats[imgConvexHullArea]);
297 mConvexHullRatioStats.AddData(imgStats[imgConvexHullRatio]);
299 mImageMap[sn] = imgStats;
301 delete ptCoordinates;
302 ptCoordinates = NULL;
305 if (mProgress != NULL)
306 mProgress->CheckStatus();
320 void ControlNetStatistics::PrintImageStats(
const QString &psImageFile) {
322 if (!mSerialNumList.size()) {
323 QString msg =
"Serial Number of Images has not been provided to get Image Stats";
329 QString outName(outFile.expanded());
330 ostm.open(outName.toLatin1().data(), std::ios::out);
333 QString msg = QObject::tr(
"Cannot open file [%1]").arg(psImageFile);
338 map<QString, bool>::iterator it;
342 ostm <<
"Filename, SerialNumber, TotalPoints, PointsIgnored, PointsEditLocked, Fixed, Constrained, Free, ConvexHullRatio" << endl;
344 for (it = mSerialNumMap.begin(); it != mSerialNumMap.end(); it++) {
345 ostm << mSerialNumList.fileName((*it).first) <<
", " << (*it).first <<
", ";
346 bool serialNumExists = (*it).second ;
347 if (serialNumExists) {
348 vector<double>imgStats = mImageMap[(*it).first] ;
349 ostm << imgStats[imgTotalPoints]<<
", " << imgStats[imgIgnoredPoints] <<
", " ;
350 ostm << imgStats[imgLockedPoints] <<
", " << imgStats[imgFixedPoints] <<
", " ;
351 ostm << imgStats[imgConstrainedPoints] <<
", " << imgStats[imgFreePoints] <<
", ";
352 ostm << imgStats[ imgConvexHullRatio] << endl;
355 ostm <<
"0, 0, 0, 0, 0, 0, 0" << endl;
360 QString msg = QObject::tr(
"Error writing to file: [%1]").arg(psImageFile);
376 vector<double> ControlNetStatistics::GetImageStatsBySerialNum(QString psSerialNum)
const {
377 return (*mImageMap.find(psSerialNum)).second;
390 void ControlNetStatistics::GeneratePointStats(
const QString &psPointFile) {
394 QString outName(outFile.expanded());
395 ostm.open(outName.toLatin1().data(), std::ios::out);
398 QString msg = QObject::tr(
"Cannot open file [%1]").arg(psPointFile);
402 ostm <<
" PointId, PointType, PointIgnore, PointEditLock, TotalMeasures, MeasuresValid, MeasuresIgnore, MeasuresEditLock," << endl;
404 int iNumPoints = mCNet->GetNumPoints();
407 if (mProgress != NULL && iNumPoints > 0) {
408 mProgress->SetText(
"Point Stats: Loading Control Points...");
409 mProgress->SetMaximumSteps(iNumPoints);
410 mProgress->CheckStatus();
413 for (
int i = 0; i < iNumPoints; i++) {
415 int iNumMeasures = cPoint->GetNumMeasures();
417 int iIgnoredMeasures = iNumMeasures - iValidMeasures;
421 ostm << sBoolean[(int)cPoint->IsEditLocked()] <<
", " << iNumMeasures <<
", " << iValidMeasures <<
", ";
425 if (mProgress != NULL)
426 mProgress->CheckStatus();
430 QString msg = QObject::tr(
"Error writing to file: [%1]").arg(psPointFile);
443 void ControlNetStatistics::GetPointIntStats() {
447 for (
int i=0; i<numPointIntStats; i++) {
448 mPointIntStats[i] = 0;
451 int iNumPoints = mCNet->GetNumPoints();
454 mPointIntStats[totalPoints] = iNumPoints;
456 for (
int i = 0; i < iNumPoints; i++) {
457 if (!mCNet->GetPoint(i)->IsIgnored()) {
459 mPointIntStats[validPoints]++;
463 mPointIntStats[ignoredPoints]++;
467 if (mCNet->GetPoint(i)->GetType() == ControlPoint::Fixed)
468 mPointIntStats[fixedPoints]++;
471 if (mCNet->GetPoint(i)->GetType() == ControlPoint::Constrained)
472 mPointIntStats[constrainedPoints]++;
475 if (mCNet->GetPoint(i)->GetType() == ControlPoint::Free)
476 mPointIntStats[freePoints]++;
479 if (mCNet->GetPoint(i)->IsEditLocked()) {
480 mPointIntStats[editLockedPoints]++;
484 mPointIntStats[totalMeasures] += mCNet->GetPoint(i)->GetNumMeasures();
487 mPointIntStats[validMeasures] += mCNet->GetPoint(i)->GetNumValidMeasures();
490 mPointIntStats[editLockedMeasures] += mCNet->GetPoint(i)->GetNumLockedMeasures();
493 mPointIntStats[ignoredMeasures] = mPointIntStats[totalMeasures] - mPointIntStats[validMeasures];
502 void ControlNetStatistics::InitPointDoubleStats() {
503 for (
int i = 0; i < numPointDblStats; i++) {
504 mPointDoubleStats[i] =
Null;
515 void ControlNetStatistics::GetPointDoubleStats() {
516 InitPointDoubleStats();
518 int iNumPoints = mCNet->GetNumPoints();
524 for (
int i = 0; i < iNumPoints; i++) {
527 if (!cp->IsIgnored()) {
528 for (
int cmIndex = 0; cmIndex < cp->GetNumMeasures(); cmIndex++) {
531 if (!cm->IsIgnored()) {
535 pixelShiftStats.
AddData(fabs(cm->GetPixelShift()));
541 &ControlMeasure::GetResidualMagnitude);
542 UpdateMinMaxStats(resMagStats, minResidual, maxResidual);
545 &ControlMeasure::GetLineResidual);
546 UpdateMinMaxStats(resLineStats, minLineResidual, maxLineResidual);
549 &ControlMeasure::GetSampleResidual);
550 UpdateMinMaxStats(resSampStats, minSampleResidual, maxSampleResidual);
553 &ControlMeasure::GetPixelShift);
554 UpdateMinMaxStats(pixShiftStats, minPixelShift, maxPixelShift);
557 &ControlMeasure::GetLineShift);
558 UpdateMinMaxStats(lineShiftStats, minLineShift, maxLineShift);
561 &ControlMeasure::GetSampleShift);
562 UpdateMinMaxStats(sampShiftStats, minSampleShift, maxSampleShift);
565 ControlMeasureLogData::GoodnessOfFit);
566 UpdateMinMaxStats(gFitStats, minGFit, maxGFit);
569 ControlMeasureLogData::MinimumPixelZScore);
572 dValue = fabs(minPixelZScoreStats.
Minimum());
573 if (mPointDoubleStats[minPixelZScore] > dValue)
574 mPointDoubleStats[minPixelZScore] = dValue;
578 ControlMeasureLogData::MaximumPixelZScore);
581 dValue = fabs(maxPixelZScoreStats.
Maximum());
582 if (mPointDoubleStats[maxPixelZScore] > dValue)
583 mPointDoubleStats[maxPixelZScore] = dValue;
588 mPointDoubleStats[avgResidual] = residualMagStats.
Average();
591 mPointDoubleStats[avgPixelShift] = pixelShiftStats.
Average();
595 void ControlNetStatistics::UpdateMinMaxStats(
const Statistics & stats,
596 ePointDoubleStats min, ePointDoubleStats max) {
598 if (mPointDoubleStats[min] !=
Null) {
599 mPointDoubleStats[min] = qMin(
600 mPointDoubleStats[min], fabs(stats.
Minimum()));
603 mPointDoubleStats[min] = fabs(stats.
Minimum());
606 if (mPointDoubleStats[max] !=
Null) {
607 mPointDoubleStats[max] = qMax(
608 mPointDoubleStats[max], fabs(stats.
Maximum()));
611 mPointDoubleStats[max] = fabs(stats.
Maximum());
PointType GetType() const
Serial Number with added functionality for Control Networks.
const double Null
Value for an Isis Null pixel.
File name manipulation and expansion.
Statistics GetStatistic(double(ControlMeasure::*statFunc)() const) const
This function will call a given method on every control measure that this point has.
double Minimum() const
Returns the absolute minimum double found in all data passed through the AddData method.
double GetResidualMagnitude() const
Return Residual magnitude.
int GetNumValidMeasures() const
QString sPointType[]
String names for Point Type.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
void SetNumOpenCubes(unsigned int numCubes)
This sets the maximum number of opened cubes for this instance of CubeManager.
This class is used to accumulate statistics on double arrays.
Program progress reporter.
QString GetId() const
Return the Id of the control point.
BigInt ValidPixels() const
Returns the total number of valid pixels processed.
Contains multiple PvlContainers.
double Average() const
Computes and returns the average.
#define _FILEINFO_
Macro for the filename and line number.
A single keyword-value pair.
double Maximum() const
Returns the absolute maximum double found in all data passed through the AddData method.
bool IsSpecial(const double d)
Returns if the input pixel is special.
QString sBoolean[]
String values for Boolean.
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
Class for quick re-accessing of cubes based on file name.
int GetNumLockedMeasures() const
Returns the number of locked control measures.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Serial Number list generator.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
Cube * OpenCube(const QString &cubeFileName)
This method opens a cube.
IO Handler for Isis Cubes.