Isis 3 Programmer Reference
SpectralDefinition2D.cpp
Go to the documentation of this file.
1 
24 #include "SpectralDefinition2D.h"
25 
26 #include <cassert>
27 #include <QList>
28 
29 #include "ProcessBySample.h"
30 #include "Spectel.h"
31 
32 namespace Isis {
33 
43  ProcessBySample importCube;
45  m_spectelList = NULL;
46  m_sectionList = NULL;
47  Cube *smileCube = importCube.SetInputCube(smileDefFilename.expanded(), cai);
48 
49  try {
50  // Check to see if input definition has the correct format
51  if (smileCube->lineCount() != 2) {
52  QString msg = QObject::tr("Input calibration file [%1] must have 2 lines: "
53  "one containing wavelength centers and one containing widths").
54  arg(smileDefFilename.toString());
56  }
57 
60 
61  m_ns = smileCube->sampleCount();
62  m_nl = 0;
63  m_nb = smileCube->bandCount();
64 
65  m_sectionList->append(1); //first section will always be band 1
66  importCube.SetProcessingDirection(ProcessByBrick::BandsFirst);
67  importCube.Progress()->SetText("Importing Spectral Definition Cube");
68  importCube.ProcessCubeInPlace(*this, false);
69  importCube.Finalize();
70 
71  m_numSections = m_sectionList->length();
72 
73  } catch (IException &e) {
74  //delete dynamically allocated memory, since destructor won't be called.
75  if (m_spectelList != NULL) {
76  delete m_spectelList;
77  }
78  if (m_sectionList != NULL) {
79  delete m_sectionList;
80  }
81  QString msg = QObject::tr("Unable to open input cube [%1] and read it into a spectral "
82  "definition.").arg(smileDefFilename.toString());
84  }
85  }
86 
88  return m_numSections;
89  }
90 
91 
93  int SpectralDefinition2D::sectionNumber(int s, int l, int b) const {
94  if (m_sectionList->contains(b)) {
95  return m_sectionList->indexOf(b);
96  }
97  else if (m_sectionList->size() == 1) {
98  return 0;
99  }
100  else {
101  for (int i=0; i<m_sectionList->size()-1; i++ ) {
102  if ( (b > m_sectionList->at(i)) && (b < m_sectionList->at(i+1)) ) {
103  return i;
104  }
105  }
106  return m_sectionList->size() - 1;
107  }
108  }
109 
110 
113  delete m_spectelList;
114  delete m_sectionList;
115  }
116 
117 
129  Spectel SpectralDefinition2D::findSpectel(const int sample, const int line,
130  const int band) const {
131  // There is no DN, since the imported image's DNs are centers and widths
132 
133  // TODO:
134  // Test the QList bounds ourselves and throw an ISIS exception if not valid. QList.at does
135  // not throw if invalid. It aborts using assert
136  return m_spectelList->at(sample - 1)->at(band - 1);
137  }
138 
139 
140  Spectel SpectralDefinition2D::findSpectelByWavelength(const double wavelength,
141  const int sectionNumber) const {
142  // Can not search a 2D definistion with only one value (i.e. wavelength), so abort
143  // NOTE: This is ignored for code coverage until a good way to test it is found
144  // May not want to use the assert, but this function should not be called
145 
146  assert(0);
147  return Spectel();
148  }
149 
150  // TODO: If the requested wavelength is outside all the definitioin wavelength we should do something
151  Spectel SpectralDefinition2D::findSpectel(const Spectel &inSpectel,
152  const int sectionNumber) const {
153  double diff;
154  double bestdiff = DBL_MAX;
155  double bestband = 0;
156  double wavelength = inSpectel.centerWavelength();
157  QList<Spectel> *spectrum = m_spectelList->at(inSpectel.sample()-1);
158 
159  //only search in correct section
160  int start = m_sectionList->at(sectionNumber) - 1; //bands are 1-indexed, but are stored as 0-indexed
161  int end;
162  if (sectionNumber == m_sectionList->size()-1) { //we're in the last section
163  end = spectrum->length();
164  }
165  else {
166  end = m_sectionList->at(sectionNumber + 1) - 1;
167  }
168 
169  for (int i=start; i<end; i++) {
170  diff = spectrum->at(i).centerWavelength() - wavelength;
171  if (std::abs(diff) < std::abs(bestdiff)) {
172  bestdiff = diff;
173  bestband = i;
174  }
175  }
176 
177  // TODO: QList aborts if at(arg) is out of bounds do the necessary error check and throw if needed
178  return spectrum->at(bestband);
179  }
180 
189  QString temp;
190  for (int samp=0; samp<m_spectelList->size(); samp++) {
191  for(int band=0; band<m_spectelList->at(samp)->size(); band++){
192  Spectel spec = m_spectelList->at(samp)->at(band);
193  temp+="Spectel at (s,b) (";
194  temp+= QString::number(samp);
195  temp+= ", ";
196  temp+= QString::number(band);
197  temp+=") : Wavelength=";
198  temp+=QString::number(spec.centerWavelength());
199  temp+=" Width=";
200  temp+=QString::number(spec.filterWidth());
201  temp+="\n";
202  }
203  }
204  return temp;
205  }
206 
207 
208  // TODO: Test for equal wavelengths within a single section (currently ignored)
212 
213  // Each time we come back to the first band allocate space for this new spectrum of spectels
214  if (in.Band() == 1) {
215  QList<Spectel> *tempList = new QList<Spectel>;
216  m_spectelList->append(tempList);
217  }
218 
219  // Store the spectel
220  Spectel temp(in.Sample(), Isis::NULL8, in.Band(), Isis::NULL8, in[0], in[1]);
221  m_spectelList->at(in.Sample()-1)->append(temp);
222 
223  // Check for sections (change in wavelength direction) in the first spectrum only
224  // TODO: Consider doing this for all spectrums as a saftey check
225  // The first two spectels define the initial wavelength direction.
226  if (in.Sample() == 1) {
227 
228  QList<Spectel> *spectrum = m_spectelList->at(in.Sample()-1);
229  int index = in.Band() - 1;
230 
231  if ((index > 1) && // We now have at least 3 saved
232  (index != m_sectionList->last()) && // Don't look for a switch until one after the most recent
233  (((spectrum->at(index-2).centerWavelength() <
234  spectrum->at(index-1).centerWavelength()) && // previous 2 are ascending
235  (spectrum->at(index-1).centerWavelength() >
236  spectrum->at(index).centerWavelength())) || // previous and this are descending
237  ((spectrum->at(index-2).centerWavelength() >
238  spectrum->at(index-1).centerWavelength()) && // previous 2 are descending
239  (spectrum->at(index-1).centerWavelength() <
240  spectrum->at(index).centerWavelength())))) { // previous and this are ascending
241 
242  m_sectionList->append(in.Band());
243  }
244  }
245  }
246 }
SpectralDefinition2D(FileName smileDefFilename)
Construct a SpectralDefinition2D object using a filename.
Buffer for reading and writing cube data.
Definition: Buffer.h:69
Manipulate and parse attributes of input cube filenames.
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
Definition: Buffer.cpp:178
File name manipulation and expansion.
Definition: FileName.h:116
double centerWavelength() const
Gets central wavelength of spectel.
Definition: Spectel.cpp:111
int sampleCount() const
Definition: Cube.cpp:1452
Spectel findSpectel(const int sample, const int line, const int band) const
Get the Spectel at some sample, line, band (associated with your input/calibration file) ...
double filterWidth() const
Gets wavelength width associated with spectel.
Definition: Spectel.cpp:123
int m_numSections
The number of sections of this Spectral Definition.
void operator()(Buffer &in) const
Internal function used to help read-in a calibration cube.
Isis::Cube * SetInputCube(const QString &parameter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
QList< QList< Spectel > * > * m_spectelList
Internally represent the samples x 2 lines x n bands calibration file Outside list is the sample inde...
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
Definition: Buffer.cpp:143
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition: Progress.cpp:77
virtual int sectionCount() const
Returns the number of sections in the calibration image.
int sectionNumber(int s, int l, int b) const
returns section number given (s,l,b)
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
QString toString()
Returns QString representation of SpectralDefinition2D.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
void ProcessCubeInPlace(const Functor &funct, bool threaded=true)
Isis::Progress * Progress()
This method returns a pointer to a Progress object.
Definition: Process.h:270
int m_nl
Number of lines in input Cube.
int m_nb
Number of bands in input Cube.
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition: FileName.cpp:531
int m_ns
Number of samples in input Cube.
QList< int > * m_sectionList
The list of sections.
int lineCount() const
Definition: Cube.cpp:1379
void SetProcessingDirection(ProcessingDirection direction)
Set the direction the data will be read, either all lines in a single band proceeding to the next ban...
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition: Cube.cpp:1125
Stores information about a "Spectral pixel" or spectel.
Definition: Spectel.h:43
Process cubes by sample.
void Finalize()
Cleans up by closing cubes and freeing memory.
IO Handler for Isis Cubes.
Definition: Cube.h:170