Isis 3 Programmer Reference
CubeCalculator.cpp
Go to the documentation of this file.
1 
22 #include "CubeCalculator.h"
23 
24 #include <QVector>
25 
26 #include "Angle.h"
27 #include "Camera.h"
28 #include "Distance.h"
29 #include "IString.h"
30 #include "Statistics.h"
31 
32 using namespace std;
33 
34 namespace Isis {
35 
37  CubeCalculator::CubeCalculator() {
38  m_calculations = NULL;
39  m_methods = NULL;
40  m_dataDefinitions = NULL;
41  m_cubeStats = NULL;
42  m_cubeCameras = NULL;
43  m_cameraBuffers = NULL;
44 
45  m_calculations = new QVector<Calculations>();
46  m_methods = new QVector<void (Calculator:: *)(void)>();
47  m_dataDefinitions = new QVector<DataValue>();
48  m_cubeStats = new QVector<Statistics *>();
49  m_cubeCameras = new QVector<Camera *>();
50  m_cameraBuffers = new QVector<CameraBuffers *>();
51 
52  m_outputSamples = 0;
53  }
54 
55 
57  CubeCalculator::~CubeCalculator() {
58  Clear(); // free dynamic memory in container members
59 
60  delete m_calculations;
61  delete m_methods;
62  delete m_dataDefinitions;
63  delete m_cubeStats;
64  delete m_cubeCameras;
65  delete m_cameraBuffers;
66 
67  m_calculations = NULL;
68  m_methods = NULL;
69  m_dataDefinitions = NULL;
70  m_cubeStats = NULL;
71  m_cubeCameras = NULL;
72  m_cameraBuffers = NULL;
73  }
74 
75 
79  void CubeCalculator::Clear() {
80  Calculator::Clear();
81 
82  if (m_calculations) {
83  m_calculations->clear();
84  }
85 
86  if (m_methods) {
87  m_methods->clear();
88  }
89 
90  if (m_dataDefinitions) {
91  m_dataDefinitions->clear();
92  }
93 
94  // m_cubeStats contains pointers to dynamic memory - need to free
95  if (m_cubeStats) {
96  for (int i = 0; i < m_cubeStats->size(); i++) {
97  delete (*m_cubeStats)[i];
98  (*m_cubeStats)[i] = NULL;
99  }
100  m_cubeStats->clear();
101  }
102 
103  if (m_cubeCameras) {
104  m_cubeCameras->clear();
105  }
106 
107  // m_cameraBuffers contains pointers to dynamic memory - need to free
108  if (m_cameraBuffers) {
109  for (int i = 0; i < m_cameraBuffers->size(); i++) {
110  delete (*m_cameraBuffers)[i];
111  (*m_cameraBuffers)[i] = NULL;
112  }
113  m_cameraBuffers->clear();
114  }
115  }
116 
117 
129  QVector<double> CubeCalculator::runCalculations(QVector<Buffer *> &cubeData,
130  int curLine,
131  int curBand) {
132  // For now we'll only process a single line in this method for our results. In order
133  // to do more powerful indexing, passing a list of cubes and the output cube will
134  // be necessary.
135  int methodIndex = 0;
136  int dataIndex = 0;
137 
138  for (int currentCalculation = 0; currentCalculation < m_calculations->size();
139  currentCalculation++) {
140  if ((*m_calculations)[currentCalculation] == CallNextMethod) {
141  void (Calculator::*aMethod)() = (*m_methods)[methodIndex];
142  (this->*aMethod)();
143  methodIndex ++;
144  }
145  else {
146  DataValue &data = (*m_dataDefinitions)[dataIndex];
147  if (data.type() == DataValue::Constant) {
148  Push(data.constant());
149  }
150  else if (data.type() == DataValue::Band) {
151  Push(curBand);
152  }
153  else if (data.type() == DataValue::Line) {
154  Push(curLine);
155  }
156  else if (data.type() == DataValue::Sample) {
157  QVector<double> samples;
158  samples.resize(m_outputSamples);
159 
160  for (int i = 0; i < m_outputSamples; i++) {
161  samples[i] = i + 1;
162  }
163 
164  Push(samples);
165  }
166  else if (data.type() == DataValue::CubeData) {
167  Push(*cubeData[data.cubeIndex()]);
168  }
169  else if (data.type() == DataValue::InaData) {
170  Push(*((*m_cameraBuffers)[data.cubeIndex()]->inaBuffer(curLine,
171  m_outputSamples,
172  curBand)));
173  }
174  else if (data.type() == DataValue::EmaData) {
175  Push(*((*m_cameraBuffers)[data.cubeIndex()]->emaBuffer(curLine,
176  m_outputSamples,
177  curBand)));
178  }
179  else if (data.type() == DataValue::PhaData) {
180  Push(*((*m_cameraBuffers)[data.cubeIndex()]->phaBuffer(curLine,
181  m_outputSamples,
182  curBand)));
183  }
184  else if (data.type() == DataValue::InalData) {
185  Push(*((*m_cameraBuffers)[data.cubeIndex()]->inalBuffer(curLine,
186  m_outputSamples,
187  curBand)));
188  }
189  else if (data.type() == DataValue::EmalData) {
190  Push(*((*m_cameraBuffers)[data.cubeIndex()]->emalBuffer(curLine,
191  m_outputSamples,
192  curBand)));
193  }
194  else if (data.type() == DataValue::PhalData) {
195  Push(*((*m_cameraBuffers)[data.cubeIndex()]->phalBuffer(curLine,
196  m_outputSamples,
197  curBand)));
198  }
199  else if (data.type() == DataValue::LatData) {
200  Push(*((*m_cameraBuffers)[data.cubeIndex()]->latBuffer(curLine,
201  m_outputSamples,
202  curBand)));
203  }
204  else if (data.type() == DataValue::LonData) {
205  Push(*((*m_cameraBuffers)[data.cubeIndex()]->lonBuffer(curLine,
206  m_outputSamples,
207  curBand)));
208  }
209  else if (data.type() == DataValue::ResData) {
210  Push(*((*m_cameraBuffers)[data.cubeIndex()]->resBuffer(curLine,
211  m_outputSamples,
212  curBand)));
213  }
214  else if (data.type() == DataValue::RadiusData) {
215  Push(*((*m_cameraBuffers)[data.cubeIndex()]->radiusBuffer(curLine,
216  m_outputSamples,
217  curBand)));
218  }
219  else if (data.type() == DataValue::InacData) {
220  Push(*((*m_cameraBuffers)[data.cubeIndex()]->inacBuffer(curLine,
221  m_outputSamples,
222  curBand)));
223  }
224  else if (data.type() == DataValue::EmacData) {
225  Push(*((*m_cameraBuffers)[data.cubeIndex()]->emacBuffer(curLine,
226  m_outputSamples,
227  curBand)));
228  }
229  else if (data.type() == DataValue::PhacData) {
230  Push(*((*m_cameraBuffers)[data.cubeIndex()]->phacBuffer(curLine,
231  m_outputSamples,
232  curBand)));
233  }
234  else {
235  }
236 
237  dataIndex ++;
238  }
239  }
240 
241  if (StackSize() != 1) {
242  string msg = "Too many operands in the equation.";
243  throw IException(IException::Unknown, msg, _FILEINFO_);
244  }
245 
246  return Pop(true);
247  }
248 
249 
264  void CubeCalculator::prepareCalculations(QString equation,
265  QVector<Cube *> &inCubes,
266  Cube *outCube) {
267  Clear();
268 
269  m_outputSamples = outCube->sampleCount();
270 
271  IString eq = equation;
272  while (eq != "") {
273  IString token = eq.Token(" ");
274 
275  // Step through every part of the postfix equation and set up the appropriate
276  // action list based on the current token. Attempting to order if-else conditions
277  // in terms of what would probably be encountered more often.
278 
279  // Scalars
280  if (isdigit(token[0]) || token[0] == '.') {
281  m_calculations->push_back(PushNextData);
282  m_dataDefinitions->push_back(DataValue(DataValue::Constant,
283  token.ToDouble()));
284  }
285  // File, e.g. F1 = first file in list. Must come after any functions starting with 'f' that
286  // is not a cube.
287  else if (token[0] == 'f') {
288  IString tok(token.substr(1));
289  int file = tok.ToInteger() - 1;
290  if (file < 0 || file >= (int)inCubes.size()) {
291  QString msg = "Invalid file number [" + tok.ToQt() + "]";
292  throw IException(IException::Unknown, msg, _FILEINFO_);
293  }
294 
295  m_calculations->push_back(PushNextData);
296  m_dataDefinitions->push_back(DataValue(DataValue::CubeData, file));
297  }
298  else if (token == "band") {
299  m_calculations->push_back(PushNextData);
300  m_dataDefinitions->push_back(DataValue(DataValue::Band));
301  }
302  else if (token == "line") {
303  m_calculations->push_back(PushNextData);
304  m_dataDefinitions->push_back(DataValue(DataValue::Line));
305  }
306  else if (token == "sample") {
307  m_calculations->push_back(PushNextData);
308  m_dataDefinitions->push_back(DataValue(DataValue::Sample));
309  }
310  // Addition
311  else if (token == "+") {
312  addMethodCall(&Calculator::Add);
313  }
314 
315  // Subtraction
316  else if (token == "-") {
317  addMethodCall(&Calculator::Subtract);
318  }
319 
320  // Multiplication
321  else if (token == "*") {
322  addMethodCall(&Calculator::Multiply);
323  }
324 
325  // Division
326  else if (token == "/") {
327  addMethodCall(&Calculator::Divide);
328  }
329 
330  // Modulus
331  else if (token == "%") {
332  addMethodCall(&Calculator::Modulus);
333  }
334 
335  // Exponent
336  else if (token == "^") {
337  addMethodCall(&Calculator::Exponent);
338  }
339 
340  // Negative
341  else if (token == "--") {
342  addMethodCall(&Calculator::Negative);
343  }
344 
345  // Negative
346  else if (token == "neg") {
347  addMethodCall(&Calculator::Negative);
348  }
349 
350  // Left shift
351  else if (token == "<<") {
352  addMethodCall(&Calculator::LeftShift);
353  }
354 
355  // Right shift
356  else if (token == ">>") {
357  addMethodCall(&Calculator::RightShift);
358  }
359 
360  // Maximum In The Line
361  else if (token == "linemax") {
362  addMethodCall(&Calculator::MaximumLine);
363  }
364 
365  // Maximum Pixel on a per-pixel basis
366  else if (token == "max") {
367  addMethodCall(&Calculator::MaximumPixel);
368  }
369 
370  // Minimum In The Line
371  else if (token == "linemin") {
372  addMethodCall(&Calculator::MinimumLine);
373  }
374 
375  // Minimum Pixel on a per-pixel basis
376  else if (token == "min") {
377  addMethodCall(&Calculator::MinimumPixel);
378  }
379 
380  // Absolute value
381  else if (token == "abs") {
382  addMethodCall(&Calculator::AbsoluteValue);
383  }
384 
385  // Square root
386  else if (token == "sqrt") {
387  addMethodCall(&Calculator::SquareRoot);
388  }
389 
390  // Natural Log
391  else if (token == "log" || token == "ln") {
392  addMethodCall(&Calculator::Log);
393  }
394 
395  // Log base 10
396  else if (token == "log10") {
397  addMethodCall(&Calculator::Log10);
398  }
399 
400  // Pi
401  else if (token == "pi") {
402  m_calculations->push_back(PushNextData);
403  m_dataDefinitions->push_back(
404  DataValue(DataValue::Constant, PI)
405  );
406  }
407 
408  // e
409  else if (token == "e") {
410  m_calculations->push_back(PushNextData);
411  m_dataDefinitions->push_back(
412  DataValue(DataValue::Constant, E)
413  );
414  }
415 
416  else if (token == "rads") {
417  m_calculations->push_back(PushNextData);
418  m_dataDefinitions->push_back(
419  DataValue(DataValue::Constant, PI / 180.0)
420  );
421 
422  addMethodCall(&Calculator::Multiply);
423  }
424 
425  else if (token == "degs") {
426  m_calculations->push_back(PushNextData);
427  m_dataDefinitions->push_back(
428  DataValue(DataValue::Constant, 180.0 / PI)
429  );
430  addMethodCall(&Calculator::Multiply);
431  }
432 
433  // Sine
434  else if (token == "sin") {
435  addMethodCall(&Calculator::Sine);
436  }
437 
438  // Cosine
439  else if (token == "cos") {
440  addMethodCall(&Calculator::Cosine);
441  }
442 
443  // Tangent
444  else if (token == "tan") {
445  addMethodCall(&Calculator::Tangent);
446  }
447 
448  // Secant
449  else if (token == "sec") {
450  addMethodCall(&Calculator::Secant);
451  }
452 
453  // Cosecant
454  else if (token == "csc") {
455  addMethodCall(&Calculator::Cosecant);
456  }
457 
458  // Cotangent
459  else if (token == "cot") {
460  addMethodCall(&Calculator::Cotangent);
461  }
462 
463  // Arcsin
464  else if (token == "asin") {
465  addMethodCall(&Calculator::Arcsine);
466  }
467 
468  // Arccos
469  else if (token == "acos") {
470  addMethodCall(&Calculator::Arccosine);
471  }
472 
473  // Arctan
474  else if (token == "atan") {
475  addMethodCall(&Calculator::Arctangent);
476  }
477 
478  // Arctan2
479  else if (token == "atan2") {
480  addMethodCall(&Calculator::Arctangent2);
481  }
482 
483  // SineH
484  else if (token == "sinh") {
485  addMethodCall(&Calculator::SineH);
486  }
487 
488  // CosH
489  else if (token == "cosh") {
490  addMethodCall(&Calculator::CosineH);
491  }
492 
493  // TanH
494  else if (token == "tanh") {
495  addMethodCall(&Calculator::TangentH);
496  }
497 
498  // Less than
499  else if (token == "<") {
500  addMethodCall(&Calculator::LessThan);
501  }
502 
503  // Greater than
504  else if (token == ">") {
505  addMethodCall(&Calculator::GreaterThan);
506  }
507 
508  // Less than or equal
509  else if (token == "<=") {
510  addMethodCall(&Calculator::LessThanOrEqual);
511  }
512 
513  // Greater than or equal
514  else if (token == ">=") {
515  addMethodCall(&Calculator::GreaterThanOrEqual);
516  }
517 
518  // Equal
519  else if (token == "==") {
520  addMethodCall(&Calculator::Equal);
521  }
522 
523  // Not equal
524  else if (token == "!=") {
525  addMethodCall(&Calculator::NotEqual);
526  }
527 
528  // Maximum in a cube
529  else if (token == "cubemax") {
530  int cubeIndex = lastPushToCubeStats(inCubes);
531 
532  m_calculations->push_back(PushNextData);
533  m_dataDefinitions->push_back(
534  DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Maximum())
535  );
536  //TODO: Test for NULL Maximum
537  }
538 
539  // Maximum in a cube
540  else if (token == "cubemin") {
541  int cubeIndex = lastPushToCubeStats(inCubes);
542 
543  m_calculations->push_back(PushNextData);
544  m_dataDefinitions->push_back(
545  DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Minimum())
546  );
547  //TODO: Test for NULL Minimum
548  }
549 
550  // Average of a cube
551  else if (token == "cubeavg") {
552  int cubeIndex = lastPushToCubeStats(inCubes);
553 
554  m_calculations->push_back(PushNextData);
555  m_dataDefinitions->push_back(
556  DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Average())
557  );
558  //TODO: Test for NULL Average
559  }
560 
561  // Standard deviation of a cube
562  else if (token == "cubestd") {
563  int cubeIndex = lastPushToCubeStats(inCubes);
564 
565  m_calculations->push_back(PushNextData);
566  m_dataDefinitions->push_back(
567  DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->StandardDeviation())
568  );
569  //TODO: Test for NULL standard deviation
570  }
571 
572  // Center incidence
573  else if (token == "inac") {
574  int cubeIndex = lastPushToCubeCameras(inCubes);
575  (*m_cameraBuffers)[cubeIndex]->enableInacBuffer();
576 
577  m_calculations->push_back(PushNextData);
578  m_dataDefinitions->push_back(DataValue(DataValue::InacData, cubeIndex));
579  }
580 
581  // Center emission
582  else if (token == "emac") {
583  int cubeIndex = lastPushToCubeCameras(inCubes);
584  (*m_cameraBuffers)[cubeIndex]->enableEmacBuffer();
585 
586  m_calculations->push_back(PushNextData);
587  m_dataDefinitions->push_back(DataValue(DataValue::EmacData, cubeIndex));
588  }
589 
590  // Center phase
591  else if (token == "phac") {
592  int cubeIndex = lastPushToCubeCameras(inCubes);
593  (*m_cameraBuffers)[cubeIndex]->enablePhacBuffer();
594 
595  m_calculations->push_back(PushNextData);
596  m_dataDefinitions->push_back(DataValue(DataValue::PhacData, cubeIndex));
597  }
598 
599  // Incidence on the ellipsoid
600  else if (token == "ina") {
601  int cubeIndex = lastPushToCubeCameras(inCubes);
602  (*m_cameraBuffers)[cubeIndex]->enableInaBuffer();
603 
604  m_calculations->push_back(PushNextData);
605  m_dataDefinitions->push_back(DataValue(DataValue::InaData, cubeIndex));
606  }
607 
608  // Emission on the ellipsoid
609  else if (token == "ema") {
610  int cubeIndex = lastPushToCubeCameras(inCubes);
611  (*m_cameraBuffers)[cubeIndex]->enableEmaBuffer();
612 
613  m_calculations->push_back(PushNextData);
614  m_dataDefinitions->push_back(DataValue(DataValue::EmaData, cubeIndex));
615  }
616 
617  // Phase on the ellipsoid
618  else if (token == "pha") {
619  int cubeIndex = lastPushToCubeCameras(inCubes);
620  (*m_cameraBuffers)[cubeIndex]->enablePhaBuffer();
621 
622  m_calculations->push_back(PushNextData);
623  m_dataDefinitions->push_back(DataValue(DataValue::PhaData, cubeIndex));
624  }
625 
626  // Incidence on the DTM
627  else if (token == "inal") {
628  int cubeIndex = lastPushToCubeCameras(inCubes);
629  (*m_cameraBuffers)[cubeIndex]->enableInalBuffer();
630 
631  m_calculations->push_back(PushNextData);
632  m_dataDefinitions->push_back(DataValue(DataValue::InalData, cubeIndex));
633  }
634 
635  // Emission on the DTM
636  else if (token == "emal") {
637  int cubeIndex = lastPushToCubeCameras(inCubes);
638  (*m_cameraBuffers)[cubeIndex]->enableEmalBuffer();
639 
640  m_calculations->push_back(PushNextData);
641  m_dataDefinitions->push_back(DataValue(DataValue::EmalData, cubeIndex));
642  }
643 
644  // Phase on the ellipsoid
645  else if (token == "phal") {
646  int cubeIndex = lastPushToCubeCameras(inCubes);
647  (*m_cameraBuffers)[cubeIndex]->enablePhalBuffer();
648 
649  m_calculations->push_back(PushNextData);
650  m_dataDefinitions->push_back(DataValue(DataValue::PhalData, cubeIndex));
651  }
652 
653  // Latitude
654  else if (token == "lat") {
655  int cubeIndex = lastPushToCubeCameras(inCubes);
656  (*m_cameraBuffers)[cubeIndex]->enableLatBuffer();
657 
658  m_calculations->push_back(PushNextData);
659  m_dataDefinitions->push_back(DataValue(DataValue::LatData, cubeIndex));
660  }
661 
662  // Longitude
663  else if (token == "lon") {
664  int cubeIndex = lastPushToCubeCameras(inCubes);
665  (*m_cameraBuffers)[cubeIndex]->enableLonBuffer();
666 
667  m_calculations->push_back(PushNextData);
668  m_dataDefinitions->push_back(DataValue(DataValue::LonData, cubeIndex));
669  }
670 
671  // Pixel resolution
672  else if (token == "res") {
673  int cubeIndex = lastPushToCubeCameras(inCubes);
674  (*m_cameraBuffers)[cubeIndex]->enableResBuffer();
675 
676  m_calculations->push_back(PushNextData);
677  m_dataDefinitions->push_back(DataValue(DataValue::ResData, cubeIndex));
678  }
679 
680  // Local Radius
681  else if (token == "radius") {
682  int cubeIndex = lastPushToCubeCameras(inCubes);
683  (*m_cameraBuffers)[cubeIndex]->enableRadiusBuffer();
684 
685  m_calculations->push_back(PushNextData);
686  m_dataDefinitions->push_back(DataValue(DataValue::RadiusData, cubeIndex));
687  }
688 
689  // Ignore empty token
690  else if (token == "") {
691  }
692 
693  else {
694  string msg = "Unidentified operator [";
695  msg += token + "]";
696  throw IException(IException::Unknown, msg, _FILEINFO_);
697  }
698  } // while loop
699  }
700 
701 
714  int CubeCalculator::lastPushToCubeStats(QVector<Cube *> &inCubes) {
715  if (!m_calculations->size()) {
716  string msg = "Not sure which file to get statistics from";
717  throw IException(IException::Unknown, msg, _FILEINFO_);
718  }
719 
720  if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
721  string msg = "This function must not contain calculations,";
722  msg += " only input cubes may be specified.";
723  throw IException(IException::Unknown, msg, _FILEINFO_);
724  }
725 
726  m_calculations->pop_back();
727 
728  // This must have data if calculations had data that equaled push data
729  DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
730 
731  if (lastData.type() != DataValue::CubeData) {
732  string msg = "This function must not contain constants,";
733  msg += " only input cubes may be specified.";
734  throw IException(IException::Unknown, msg, _FILEINFO_);
735  }
736 
737  int cubeStatsIndex = lastData.cubeIndex();
738  m_dataDefinitions->pop_back();
739 
740  // Member variables are now cleaned up, we need to verify the stats exists
741 
742  // Make sure room exists in the vector
743  while (m_cubeStats->size() < cubeStatsIndex + 1) {
744  m_cubeStats->push_back(NULL);
745  }
746 
747  // Now we can for sure put the stats object in the right place... put it
748  // there
749  if ((*m_cubeStats)[cubeStatsIndex] == NULL) {
750  (*m_cubeStats)[cubeStatsIndex] = inCubes[cubeStatsIndex]->statistics();
751  }
752 
753  return cubeStatsIndex;
754  }
755 
756 
774  int CubeCalculator::lastPushToCubeCameras(QVector<Cube *> &inCubes) {
775  if (!m_calculations->size()) {
776  string msg = "Not sure which file to get cameras from";
777  throw IException(IException::Unknown, msg, _FILEINFO_);
778  }
779 
780  if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
781  string msg = "This function must not contain calculations,";
782  msg += " only input cubes may be specified.";
783  throw IException(IException::Unknown, msg, _FILEINFO_);
784  }
785 
786  m_calculations->pop_back();
787 
788  // This must have data if calculations had data that equaled push data
789  DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
790 
791  if (lastData.type() != DataValue::CubeData) {
792  string msg = "This function must not contain constants,";
793  msg += " only input cubes may be specified.";
794  throw IException(IException::Unknown, msg, _FILEINFO_);
795  }
796 
797  int cubeIndex = lastData.cubeIndex();
798  m_dataDefinitions->pop_back();
799 
800  // Member variables are now cleaned up, we need to verify the camera exists
801 
802  // Make sure room exists in the vector
803  while (m_cubeCameras->size() < cubeIndex + 1) {
804  m_cubeCameras->push_back(NULL);
805  }
806 
807  while (m_cameraBuffers->size() < cubeIndex + 1) {
808  m_cameraBuffers->push_back(NULL);
809  }
810 
811  // Now we can for sure put the camera object in the right place... put it
812  // there
813  if ((*m_cubeCameras)[cubeIndex] == NULL) {
814  Camera *cam;
815  try {
816  cam = inCubes[cubeIndex]->camera();
817  if (cam == NULL) {
818  string msg = "This function requires a camera and the input cube does";
819  msg += " not have one. You may need to run spiceinit";
820  throw IException(IException::Unknown, msg, _FILEINFO_);
821  }
822  }
823  catch (IException &e) {
824  string msg = "This function requires a camera and the input cube does";
825  msg += " not have one. You may need to run spiceinit";
826  throw IException(e, IException::Unknown, msg, _FILEINFO_);
827  }
828 
829  (*m_cubeCameras)[cubeIndex] = cam;
830  (*m_cameraBuffers)[cubeIndex] = new CameraBuffers(cam);
831  }
832 
833  return cubeIndex;
834  }
835 
836 
843  void CubeCalculator::addMethodCall(void (Calculator::*method)(void)) {
844  m_calculations->push_back(CallNextMethod);
845  m_methods->push_back(method);
846  }
847 
848 
855  DataValue::DataValue() {
856  m_type = (DataValueType) - 1;
857  m_cubeIndex = -1;
858  m_constantValue = 0.0;
859  }
860 
861 
870  DataValue::DataValue(DataValueType type) {
871  m_type = type;
872  m_constantValue = 0.0;
873  m_cubeIndex = -1;
874  }
875 
876 
886  DataValue::DataValue(DataValueType type, int cubeIndex) {
887  m_type = type;
888  m_constantValue = 0.0;
889  m_cubeIndex = cubeIndex;
890  }
891 
892 
903  DataValue::DataValue(DataValueType type, double value) {
904  m_type = type;
905  m_cubeIndex = -1;
906 
907  if (type == Constant) {
908  m_constantValue = value;
909  }
910  }
911 
912 
918  DataValue::DataValueType DataValue::type() {
919  return m_type;
920  }
921 
922 
928  int DataValue::cubeIndex() {
929  return m_cubeIndex;
930  }
931 
932 
938  double DataValue::constant() {
939  return m_constantValue;
940  }
941 
942 
948  CameraBuffers::CameraBuffers(Camera *camera) {
949  m_camera = camera;
950  m_phaBuffer = NULL;
951  m_inaBuffer = NULL;
952  m_emaBuffer = NULL;
953  m_phalBuffer = NULL;
954  m_inalBuffer = NULL;
955  m_emalBuffer = NULL;
956  m_phacBuffer = NULL;
957  m_inacBuffer = NULL;
958  m_emacBuffer = NULL;
959  m_resBuffer = NULL;
960  m_latBuffer = NULL;
961  m_lonBuffer = NULL;
962  m_radiusBuffer = NULL;
963 
964  m_lastLine = -1;
965  }
966 
967 
971  CameraBuffers::~CameraBuffers() {
972  delete m_phaBuffer;
973  delete m_inaBuffer;
974  delete m_emaBuffer;
975  delete m_phalBuffer;
976  delete m_inalBuffer;
977  delete m_emalBuffer;
978  delete m_phacBuffer;
979  delete m_inacBuffer;
980  delete m_emacBuffer;
981  delete m_resBuffer;
982  delete m_latBuffer;
983  delete m_lonBuffer;
984  delete m_radiusBuffer;
985 
986  m_phaBuffer = NULL;
987  m_inaBuffer = NULL;
988  m_emaBuffer = NULL;
989  m_phalBuffer = NULL;
990  m_inalBuffer = NULL;
991  m_emalBuffer = NULL;
992  m_phacBuffer = NULL;
993  m_inacBuffer = NULL;
994  m_emacBuffer = NULL;
995  m_resBuffer = NULL;
996  m_latBuffer = NULL;
997  m_lonBuffer = NULL;
998  m_radiusBuffer = NULL;
999  }
1000 
1001 
1003  void CameraBuffers::enablePhaBuffer() {
1004  if (!m_phaBuffer) m_phaBuffer = new QVector<double>;
1005  }
1006 
1007 
1009  void CameraBuffers::enableInaBuffer() {
1010  if (!m_inaBuffer) m_inaBuffer = new QVector<double>;
1011  }
1012 
1013 
1015  void CameraBuffers::enableEmaBuffer() {
1016  if (!m_emaBuffer) m_emaBuffer = new QVector<double>;
1017  }
1018 
1019 
1021  void CameraBuffers::enableLatBuffer() {
1022  if (!m_latBuffer) m_latBuffer = new QVector<double>;
1023  }
1024 
1025 
1027  void CameraBuffers::enableLonBuffer() {
1028  if (!m_lonBuffer) m_lonBuffer = new QVector<double>;
1029  }
1030 
1031 
1033  void CameraBuffers::enableResBuffer() {
1034  if (!m_resBuffer) m_resBuffer = new QVector<double>;
1035  }
1036 
1037 
1039  void CameraBuffers::enableRadiusBuffer() {
1040  if (!m_radiusBuffer) m_radiusBuffer = new QVector<double>;
1041  }
1042 
1043 
1045  void CameraBuffers::enablePhalBuffer() {
1046  if (!m_phalBuffer) m_phalBuffer = new QVector<double>;
1047  }
1048 
1049 
1051  void CameraBuffers::enableInalBuffer() {
1052  if (!m_inalBuffer) m_inalBuffer = new QVector<double>;
1053  }
1054 
1055 
1057  void CameraBuffers::enableEmalBuffer() {
1058  if (!m_emalBuffer) m_emalBuffer = new QVector<double>;
1059  }
1060 
1061 
1063  void CameraBuffers::enablePhacBuffer() {
1064  if (!m_phacBuffer) m_phacBuffer = new QVector<double>;
1065  }
1066 
1067 
1069  void CameraBuffers::enableInacBuffer() {
1070  if (!m_inacBuffer) m_inacBuffer = new QVector<double>;
1071  }
1072 
1073 
1075  void CameraBuffers::enableEmacBuffer() {
1076  if (!m_emacBuffer) m_emacBuffer = new QVector<double>;
1077  }
1078 
1079 
1080  QVector<double> *CameraBuffers::phaBuffer(int currentLine, int ns, int currentBand) {
1081  loadBuffers(currentLine, ns, currentBand);
1082  return m_phaBuffer;
1083  }
1084 
1085 
1086  QVector<double> *CameraBuffers::inaBuffer(int currentLine, int ns, int currentBand) {
1087  loadBuffers(currentLine, ns, currentBand);
1088  return m_inaBuffer;
1089  }
1090 
1091 
1092  QVector<double> *CameraBuffers::emaBuffer(int currentLine, int ns, int currentBand) {
1093  loadBuffers(currentLine, ns, currentBand);
1094  return m_emaBuffer;
1095  }
1096 
1097 
1098  QVector<double> *CameraBuffers::latBuffer(int currentLine, int ns, int currentBand) {
1099  loadBuffers(currentLine, ns, currentBand);
1100  return m_latBuffer;
1101  }
1102 
1103 
1104  QVector<double> *CameraBuffers::lonBuffer(int currentLine, int ns, int currentBand) {
1105  loadBuffers(currentLine, ns, currentBand);
1106  return m_lonBuffer;
1107  }
1108 
1109 
1110  QVector<double> *CameraBuffers::resBuffer(int currentLine, int ns, int currentBand) {
1111  loadBuffers(currentLine, ns, currentBand);
1112  return m_resBuffer;
1113  }
1114 
1115 
1116  QVector<double> *CameraBuffers::radiusBuffer(int currentLine, int ns, int currentBand) {
1117  loadBuffers(currentLine,ns,currentBand);
1118  return m_radiusBuffer;
1119  }
1120 
1121 
1122  QVector<double> *CameraBuffers::phalBuffer(int currentLine, int ns, int currentBand) {
1123  loadBuffers(currentLine, ns, currentBand);
1124  return m_phalBuffer;
1125  }
1126 
1127 
1128  QVector<double> *CameraBuffers::inalBuffer(int currentLine, int ns, int currentBand) {
1129  loadBuffers(currentLine, ns, currentBand);
1130  return m_inalBuffer;
1131  }
1132 
1133 
1134  QVector<double> *CameraBuffers::emalBuffer(int currentLine, int ns, int currentBand) {
1135  loadBuffers(currentLine, ns, currentBand);
1136  return m_emalBuffer;
1137  }
1138 
1139 
1140  QVector<double> *CameraBuffers::phacBuffer(int currentLine, int ns, int currentBand) {
1141  loadBuffers(currentLine, ns, currentBand);
1142  return m_phacBuffer;
1143  }
1144 
1145 
1146  QVector<double> *CameraBuffers::inacBuffer(int currentLine, int ns, int currentBand) {
1147  loadBuffers(currentLine, ns, currentBand);
1148  return m_inacBuffer;
1149  }
1150 
1151 
1152  QVector<double> *CameraBuffers::emacBuffer(int currentLine, int ns, int currentBand) {
1153  loadBuffers(currentLine, ns, currentBand);
1154  return m_emacBuffer;
1155  }
1156 
1157 
1158  void CameraBuffers::loadBuffers(int currentLine, int ns, int currentBand) {
1159  if (currentLine != m_lastLine) {
1160  m_lastLine = currentLine;
1161 
1162  // Resize buffers if necessary
1163  if (m_phaBuffer) m_phaBuffer->resize(ns);
1164  if (m_inaBuffer) m_inaBuffer->resize(ns);
1165  if (m_emaBuffer) m_emaBuffer->resize(ns);
1166  if (m_latBuffer) m_latBuffer->resize(ns);
1167  if (m_lonBuffer) m_lonBuffer->resize(ns);
1168  if (m_resBuffer) m_resBuffer->resize(ns);
1169  if (m_radiusBuffer) m_radiusBuffer->resize(ns);
1170  if (m_phalBuffer) m_phalBuffer->resize(ns);
1171  if (m_inalBuffer) m_inalBuffer->resize(ns);
1172  if (m_emalBuffer) m_emalBuffer->resize(ns);
1173 
1174  // Center angle buffers will only ever have one item, the center angle value
1175  if (m_phacBuffer) m_phacBuffer->resize(1);
1176  if (m_inacBuffer) m_inacBuffer->resize(1);
1177  if (m_emacBuffer) m_emacBuffer->resize(1);
1178 
1179  m_camera->SetBand(currentBand);
1180 
1181  if (m_phacBuffer || m_inacBuffer || m_emacBuffer) {
1182  QString tokenName; // used for exception
1183  double centerLine = m_camera->Lines() / 2.0 + 0.5;
1184  double centerSamp = m_camera->Samples() / 2.0 + 0.5;
1185 
1186  if (m_camera->SetImage(centerSamp, centerLine)) {
1187  if (m_phacBuffer) {
1188  tokenName = "phac";
1189  (*m_phacBuffer)[0] = m_camera->PhaseAngle();
1190  }
1191  if (m_inacBuffer) {
1192  tokenName = "inac";
1193  (*m_inacBuffer)[0] = m_camera->IncidenceAngle();
1194  }
1195  if (m_emacBuffer) {
1196  tokenName = "emac";
1197  (*m_emacBuffer)[0] = m_camera->EmissionAngle();
1198  }
1199  }
1200  else {
1201  QString msg = "Unable to compute illumination angles at image center for operator ["
1202  + tokenName + "].";
1203  throw IException(IException::Unknown, msg, _FILEINFO_);
1204  }
1205  }
1206 
1207  else {
1208  for (int i = 0; i < ns; i++) {
1209 
1210  if (m_camera->SetImage(i + 1, currentLine)) {
1211  if (m_phaBuffer) (*m_phaBuffer)[i] = m_camera->PhaseAngle();
1212  if (m_inaBuffer) (*m_inaBuffer)[i] = m_camera->IncidenceAngle();
1213  if (m_emaBuffer) (*m_emaBuffer)[i] = m_camera->EmissionAngle();
1214  if (m_latBuffer) (*m_latBuffer)[i] = m_camera->UniversalLatitude();
1215  if (m_lonBuffer) (*m_lonBuffer)[i] = m_camera->UniversalLongitude();
1216  if (m_resBuffer) (*m_resBuffer)[i] = m_camera->PixelResolution();
1217  if (m_radiusBuffer) (*m_radiusBuffer)[i] = m_camera->LocalRadius().meters();
1218  if (m_phalBuffer || m_inalBuffer || m_emalBuffer) {
1219  Angle phal, inal, emal;
1220  bool okay;
1221  m_camera->LocalPhotometricAngles(phal, inal, emal, okay);
1222  if (okay) {
1223  if (m_phalBuffer) (*m_phalBuffer)[i] = phal.degrees();
1224  if (m_inalBuffer) (*m_inalBuffer)[i] = inal.degrees();
1225  if (m_emalBuffer) (*m_emalBuffer)[i] = emal.degrees();
1226  }
1227  else {
1228  if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
1229  if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
1230  if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;
1231  }
1232  }
1233  }
1234  else {
1235  if (m_phaBuffer) (*m_phaBuffer)[i] = NAN;
1236  if (m_inaBuffer) (*m_inaBuffer)[i] = NAN;
1237  if (m_emaBuffer) (*m_emaBuffer)[i] = NAN;
1238  if (m_latBuffer) (*m_latBuffer)[i] = NAN;
1239  if (m_lonBuffer) (*m_lonBuffer)[i] = NAN;
1240  if (m_resBuffer) (*m_resBuffer)[i] = NAN;
1241  if (m_radiusBuffer) (*m_radiusBuffer)[i] = NAN;
1242  if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
1243  if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
1244  if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;
1245  }
1246  }
1247  }
1248  }
1249  }
1250 
1251 } // End of namespace Isis
1252 
This class is used to define what kind of data is being pushed onto the cube calculator.
const double PI
The mathematical constant PI.
Definition: Constants.h:56
int sampleCount() const
Definition: Cube.cpp:1452
This class is used to manage buffers for calculating camera related information, such as angles...
double ToDouble() const
Returns the floating point value the IString represents.
Definition: IString.cpp:814
Namespace for the standard library.
int ToInteger() const
Returns the object string as an integer.
Definition: IString.cpp:733
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
IString Token(const IString &separator)
Returns the first token in the IString.
Definition: IString.cpp:912
DataValueType type()
Accesses the type of the DataValue.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
DataValueType
This is used to tell what kind of data to push onto the RPN calculator.
const double E
Sets some basic constants for use in ISIS programming.
Definition: Constants.h:55
int cubeIndex()
Accesses the cube index of the DataValue.
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
double constant()
Accesses the constant value of the DataValue.
Functor for reduce using average functionality.
Definition: Reduce.h:102
Calculator for arrays.
Definition: Calculator.h:70
IO Handler for Isis Cubes.
Definition: Cube.h:170