Isis 3 Programmer Reference
CubeCalculator.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "CubeCalculator.h"
8
9#include <QVector>
10
11#include "Angle.h"
12#include "Camera.h"
13#include "Distance.h"
14#include "IString.h"
15#include "Statistics.h"
16
17using namespace std;
18
19namespace Isis {
20
23 m_calculations = NULL;
24 m_methods = NULL;
25 m_dataDefinitions = NULL;
26 m_cubeStats = NULL;
27 m_cubeCameras = NULL;
28 m_cameraBuffers = NULL;
29
30 m_calculations = new QVector<Calculations>();
31 m_methods = new QVector<void (Calculator:: *)(void)>();
32 m_dataDefinitions = new QVector<DataValue>();
33 m_cubeStats = new QVector<Statistics *>();
34 m_cubeCameras = new QVector<Camera *>();
35 m_cameraBuffers = new QVector<CameraBuffers *>();
36
38 }
39
40
43 Clear(); // free dynamic memory in container members
44
45 delete m_calculations;
46 delete m_methods;
47 delete m_dataDefinitions;
48 delete m_cubeStats;
49 delete m_cubeCameras;
50 delete m_cameraBuffers;
51
52 m_calculations = NULL;
53 m_methods = NULL;
54 m_dataDefinitions = NULL;
55 m_cubeStats = NULL;
56 m_cubeCameras = NULL;
57 m_cameraBuffers = NULL;
58 }
59
60
66
67 if (m_calculations) {
68 m_calculations->clear();
69 }
70
71 if (m_methods) {
72 m_methods->clear();
73 }
74
76 m_dataDefinitions->clear();
77 }
78
79 // m_cubeStats contains pointers to dynamic memory - need to free
80 if (m_cubeStats) {
81 for (int i = 0; i < m_cubeStats->size(); i++) {
82 delete (*m_cubeStats)[i];
83 (*m_cubeStats)[i] = NULL;
84 }
85 m_cubeStats->clear();
86 }
87
88 if (m_cubeCameras) {
89 m_cubeCameras->clear();
90 }
91
92 // m_cameraBuffers contains pointers to dynamic memory - need to free
93 if (m_cameraBuffers) {
94 for (int i = 0; i < m_cameraBuffers->size(); i++) {
95 delete (*m_cameraBuffers)[i];
96 (*m_cameraBuffers)[i] = NULL;
97 }
98 m_cameraBuffers->clear();
99 }
100 }
101
102
114 QVector<double> CubeCalculator::runCalculations(QVector<Buffer *> &cubeData,
115 int curLine,
116 int curBand) {
117 // For now we'll only process a single line in this method for our results. In order
118 // to do more powerful indexing, passing a list of cubes and the output cube will
119 // be necessary.
120 int methodIndex = 0;
121 int dataIndex = 0;
122
123 for (int currentCalculation = 0; currentCalculation < m_calculations->size();
124 currentCalculation++) {
125 if ((*m_calculations)[currentCalculation] == CallNextMethod) {
126 void (Calculator::*aMethod)() = (*m_methods)[methodIndex];
127 (this->*aMethod)();
128 methodIndex ++;
129 }
130 else {
131 DataValue &data = (*m_dataDefinitions)[dataIndex];
132 if (data.type() == DataValue::Constant) {
133 Push(data.constant());
134 }
135 else if (data.type() == DataValue::Band) {
136 Push(curBand);
137 }
138 else if (data.type() == DataValue::Line) {
139 Push(curLine);
140 }
141 else if (data.type() == DataValue::Sample) {
142 QVector<double> samples;
143 samples.resize(m_outputSamples);
144
145 for (int i = 0; i < m_outputSamples; i++) {
146 samples[i] = i + 1;
147 }
148
149 Push(samples);
150 }
151 else if (data.type() == DataValue::CubeData) {
152 Push(*cubeData[data.cubeIndex()]);
153 }
154 else if (data.type() == DataValue::InaData) {
155 Push(*((*m_cameraBuffers)[data.cubeIndex()]->inaBuffer(curLine,
157 curBand)));
158 }
159 else if (data.type() == DataValue::EmaData) {
160 Push(*((*m_cameraBuffers)[data.cubeIndex()]->emaBuffer(curLine,
162 curBand)));
163 }
164 else if (data.type() == DataValue::PhaData) {
165 Push(*((*m_cameraBuffers)[data.cubeIndex()]->phaBuffer(curLine,
167 curBand)));
168 }
169 else if (data.type() == DataValue::InalData) {
170 Push(*((*m_cameraBuffers)[data.cubeIndex()]->inalBuffer(curLine,
172 curBand)));
173 }
174 else if (data.type() == DataValue::EmalData) {
175 Push(*((*m_cameraBuffers)[data.cubeIndex()]->emalBuffer(curLine,
177 curBand)));
178 }
179 else if (data.type() == DataValue::PhalData) {
180 Push(*((*m_cameraBuffers)[data.cubeIndex()]->phalBuffer(curLine,
182 curBand)));
183 }
184 else if (data.type() == DataValue::LatData) {
185 Push(*((*m_cameraBuffers)[data.cubeIndex()]->latBuffer(curLine,
187 curBand)));
188 }
189 else if (data.type() == DataValue::LonData) {
190 Push(*((*m_cameraBuffers)[data.cubeIndex()]->lonBuffer(curLine,
192 curBand)));
193 }
194 else if (data.type() == DataValue::ResData) {
195 Push(*((*m_cameraBuffers)[data.cubeIndex()]->resBuffer(curLine,
197 curBand)));
198 }
199 else if (data.type() == DataValue::RadiusData) {
200 Push(*((*m_cameraBuffers)[data.cubeIndex()]->radiusBuffer(curLine,
202 curBand)));
203 }
204 else if (data.type() == DataValue::InacData) {
205 Push(*((*m_cameraBuffers)[data.cubeIndex()]->inacBuffer(curLine,
207 curBand)));
208 }
209 else if (data.type() == DataValue::EmacData) {
210 Push(*((*m_cameraBuffers)[data.cubeIndex()]->emacBuffer(curLine,
212 curBand)));
213 }
214 else if (data.type() == DataValue::PhacData) {
215 Push(*((*m_cameraBuffers)[data.cubeIndex()]->phacBuffer(curLine,
217 curBand)));
218 }
219 else {
220 }
221
222 dataIndex ++;
223 }
224 }
225
226 if (StackSize() != 1) {
227 string msg = "Too many operands in the equation.";
228 throw IException(IException::Unknown, msg, _FILEINFO_);
229 }
230
231 return Pop(true);
232 }
233
234
250 QVector<Cube *> &inCubes,
251 Cube *outCube) {
252 Clear();
253
254 m_outputSamples = outCube->sampleCount();
255
256 IString eq = equation;
257 while (eq != "") {
258 IString token = eq.Token(" ");
259
260 // Step through every part of the postfix equation and set up the appropriate
261 // action list based on the current token. Attempting to order if-else conditions
262 // in terms of what would probably be encountered more often.
263
264 // Scalars
265 if (isdigit(token[0]) || token[0] == '.') {
266 m_calculations->push_back(PushNextData);
268 token.ToDouble()));
269 }
270 // File, e.g. F1 = first file in list. Must come after any functions starting with 'f' that
271 // is not a cube.
272 else if (token[0] == 'f') {
273 IString tok(token.substr(1));
274 int file = tok.ToInteger() - 1;
275 if (file < 0 || file >= (int)inCubes.size()) {
276 QString msg = "Invalid file number [" + tok.ToQt() + "]";
277 throw IException(IException::Unknown, msg, _FILEINFO_);
278 }
279
280 m_calculations->push_back(PushNextData);
282 }
283 else if (token == "band") {
284 m_calculations->push_back(PushNextData);
286 }
287 else if (token == "line") {
288 m_calculations->push_back(PushNextData);
290 }
291 else if (token == "sample") {
292 m_calculations->push_back(PushNextData);
294 }
295 // Addition
296 else if (token == "+") {
298 }
299
300 // Subtraction
301 else if (token == "-") {
303 }
304
305 // Multiplication
306 else if (token == "*") {
308 }
309
310 // Division
311 else if (token == "/") {
313 }
314
315 // Modulus
316 else if (token == "%") {
318 }
319
320 // Exponent
321 else if (token == "^") {
323 }
324
325 // Negative
326 else if (token == "--") {
328 }
329
330 // Negative
331 else if (token == "neg") {
333 }
334
335 // Left shift
336 else if (token == "<<") {
338 }
339
340 // Right shift
341 else if (token == ">>") {
343 }
344
345 // Maximum In The Line
346 else if (token == "linemax") {
348 }
349
350 // Maximum Pixel on a per-pixel basis
351 else if (token == "max") {
353 }
354
355 // Minimum In The Line
356 else if (token == "linemin") {
358 }
359
360 // Minimum Pixel on a per-pixel basis
361 else if (token == "min") {
363 }
364
365 // Absolute value
366 else if (token == "abs") {
368 }
369
370 // Square root
371 else if (token == "sqrt") {
373 }
374
375 // Natural Log
376 else if (token == "log" || token == "ln") {
378 }
379
380 // Log base 10
381 else if (token == "log10") {
383 }
384
385 // Pi
386 else if (token == "pi") {
387 m_calculations->push_back(PushNextData);
388 m_dataDefinitions->push_back(
390 );
391 }
392
393 // e
394 else if (token == "e") {
395 m_calculations->push_back(PushNextData);
396 m_dataDefinitions->push_back(
398 );
399 }
400
401 else if (token == "rads") {
402 m_calculations->push_back(PushNextData);
403 m_dataDefinitions->push_back(
405 );
406
408 }
409
410 else if (token == "degs") {
411 m_calculations->push_back(PushNextData);
412 m_dataDefinitions->push_back(
414 );
416 }
417
418 // Sine
419 else if (token == "sin") {
421 }
422
423 // Cosine
424 else if (token == "cos") {
426 }
427
428 // Tangent
429 else if (token == "tan") {
431 }
432
433 // Secant
434 else if (token == "sec") {
436 }
437
438 // Cosecant
439 else if (token == "csc") {
441 }
442
443 // Cotangent
444 else if (token == "cot") {
446 }
447
448 // Arcsin
449 else if (token == "asin") {
451 }
452
453 // Arccos
454 else if (token == "acos") {
456 }
457
458 // Arctan
459 else if (token == "atan") {
461 }
462
463 // Arctan2
464 else if (token == "atan2") {
466 }
467
468 // SineH
469 else if (token == "sinh") {
471 }
472
473 // CosH
474 else if (token == "cosh") {
476 }
477
478 // TanH
479 else if (token == "tanh") {
481 }
482
483 // Less than
484 else if (token == "<") {
486 }
487
488 // Greater than
489 else if (token == ">") {
491 }
492
493 // Less than or equal
494 else if (token == "<=") {
496 }
497
498 // Greater than or equal
499 else if (token == ">=") {
501 }
502
503 // Equal
504 else if (token == "==") {
506 }
507
508 // Not equal
509 else if (token == "!=") {
511 }
512
513 // Maximum in a cube
514 else if (token == "cubemax") {
515 int cubeIndex = lastPushToCubeStats(inCubes);
516
517 m_calculations->push_back(PushNextData);
518 m_dataDefinitions->push_back(
519 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Maximum())
520 );
521 //TODO: Test for NULL Maximum
522 }
523
524 // Maximum in a cube
525 else if (token == "cubemin") {
526 int cubeIndex = lastPushToCubeStats(inCubes);
527
528 m_calculations->push_back(PushNextData);
529 m_dataDefinitions->push_back(
530 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Minimum())
531 );
532 //TODO: Test for NULL Minimum
533 }
534
535 // Average of a cube
536 else if (token == "cubeavg") {
537 int cubeIndex = lastPushToCubeStats(inCubes);
538
539 m_calculations->push_back(PushNextData);
540 m_dataDefinitions->push_back(
542 );
543 //TODO: Test for NULL Average
544 }
545
546 // Standard deviation of a cube
547 else if (token == "cubestd") {
548 int cubeIndex = lastPushToCubeStats(inCubes);
549
550 m_calculations->push_back(PushNextData);
551 m_dataDefinitions->push_back(
552 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->StandardDeviation())
553 );
554 //TODO: Test for NULL standard deviation
555 }
556
557 // Center incidence
558 else if (token == "inac") {
559 int cubeIndex = lastPushToCubeCameras(inCubes);
560 (*m_cameraBuffers)[cubeIndex]->enableInacBuffer();
561
562 m_calculations->push_back(PushNextData);
563 m_dataDefinitions->push_back(DataValue(DataValue::InacData, cubeIndex));
564 }
565
566 // Center emission
567 else if (token == "emac") {
568 int cubeIndex = lastPushToCubeCameras(inCubes);
569 (*m_cameraBuffers)[cubeIndex]->enableEmacBuffer();
570
571 m_calculations->push_back(PushNextData);
572 m_dataDefinitions->push_back(DataValue(DataValue::EmacData, cubeIndex));
573 }
574
575 // Center phase
576 else if (token == "phac") {
577 int cubeIndex = lastPushToCubeCameras(inCubes);
578 (*m_cameraBuffers)[cubeIndex]->enablePhacBuffer();
579
580 m_calculations->push_back(PushNextData);
581 m_dataDefinitions->push_back(DataValue(DataValue::PhacData, cubeIndex));
582 }
583
584 // Incidence on the ellipsoid
585 else if (token == "ina") {
586 int cubeIndex = lastPushToCubeCameras(inCubes);
587 (*m_cameraBuffers)[cubeIndex]->enableInaBuffer();
588
589 m_calculations->push_back(PushNextData);
590 m_dataDefinitions->push_back(DataValue(DataValue::InaData, cubeIndex));
591 }
592
593 // Emission on the ellipsoid
594 else if (token == "ema") {
595 int cubeIndex = lastPushToCubeCameras(inCubes);
596 (*m_cameraBuffers)[cubeIndex]->enableEmaBuffer();
597
598 m_calculations->push_back(PushNextData);
599 m_dataDefinitions->push_back(DataValue(DataValue::EmaData, cubeIndex));
600 }
601
602 // Phase on the ellipsoid
603 else if (token == "pha") {
604 int cubeIndex = lastPushToCubeCameras(inCubes);
605 (*m_cameraBuffers)[cubeIndex]->enablePhaBuffer();
606
607 m_calculations->push_back(PushNextData);
608 m_dataDefinitions->push_back(DataValue(DataValue::PhaData, cubeIndex));
609 }
610
611 // Incidence on the DTM
612 else if (token == "inal") {
613 int cubeIndex = lastPushToCubeCameras(inCubes);
614 (*m_cameraBuffers)[cubeIndex]->enableInalBuffer();
615
616 m_calculations->push_back(PushNextData);
617 m_dataDefinitions->push_back(DataValue(DataValue::InalData, cubeIndex));
618 }
619
620 // Emission on the DTM
621 else if (token == "emal") {
622 int cubeIndex = lastPushToCubeCameras(inCubes);
623 (*m_cameraBuffers)[cubeIndex]->enableEmalBuffer();
624
625 m_calculations->push_back(PushNextData);
626 m_dataDefinitions->push_back(DataValue(DataValue::EmalData, cubeIndex));
627 }
628
629 // Phase on the ellipsoid
630 else if (token == "phal") {
631 int cubeIndex = lastPushToCubeCameras(inCubes);
632 (*m_cameraBuffers)[cubeIndex]->enablePhalBuffer();
633
634 m_calculations->push_back(PushNextData);
635 m_dataDefinitions->push_back(DataValue(DataValue::PhalData, cubeIndex));
636 }
637
638 // Latitude
639 else if (token == "lat") {
640 int cubeIndex = lastPushToCubeCameras(inCubes);
641 (*m_cameraBuffers)[cubeIndex]->enableLatBuffer();
642
643 m_calculations->push_back(PushNextData);
644 m_dataDefinitions->push_back(DataValue(DataValue::LatData, cubeIndex));
645 }
646
647 // Longitude
648 else if (token == "lon") {
649 int cubeIndex = lastPushToCubeCameras(inCubes);
650 (*m_cameraBuffers)[cubeIndex]->enableLonBuffer();
651
652 m_calculations->push_back(PushNextData);
653 m_dataDefinitions->push_back(DataValue(DataValue::LonData, cubeIndex));
654 }
655
656 // Pixel resolution
657 else if (token == "res") {
658 int cubeIndex = lastPushToCubeCameras(inCubes);
659 (*m_cameraBuffers)[cubeIndex]->enableResBuffer();
660
661 m_calculations->push_back(PushNextData);
662 m_dataDefinitions->push_back(DataValue(DataValue::ResData, cubeIndex));
663 }
664
665 // Local Radius
666 else if (token == "radius") {
667 int cubeIndex = lastPushToCubeCameras(inCubes);
668 (*m_cameraBuffers)[cubeIndex]->enableRadiusBuffer();
669
670 m_calculations->push_back(PushNextData);
671 m_dataDefinitions->push_back(DataValue(DataValue::RadiusData, cubeIndex));
672 }
673
674 // Ignore empty token
675 else if (token == "") {
676 }
677
678 else {
679 string msg = "Unidentified operator [";
680 msg += token + "]";
681 throw IException(IException::Unknown, msg, _FILEINFO_);
682 }
683 } // while loop
684 }
685
686
699 int CubeCalculator::lastPushToCubeStats(QVector<Cube *> &inCubes) {
700 if (!m_calculations->size()) {
701 string msg = "Not sure which file to get statistics from";
702 throw IException(IException::Unknown, msg, _FILEINFO_);
703 }
704
705 if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
706 string msg = "This function must not contain calculations,";
707 msg += " only input cubes may be specified.";
708 throw IException(IException::Unknown, msg, _FILEINFO_);
709 }
710
711 m_calculations->pop_back();
712
713 // This must have data if calculations had data that equaled push data
714 DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
715
716 if (lastData.type() != DataValue::CubeData) {
717 string msg = "This function must not contain constants,";
718 msg += " only input cubes may be specified.";
719 throw IException(IException::Unknown, msg, _FILEINFO_);
720 }
721
722 int cubeStatsIndex = lastData.cubeIndex();
723 m_dataDefinitions->pop_back();
724
725 // Member variables are now cleaned up, we need to verify the stats exists
726
727 // Make sure room exists in the vector
728 while (m_cubeStats->size() < cubeStatsIndex + 1) {
729 m_cubeStats->push_back(NULL);
730 }
731
732 // Now we can for sure put the stats object in the right place... put it
733 // there
734 if ((*m_cubeStats)[cubeStatsIndex] == NULL) {
735 (*m_cubeStats)[cubeStatsIndex] = inCubes[cubeStatsIndex]->statistics();
736 }
737
738 return cubeStatsIndex;
739 }
740
741
759 int CubeCalculator::lastPushToCubeCameras(QVector<Cube *> &inCubes) {
760 if (!m_calculations->size()) {
761 string msg = "Not sure which file to get cameras from";
762 throw IException(IException::Unknown, msg, _FILEINFO_);
763 }
764
765 if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
766 string msg = "This function must not contain calculations,";
767 msg += " only input cubes may be specified.";
768 throw IException(IException::Unknown, msg, _FILEINFO_);
769 }
770
771 m_calculations->pop_back();
772
773 // This must have data if calculations had data that equaled push data
774 DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
775
776 if (lastData.type() != DataValue::CubeData) {
777 string msg = "This function must not contain constants,";
778 msg += " only input cubes may be specified.";
779 throw IException(IException::Unknown, msg, _FILEINFO_);
780 }
781
782 int cubeIndex = lastData.cubeIndex();
783 m_dataDefinitions->pop_back();
784
785 // Member variables are now cleaned up, we need to verify the camera exists
786
787 // Make sure room exists in the vector
788 while (m_cubeCameras->size() < cubeIndex + 1) {
789 m_cubeCameras->push_back(NULL);
790 }
791
792 while (m_cameraBuffers->size() < cubeIndex + 1) {
793 m_cameraBuffers->push_back(NULL);
794 }
795
796 // Now we can for sure put the camera object in the right place... put it
797 // there
798 if ((*m_cubeCameras)[cubeIndex] == NULL) {
799 Camera *cam;
800 try {
801 cam = inCubes[cubeIndex]->camera();
802 if (cam == NULL) {
803 string msg = "This function requires a camera and the input cube does";
804 msg += " not have one. You may need to run spiceinit";
805 throw IException(IException::Unknown, msg, _FILEINFO_);
806 }
807 }
808 catch (IException &e) {
809 string msg = "This function requires a camera and the input cube does";
810 msg += " not have one. You may need to run spiceinit";
811 throw IException(e, IException::Unknown, msg, _FILEINFO_);
812 }
813
814 (*m_cubeCameras)[cubeIndex] = cam;
815 (*m_cameraBuffers)[cubeIndex] = new CameraBuffers(cam);
816 }
817
818 return cubeIndex;
819 }
820
821
828 void CubeCalculator::addMethodCall(void (Calculator::*method)(void)) {
829 m_calculations->push_back(CallNextMethod);
830 m_methods->push_back(method);
831 }
832
833
841 m_type = (DataValueType) - 1;
842 m_cubeIndex = -1;
843 m_constantValue = 0.0;
844 }
845
846
856 m_type = type;
857 m_constantValue = 0.0;
858 m_cubeIndex = -1;
859 }
860
861
871 DataValue::DataValue(DataValueType type, int cubeIndex) {
872 m_type = type;
873 m_constantValue = 0.0;
875 }
876
877
889 m_type = type;
890 m_cubeIndex = -1;
891
892 if (type == Constant) {
893 m_constantValue = value;
894 }
895 }
896
897
906
907
914 return m_cubeIndex;
915 }
916
917
924 return m_constantValue;
925 }
926
927
934 m_camera = camera;
935 m_phaBuffer = NULL;
936 m_inaBuffer = NULL;
937 m_emaBuffer = NULL;
938 m_phalBuffer = NULL;
939 m_inalBuffer = NULL;
940 m_emalBuffer = NULL;
941 m_phacBuffer = NULL;
942 m_inacBuffer = NULL;
943 m_emacBuffer = NULL;
944 m_resBuffer = NULL;
945 m_latBuffer = NULL;
946 m_lonBuffer = NULL;
947 m_radiusBuffer = NULL;
948
949 m_lastLine = -1;
950 }
951
952
957 delete m_phaBuffer;
958 delete m_inaBuffer;
959 delete m_emaBuffer;
960 delete m_phalBuffer;
961 delete m_inalBuffer;
962 delete m_emalBuffer;
963 delete m_phacBuffer;
964 delete m_inacBuffer;
965 delete m_emacBuffer;
966 delete m_resBuffer;
967 delete m_latBuffer;
968 delete m_lonBuffer;
969 delete m_radiusBuffer;
970
971 m_phaBuffer = NULL;
972 m_inaBuffer = NULL;
973 m_emaBuffer = NULL;
974 m_phalBuffer = NULL;
975 m_inalBuffer = NULL;
976 m_emalBuffer = NULL;
977 m_phacBuffer = NULL;
978 m_inacBuffer = NULL;
979 m_emacBuffer = NULL;
980 m_resBuffer = NULL;
981 m_latBuffer = NULL;
982 m_lonBuffer = NULL;
983 m_radiusBuffer = NULL;
984 }
985
986
989 if (!m_phaBuffer) m_phaBuffer = new QVector<double>;
990 }
991
992
995 if (!m_inaBuffer) m_inaBuffer = new QVector<double>;
996 }
997
998
1001 if (!m_emaBuffer) m_emaBuffer = new QVector<double>;
1002 }
1003
1004
1007 if (!m_latBuffer) m_latBuffer = new QVector<double>;
1008 }
1009
1010
1013 if (!m_lonBuffer) m_lonBuffer = new QVector<double>;
1014 }
1015
1016
1019 if (!m_resBuffer) m_resBuffer = new QVector<double>;
1020 }
1021
1022
1025 if (!m_radiusBuffer) m_radiusBuffer = new QVector<double>;
1026 }
1027
1028
1031 if (!m_phalBuffer) m_phalBuffer = new QVector<double>;
1032 }
1033
1034
1037 if (!m_inalBuffer) m_inalBuffer = new QVector<double>;
1038 }
1039
1040
1043 if (!m_emalBuffer) m_emalBuffer = new QVector<double>;
1044 }
1045
1046
1049 if (!m_phacBuffer) m_phacBuffer = new QVector<double>;
1050 }
1051
1052
1055 if (!m_inacBuffer) m_inacBuffer = new QVector<double>;
1056 }
1057
1058
1061 if (!m_emacBuffer) m_emacBuffer = new QVector<double>;
1062 }
1063
1064
1065 QVector<double> *CameraBuffers::phaBuffer(int currentLine, int ns, int currentBand) {
1066 loadBuffers(currentLine, ns, currentBand);
1067 return m_phaBuffer;
1068 }
1069
1070
1071 QVector<double> *CameraBuffers::inaBuffer(int currentLine, int ns, int currentBand) {
1072 loadBuffers(currentLine, ns, currentBand);
1073 return m_inaBuffer;
1074 }
1075
1076
1077 QVector<double> *CameraBuffers::emaBuffer(int currentLine, int ns, int currentBand) {
1078 loadBuffers(currentLine, ns, currentBand);
1079 return m_emaBuffer;
1080 }
1081
1082
1083 QVector<double> *CameraBuffers::latBuffer(int currentLine, int ns, int currentBand) {
1084 loadBuffers(currentLine, ns, currentBand);
1085 return m_latBuffer;
1086 }
1087
1088
1089 QVector<double> *CameraBuffers::lonBuffer(int currentLine, int ns, int currentBand) {
1090 loadBuffers(currentLine, ns, currentBand);
1091 return m_lonBuffer;
1092 }
1093
1094
1095 QVector<double> *CameraBuffers::resBuffer(int currentLine, int ns, int currentBand) {
1096 loadBuffers(currentLine, ns, currentBand);
1097 return m_resBuffer;
1098 }
1099
1100
1101 QVector<double> *CameraBuffers::radiusBuffer(int currentLine, int ns, int currentBand) {
1102 loadBuffers(currentLine,ns,currentBand);
1103 return m_radiusBuffer;
1104 }
1105
1106
1107 QVector<double> *CameraBuffers::phalBuffer(int currentLine, int ns, int currentBand) {
1108 loadBuffers(currentLine, ns, currentBand);
1109 return m_phalBuffer;
1110 }
1111
1112
1113 QVector<double> *CameraBuffers::inalBuffer(int currentLine, int ns, int currentBand) {
1114 loadBuffers(currentLine, ns, currentBand);
1115 return m_inalBuffer;
1116 }
1117
1118
1119 QVector<double> *CameraBuffers::emalBuffer(int currentLine, int ns, int currentBand) {
1120 loadBuffers(currentLine, ns, currentBand);
1121 return m_emalBuffer;
1122 }
1123
1124
1125 QVector<double> *CameraBuffers::phacBuffer(int currentLine, int ns, int currentBand) {
1126 loadBuffers(currentLine, ns, currentBand);
1127 return m_phacBuffer;
1128 }
1129
1130
1131 QVector<double> *CameraBuffers::inacBuffer(int currentLine, int ns, int currentBand) {
1132 loadBuffers(currentLine, ns, currentBand);
1133 return m_inacBuffer;
1134 }
1135
1136
1137 QVector<double> *CameraBuffers::emacBuffer(int currentLine, int ns, int currentBand) {
1138 loadBuffers(currentLine, ns, currentBand);
1139 return m_emacBuffer;
1140 }
1141
1142
1143 void CameraBuffers::loadBuffers(int currentLine, int ns, int currentBand) {
1144 if (currentLine != m_lastLine) {
1145 m_lastLine = currentLine;
1146
1147 // Resize buffers if necessary
1148 if (m_phaBuffer) m_phaBuffer->resize(ns);
1149 if (m_inaBuffer) m_inaBuffer->resize(ns);
1150 if (m_emaBuffer) m_emaBuffer->resize(ns);
1151 if (m_latBuffer) m_latBuffer->resize(ns);
1152 if (m_lonBuffer) m_lonBuffer->resize(ns);
1153 if (m_resBuffer) m_resBuffer->resize(ns);
1154 if (m_radiusBuffer) m_radiusBuffer->resize(ns);
1155 if (m_phalBuffer) m_phalBuffer->resize(ns);
1156 if (m_inalBuffer) m_inalBuffer->resize(ns);
1157 if (m_emalBuffer) m_emalBuffer->resize(ns);
1158
1159 // Center angle buffers will only ever have one item, the center angle value
1160 if (m_phacBuffer) m_phacBuffer->resize(1);
1161 if (m_inacBuffer) m_inacBuffer->resize(1);
1162 if (m_emacBuffer) m_emacBuffer->resize(1);
1163
1164 m_camera->SetBand(currentBand);
1165
1167 QString tokenName; // used for exception
1168 double centerLine = m_camera->Lines() / 2.0 + 0.5;
1169 double centerSamp = m_camera->Samples() / 2.0 + 0.5;
1170
1171 if (m_camera->SetImage(centerSamp, centerLine)) {
1172 if (m_phacBuffer) {
1173 tokenName = "phac";
1174 (*m_phacBuffer)[0] = m_camera->PhaseAngle();
1175 }
1176 if (m_inacBuffer) {
1177 tokenName = "inac";
1178 (*m_inacBuffer)[0] = m_camera->IncidenceAngle();
1179 }
1180 if (m_emacBuffer) {
1181 tokenName = "emac";
1182 (*m_emacBuffer)[0] = m_camera->EmissionAngle();
1183 }
1184 }
1185 else {
1186 QString msg = "Unable to compute illumination angles at image center for operator ["
1187 + tokenName + "].";
1188 throw IException(IException::Unknown, msg, _FILEINFO_);
1189 }
1190 }
1191
1192 else {
1193 for (int i = 0; i < ns; i++) {
1194
1195 if (m_camera->SetImage(i + 1, currentLine)) {
1196 if (m_phaBuffer) (*m_phaBuffer)[i] = m_camera->PhaseAngle();
1197 if (m_inaBuffer) (*m_inaBuffer)[i] = m_camera->IncidenceAngle();
1198 if (m_emaBuffer) (*m_emaBuffer)[i] = m_camera->EmissionAngle();
1199 if (m_latBuffer) (*m_latBuffer)[i] = m_camera->UniversalLatitude();
1200 if (m_lonBuffer) (*m_lonBuffer)[i] = m_camera->UniversalLongitude();
1201 if (m_resBuffer) (*m_resBuffer)[i] = m_camera->PixelResolution();
1202 if (m_radiusBuffer) (*m_radiusBuffer)[i] = m_camera->LocalRadius().meters();
1204 Angle phal, inal, emal;
1205 bool okay;
1206 m_camera->LocalPhotometricAngles(phal, inal, emal, okay);
1207 if (okay) {
1208 if (m_phalBuffer) (*m_phalBuffer)[i] = phal.degrees();
1209 if (m_inalBuffer) (*m_inalBuffer)[i] = inal.degrees();
1210 if (m_emalBuffer) (*m_emalBuffer)[i] = emal.degrees();
1211 }
1212 else {
1213 if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
1214 if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
1215 if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;
1216 }
1217 }
1218 }
1219 else {
1220 if (m_phaBuffer) (*m_phaBuffer)[i] = NAN;
1221 if (m_inaBuffer) (*m_inaBuffer)[i] = NAN;
1222 if (m_emaBuffer) (*m_emaBuffer)[i] = NAN;
1223 if (m_latBuffer) (*m_latBuffer)[i] = NAN;
1224 if (m_lonBuffer) (*m_lonBuffer)[i] = NAN;
1225 if (m_resBuffer) (*m_resBuffer)[i] = NAN;
1226 if (m_radiusBuffer) (*m_radiusBuffer)[i] = NAN;
1227 if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
1228 if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
1229 if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;
1230 }
1231 }
1232 }
1233 }
1234 }
1235
1236} // End of namespace Isis
1237
Functor for reduce using average functionality.
Definition Reduce.h:107
Calculator for arrays.
Definition Calculator.h:55
void LessThan()
Pop two elements off the stack and compare them to see where one is less than the other,...
void Cosecant()
Pops one element and push the cosecant.
void Arctangent2()
Pops two elements and push the arctangent.
void Modulus()
Pops two elements, mods them, then pushes the result on the stack.
void Tangent()
Pops one element and push the tangent.
int StackSize()
Returns the current stack size.
void Arctangent()
Pops one element and push the arctangent.
void SineH()
Pops one element and push the hyperbolic sine.
void Divide()
Pops two, divides them, then pushes the quotient on the stack.
void GreaterThanOrEqual()
Pop two elements off the stack and compare them to see where one is greater than or equal to the othe...
void TangentH()
Pops one element and push the hyperbolic tangent.
void Push(double scalar)
Push a scalar onto the stack.
void Cotangent()
Pops one element and push the cotangent.
void Add()
Pops two elements, adds them, then pushes the sum on the stack.
void Multiply()
Pops two elements, multiplies them, then pushes the product on the stack.
void Negative()
Pops an element, negates it, then pushes the result.
void RightShift()
Pop the top element, then perform a right shift with zero fill.
void Sine()
Pops one element and push the sine.
virtual void Clear()
Clear out the stack.
void Arcsine()
Pops one element and push the arcsine.
void LeftShift()
Pop the top element, then perform a left shift with zero fill.
void LessThanOrEqual()
Pop two elements off the stack and compare them to see where one is less than or equal to the other,...
void NotEqual()
Pop two elements off the stack and compare them to see where one is not equal to the other,...
void GreaterThan()
Pop two elements off the stack and compare them to see where one is greater than the other,...
void Arccosine()
Pops one element and push the arccosine.
void Log10()
Pop an element, compute its base 10 log, then push the result on the stack.
void MaximumLine()
Pop one element, then push the maximum on the stack.
void MaximumPixel()
Pop two elements, then push the maximum on a pixel by pixel basis back on the stack.
void Secant()
Pops one element and push the secant.
void MinimumLine()
Pop one element, then push the minimum on the stack.
void Log()
Pop an element, compute its log, then push the result on the stack.
void Subtract()
Pops two elements, subtracts them, then pushes the difference on the stack.
void Equal()
Pop two elements off the stack and compare them to see where one is equal to the other,...
QVector< double > Pop(bool keepSpecials=false)
Pop an element off the stack.
void AbsoluteValue()
Pop an element, compute its absolute value, then push the result on the stack.
void MinimumPixel()
Pop two elements, then push the minimum on a pixel by pixel basis back on the stack.
void Exponent()
Pops two elements, computes the power then pushes the result on the stack The exponent has to be a sc...
void SquareRoot()
Pop an element, compute its square root, then push the root on the stack.
void Cosine()
Pops one element and push the cosine.
void CosineH()
Pops one element and push the hyperbolic cosine.
This class is used to manage buffers for calculating camera related information, such as angles,...
QVector< double > * m_phacBuffer
Center phase angle buffer.
void enableLonBuffer()
Enables the longitude buffer for use.
void enableLatBuffer()
Enables the latitude buffer for use.
void enablePhalBuffer()
Enables the local phase angle buffer for use.
void enableResBuffer()
Enables the resolution buffer for use.
void enablePhaBuffer()
Enables the phase angle buffer for use.
void enableRadiusBuffer()
Enables the radius buffer for use.
CameraBuffers(Camera *camera)
Constructs a CameraBuffers object.
QVector< double > * m_inaBuffer
Incidence angle buffer.
QVector< double > * m_inalBuffer
Local incidence angle buffer.
QVector< double > * m_emacBuffer
Center emission angle buffer.
QVector< double > * m_emalBuffer
Local emission angle buffer.
void enableInalBuffer()
Enables the local incidence angle buffer for use.
int m_lastLine
The number of the last line loaded into the enabled camera buffers.
QVector< double > * m_inacBuffer
Center incidence angle buffer.
QVector< double > * m_phaBuffer
Phase angle buffer.
void enableInaBuffer()
Enables the incidence angle buffer for use.
void enableEmalBuffer()
Enables the local emission angle buffer for use.
Camera * m_camera
Camera to obtain camera-related information from.
QVector< double > * m_latBuffer
Latitude buffer.
QVector< double > * m_emaBuffer
Emission angle buffer.
QVector< double > * m_phalBuffer
Local phase angle buffer.
QVector< double > * m_radiusBuffer
Radius buffer.
~CameraBuffers()
Destroys the CameraBuffers.
void enableEmacBuffer()
Enables the center emission angle buffer for use.
void enableInacBuffer()
Enables the center incidence angle buffer for use.
void enableEmaBuffer()
Enables the emission angle buffer for use.
QVector< double > * m_resBuffer
Resolution buffer.
QVector< double > * m_lonBuffer
Longitude buffer.
void enablePhacBuffer()
Enables the center phase angle buffer for use.
int Lines() const
Returns the number of lines in the image.
Definition Camera.cpp:2816
virtual double PixelResolution()
Returns the pixel resolution at the current position in meters/pixel.
Definition Camera.cpp:681
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition Camera.cpp:156
void LocalPhotometricAngles(Angle &phase, Angle &incidence, Angle &emission, bool &success)
Calculates LOCAL photometric angles using the DEM (not ellipsoid).
Definition Camera.cpp:1653
int Samples() const
Returns the number of samples in the image.
Definition Camera.cpp:2806
virtual void SetBand(const int band)
Virtual method that sets the band number.
Definition Camera.cpp:2710
int lastPushToCubeCameras(QVector< Cube * > &inCubes)
Creates internal camera for the last pushed cube data.
int m_outputSamples
Number of samples in the output cube.
void addMethodCall(void(Calculator::*method)(void))
This is a conveinience method for PrepareCalculations(...).
~CubeCalculator()
Destroys the CubeCalculator object.
int lastPushToCubeStats(QVector< Cube * > &inCubes)
Creates statistics internally for the last cube data pushed to the data definitions.
CubeCalculator()
Constructs a CubeCalculator.
QVector< Camera * > * m_cubeCameras
Stores the cameras for the input cubes.
@ CallNextMethod
The calculation requires calling one of the methods.
@ PushNextData
The calculation requires input data.
QVector< void(Calculator::*)(void)> * m_methods
This stores the addresses to the methods RunCalculations(...) will call.
void Clear()
This method completely resets the calculator.
QVector< double > runCalculations(QVector< Buffer * > &cubeData, int line, int band)
This method will execute the calculations built up when PrepareCalculations was called.
QVector< Calculations > * m_calculations
This is what RunCalculations(...) will loop over.
QVector< CameraBuffers * > * m_cameraBuffers
Stores the camera buffers that are enabled for camera related calculations.
void prepareCalculations(QString equation, QVector< Cube * > &inCubes, Cube *outCube)
This method builds a list of actions to perform based on the postfix expression.
QVector< DataValue > * m_dataDefinitions
This defines what kind of data RunCalculations(...) will push onto the calculator.
QVector< Statistics * > * m_cubeStats
Stores the cube statistics for the input cubes.
IO Handler for Isis Cubes.
Definition Cube.h:168
This class is used to define what kind of data is being pushed onto the cube calculator.
int cubeIndex()
Accesses the cube index of the DataValue.
double constant()
Accesses the constant value of the DataValue.
DataValue()
Constructs a default DataValue.
int m_cubeIndex
The index of the associated cube.
double m_constantValue
Stored constant value.
DataValueType
This is used to tell what kind of data to push onto the RPN calculator.
@ InaData
Incidence camera data.
@ PhacData
Center phase camera data.
@ EmalData
Local emission camera data.
@ PhaData
Phase camera data.
@ InalData
Local incidence camera data.
@ EmaData
Emission camera data.
@ LatData
Latitude camera data.
@ Sample
Current sample number.
@ Band
Current band number.
@ ResData
Pixel resolution camera data.
@ Constant
A single constant value.
@ InacData
Center incidence camera data.
@ PhalData
Local phase camera data.
@ Line
Current line number.
@ RadiusData
DEM radius.
@ LonData
Longitude camera data.
@ CubeData
A brick of cube data.
@ EmacData
Center emission camera data.
DataValueType m_type
Type of data stored.
DataValueType type()
Accesses the type of the DataValue.
double meters() const
Get the distance in meters.
Definition Distance.cpp:85
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
Adds specific functionality to C++ strings.
Definition IString.h:165
IString Token(const IString &separator)
Returns the first token in the IString.
Definition IString.cpp:897
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition Sensor.cpp:212
virtual double PhaseAngle() const
Returns the phase angle in degrees.
Definition Sensor.cpp:314
virtual double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition Sensor.cpp:339
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition Sensor.cpp:235
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition Sensor.cpp:269
virtual double EmissionAngle() const
Returns the emission angle in degrees.
Definition Sensor.cpp:328
const double E
Sets some basic constants for use in ISIS programming.
Definition Constants.h:39
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.