Isis 3.0 Programmer Reference
Back | Home
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 E(2.7182818284590452354)
Sets some basic constants for use in ISIS programming.
double ToDouble() const
Returns the floating point value the IString represents.
Definition: IString.cpp:814
This class is used to manage buffers for calculating camera related information, such as angles...
const double PI(3.14159265358979323846)
The mathematical constant PI.
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.
int sampleCount() const
Definition: Cube.cpp:1404
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:38
DataValueType
This is used to tell what kind of data to push onto the RPN calculator.
int cubeIndex()
Accesses the cube index of the DataValue.
Isis exception class.
Definition: IException.h:99
Adds specific functionality to C++ strings.
Definition: IString.h:179
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:66
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:17:00