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