Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
HiEqualization.cpp
1
6
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "HiEqualization.h"
10
11#include <iomanip>
12
13#include "Buffer.h"
14#include "Cube.h"
15#include "IException.h"
16#include "LineManager.h"
17#include "OverlapNormalization.h"
18#include "OverlapStatistics.h"
19#include "Process.h"
20#include "ProcessByLine.h"
21
22using std::string;
23using std::vector;
24
25
26namespace Isis {
27
28
29 HiEqualization::HiEqualization(QString fromListName) :
30 Equalization() {
31 loadInputs(fromListName);
32 }
33
34
35 HiEqualization::~HiEqualization() {
36 }
37
38
39 void HiEqualization::calculateStatistics() {
40 // TODO member variable
41 const FileList &imageList = getInputs();
42 QString maxCubeStr = toString((int) imageList.size());
43
44 // Adds statistics for whole and side regions of every cube
45 vector<Statistics *> statsList;
46 vector<Statistics *> leftStatsList;
47 vector<Statistics *> rightStatsList;
48 for (int img = 0; img < imageList.size(); img++) {
49 Statistics *stats = new Statistics();
50 Statistics *statsLeft = new Statistics();
51 Statistics *statsRight = new Statistics();
52
53 QString cubeStr = toString((int) img + 1);
54
55 ProcessByLine p;
56 p.Progress()->SetText("Calculating Statistics for Cube " +
57 cubeStr + " of " + maxCubeStr);
58 CubeAttributeInput att;
59 QString inp = imageList[img].toString();
60 p.SetInputCube(inp, att);
61 HiCalculateFunctor func(stats, statsLeft, statsRight, 100.0);
62 p.ProcessCubeInPlace(func, false);
63
64 statsList.push_back(stats);
65 leftStatsList.push_back(statsLeft);
66 rightStatsList.push_back(statsRight);
67 }
68
69 // Initialize the object that will calculate the gains and offsets
70 OverlapNormalization oNorm(statsList);
71
72 // Add the known overlaps between two cubes, and apply a weight to each
73 // overlap equal the number of pixels in the overlapping area
74 for (int i = 0; i < imageList.size() - 1; i++) {
75 int j = i + 1;
76 oNorm.AddOverlap(*rightStatsList[i], i, *leftStatsList[j], j,
77 rightStatsList[i]->ValidPixels());
78 }
79
80 loadHolds(&oNorm);
81
82 // Attempt to solve the least squares equation
83 oNorm.Solve(OverlapNormalization::Both);
84 setSolved(true);
85
86 clearAdjustments();
87 for (int img = 0; img < imageList.size(); img++) {
88 ImageAdjustment *adjustment = new ImageAdjustment(OverlapNormalization::Both);
89 adjustment->addGain(oNorm.Gain(img));
90 adjustment->addOffset(oNorm.Offset(img));
91 adjustment->addAverage(oNorm.Average(img));
92 addAdjustment(adjustment);
93 }
94
95 addValid(imageList.size() - 1);
96 setResults();
97 }
98
99
100 void HiEqualization::fillOutList(FileList &outList, QString toListName) {
101 if (toListName.isEmpty()) {
102 generateOutputs(outList);
103 }
104 else {
105 FileList tempList;
106 loadOutputs(tempList, toListName);
107
108 for (unsigned int i = 0; i < movedIndices.size(); i++) {
109 outList.push_back(tempList[movedIndices[i]]);
110 }
111 }
112 }
113
114
115 void HiEqualization::errorCheck(QString fromListName) {
116 const FileList &imageList = getInputs();
117
118 // Ensures number of images is within bound
119 if (imageList.size() > 10) {
120 QString msg = "The input file [" + fromListName +
121 "] cannot contain more than 10 file names";
122 throw IException(IException::User, msg, _FILEINFO_);
123 }
124
125 // Reference for converting a CPMM number to a CCD number
126 const int cpmm2ccd[] = {0, 1, 2, 3, 12, 4, 10, 11, 5, 13, 6, 7, 8, 9};
127
128 // Place ccd in vector, try-catch opening cubes
129 vector<int> ccds;
130 for (int i = 0; i < imageList.size(); i++) {
131 try {
132 Cube cube1;
133 cube1.open(imageList[i].toString());
134 PvlGroup &from1Instrument = cube1.group("INSTRUMENT");
135 int cpmmNumber = from1Instrument["CpmmNumber"];
136 ccds.push_back(cpmm2ccd[cpmmNumber]);
137
138 // In case we need to alter the order of the input list, keep a record
139 // of how the indices changed so we can rearrange the output list later
140 movedIndices.push_back(i);
141 }
142 catch (IException &e) {
143 QString msg = "The [" + imageList[i].toString() +
144 "] file is not a valid HiRise image";
145 throw IException(e, IException::User, msg, _FILEINFO_);
146 }
147 catch (...) {
148 // If any part of the above didn't work, we can safely assume the
149 // current file is not a valid HiRise image
150 QString msg = "The [" + imageList[i].toString() +
151 "] file is not a valid HiRise image";
152 throw IException(IException::User, msg, _FILEINFO_);
153 }
154 }
155
156 // Error checking to ensure CCDID types match
157 for (int i = 0; i < imageList.size() - 1; i++) {
158 int id1 = getCCDType(ccds[i]);
159 int id2 = getCCDType(ccds[i + 1]);
160
161 // CCDID types don't match
162 if (id1 != id2) {
163 string msg = "The list of input images must be all RED, all IR, or ";
164 msg += "all BG";
165 throw IException(IException::User, msg, _FILEINFO_);
166 }
167 }
168
169 // Insertion sorts a list of filenames by their CCD numbers
170 for (int i = 1; i < imageList.size(); i++) {
171 QString temp = imageList[i].toString();
172 int ccd1 = ccds[i];
173 int movedIndex = movedIndices[i];
174
175 int j = i - 1;
176 int ccd2 = ccds[j];
177
178 while (j >= 0 && ccd2 > ccd1) {
179 setInput(j + 1, imageList[j].toString());
180 ccds[j + 1] = ccds[j];
181 movedIndices[j + 1] = movedIndices[j];
182
183 j--;
184 if (j >= 0) ccd2 = ccds[j];
185 }
186
187 setInput(j + 1, temp);
188 ccds[j + 1] = ccd1;
189 movedIndices[j + 1] = movedIndex;
190 }
191
192 // Ensures BG and IR only have two files
193 if (ccds[0] == 10 || ccds[0] == 11) {
194 if (imageList.size() != 2) {
195 string msg = "A list of IR images must have exactly two ";
196 msg += "file names";
197 throw IException(IException::User, msg, _FILEINFO_);
198 }
199 }
200 else if (ccds[0] == 12 || ccds[0] == 13) {
201 if (imageList.size() != 2) {
202 string msg = "A list of BG images must have exactly two ";
203 msg += "file names";
204 throw IException(IException::User, msg, _FILEINFO_);
205 }
206 }
207 }
208
209
210 // CCD ID Type
211 int HiEqualization::getCCDType(int ccd) {
212 // Red, IR, or BG
213 return (ccd >= 0 && ccd <= 9) ? 0 : (ccd == 10 || ccd == 11) ? 1 : 2;
214 }
215
216
217 void HiEqualization::HiCalculateFunctor::addStats(Buffer &in) const {
218 Equalization::CalculateFunctor::addStats(in);
219
220 // Number of samples per line that intersect with the next and the
221 // previous images. Check if samples equal 682 or 683. If not the above
222 // case, then we perform an algorithm to account for binning. Number of
223 // intersecting samples is directly related to total number of samples in
224 // the line, with 2048 being the maximum possible.
225 unsigned int intersect = (in.size() == 682 || in.size() == 683) ?
226 18 : (48 * in.size()) / 2048;
227
228 m_statsLeft->AddData(&in[0], intersect);
229 m_statsRight->AddData(&in[in.size() - intersect], intersect);
230 }
231
232
233}
IO Handler for Isis Cubes.
Definition Cube.h:168
PvlGroup & group(const QString &group) const
Read a group from the cube into a Label.
Definition Cube.cpp:2277
void open(const QString &cfile, QString access="r")
This method will try to open a file as either a cube or geotiff in either read or read/write.
Definition Cube.cpp:792
This class can be used to calculate, read in, and/or apply equalization statistics for a list of file...
Internalizes a list of files.
Definition FileList.h:54
virtual void errorCheck(QString fromListName)
Checks that the input images have the same mapping groups and same number of bands.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.