37 CubeCalculator::CubeCalculator() {
38 m_calculations = NULL;
42 m_dataDefinitions = NULL;
45 m_cameraBuffers = NULL;
61 CubeCalculator::~CubeCalculator() {
62 delete m_calculations;
64 delete m_dataDefinitions;
67 delete m_cameraBuffers;
69 m_calculations = NULL;
71 m_dataDefinitions = NULL;
74 m_cameraBuffers = NULL;
78 void CubeCalculator::Clear() {
82 m_calculations->clear();
93 if (m_dataDefinitions) {
94 m_dataDefinitions->clear();
99 for (
int i = 0; i < m_cubeStats->size(); i++) {
100 delete (*m_cubeStats)[i];
101 (*m_cubeStats)[i] = NULL;
103 m_cubeStats->clear();
107 m_cubeCameras->clear();
111 if (m_cameraBuffers) {
112 for (
int i = 0; i < m_cameraBuffers->size(); i++) {
113 delete (*m_cameraBuffers)[i];
114 (*m_cameraBuffers)[i] = NULL;
116 m_cameraBuffers->clear();
138 for (
int currentCalculation = 0; currentCalculation < m_calculations->size();
139 currentCalculation++) {
140 if ((*m_calculations)[currentCalculation] == CallNextMethod) {
141 void (
Calculator::*aMethod)() = (*m_methods)[methodIndex];
146 DataValue &data = (*m_dataDefinitions)[dataIndex];
147 if (data.getType() == DataValue::Constant) {
148 Push(data.getConstant());
150 else if (data.getType() == DataValue::Band) {
153 else if (data.getType() == DataValue::Line) {
156 else if (data.getType() == DataValue::Sample) {
158 samples.resize(m_outputSamples);
160 for (
int i = 0; i < m_outputSamples; i++) {
166 else if (data.getType() == DataValue::CubeData) {
167 Push(*cubeData[data.getCubeIndex()]);
169 else if (data.getType() == DataValue::InaData) {
170 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getInaBuffer(curLine,m_outputSamples)));
172 else if (data.getType() == DataValue::EmaData) {
173 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getEmaBuffer(curLine,m_outputSamples)));
175 else if (data.getType() == DataValue::PhaData) {
176 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getPhaBuffer(curLine,m_outputSamples)));
178 else if (data.getType() == DataValue::InalData) {
179 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getInalBuffer(curLine,m_outputSamples)));
181 else if (data.getType() == DataValue::EmalData) {
182 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getEmalBuffer(curLine,m_outputSamples)));
184 else if (data.getType() == DataValue::PhalData) {
185 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getPhalBuffer(curLine,m_outputSamples)));
187 else if (data.getType() == DataValue::LatData) {
188 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getLatBuffer(curLine,m_outputSamples)));
190 else if (data.getType() == DataValue::LonData) {
191 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getLonBuffer(curLine,m_outputSamples)));
193 else if (data.getType() == DataValue::ResData) {
194 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getResBuffer(curLine,m_outputSamples)));
196 else if (data.getType() == DataValue::RadiusData) {
197 Push(*((*m_cameraBuffers)[data.getCubeIndex()]->getRadiusBuffer(curLine,m_outputSamples)));
206 if (StackSize() != 1) {
207 string msg =
"Too many operands in the equation.";
226 void CubeCalculator::prepareCalculations(QString equation,
242 if (isdigit(token[0]) || token[0] ==
'.') {
243 m_calculations->push_back(PushNextData);
244 m_dataDefinitions->push_back(
DataValue(DataValue::Constant,
249 else if (token[0] ==
'f') {
252 if (file < 0 || file >= (
int)inCubes.size()) {
253 QString msg =
"Invalid file number [" + tok.ToQt() +
"]";
257 m_calculations->push_back(PushNextData);
258 m_dataDefinitions->push_back(
DataValue(DataValue::CubeData, file));
260 else if (token ==
"band") {
261 m_calculations->push_back(PushNextData);
262 m_dataDefinitions->push_back(
DataValue(DataValue::Band));
264 else if (token ==
"line") {
265 m_calculations->push_back(PushNextData);
266 m_dataDefinitions->push_back(
DataValue(DataValue::Line));
268 else if (token ==
"sample") {
269 m_calculations->push_back(PushNextData);
270 m_dataDefinitions->push_back(
DataValue(DataValue::Sample));
273 else if (token ==
"+") {
274 addMethodCall(&Calculator::Add);
278 else if (token ==
"-") {
279 addMethodCall(&Calculator::Subtract);
283 else if (token ==
"*") {
284 addMethodCall(&Calculator::Multiply);
288 else if (token ==
"/") {
289 addMethodCall(&Calculator::Divide);
293 else if (token ==
"%") {
294 addMethodCall(&Calculator::Modulus);
298 else if (token ==
"^") {
299 addMethodCall(&Calculator::Exponent);
303 else if (token ==
"--") {
304 addMethodCall(&Calculator::Negative);
308 else if (token ==
"neg") {
309 addMethodCall(&Calculator::Negative);
313 else if (token ==
"<<") {
314 addMethodCall(&Calculator::LeftShift);
318 else if (token ==
">>") {
319 addMethodCall(&Calculator::RightShift);
323 else if (token ==
"linemax") {
324 addMethodCall(&Calculator::MaximumLine);
328 else if (token ==
"max") {
329 addMethodCall(&Calculator::MaximumPixel);
333 else if (token ==
"linemin") {
334 addMethodCall(&Calculator::MinimumLine);
338 else if (token ==
"min") {
339 addMethodCall(&Calculator::MinimumPixel);
343 else if (token ==
"abs") {
344 addMethodCall(&Calculator::AbsoluteValue);
348 else if (token ==
"sqrt") {
349 addMethodCall(&Calculator::SquareRoot);
353 else if (token ==
"log" || token ==
"ln") {
354 addMethodCall(&Calculator::Log);
358 else if (token ==
"log10") {
359 addMethodCall(&Calculator::Log10);
363 else if (token ==
"pi") {
364 m_calculations->push_back(PushNextData);
365 m_dataDefinitions->push_back(
371 else if (token ==
"e") {
372 m_calculations->push_back(PushNextData);
373 m_dataDefinitions->push_back(
378 else if (token ==
"rads") {
379 m_calculations->push_back(PushNextData);
380 m_dataDefinitions->push_back(
384 addMethodCall(&Calculator::Multiply);
387 else if (token ==
"degs") {
388 m_calculations->push_back(PushNextData);
389 m_dataDefinitions->push_back(
392 addMethodCall(&Calculator::Multiply);
396 else if (token ==
"sin") {
397 addMethodCall(&Calculator::Sine);
401 else if (token ==
"cos") {
402 addMethodCall(&Calculator::Cosine);
406 else if (token ==
"tan") {
407 addMethodCall(&Calculator::Tangent);
411 else if (token ==
"sec") {
412 addMethodCall(&Calculator::Secant);
416 else if (token ==
"csc") {
417 addMethodCall(&Calculator::Cosecant);
421 else if (token ==
"cot") {
422 addMethodCall(&Calculator::Cotangent);
426 else if (token ==
"asin") {
427 addMethodCall(&Calculator::Arcsine);
431 else if (token ==
"acos") {
432 addMethodCall(&Calculator::Arccosine);
436 else if (token ==
"atan") {
437 addMethodCall(&Calculator::Arctangent);
441 else if (token ==
"atan2") {
442 addMethodCall(&Calculator::Arctangent2);
446 else if (token ==
"sinh") {
447 addMethodCall(&Calculator::SineH);
451 else if (token ==
"cosh") {
452 addMethodCall(&Calculator::CosineH);
456 else if (token ==
"tanh") {
457 addMethodCall(&Calculator::TangentH);
461 else if (token ==
"<") {
462 addMethodCall(&Calculator::LessThan);
466 else if (token ==
">") {
467 addMethodCall(&Calculator::GreaterThan);
471 else if (token ==
"<=") {
472 addMethodCall(&Calculator::LessThanOrEqual);
476 else if (token ==
">=") {
477 addMethodCall(&Calculator::GreaterThanOrEqual);
481 else if (token ==
"==") {
482 addMethodCall(&Calculator::Equal);
486 else if (token ==
"!=") {
487 addMethodCall(&Calculator::NotEqual);
491 else if (token ==
"cubemax") {
492 int cubeIndex = lastPushToCubeStats(inCubes);
494 m_calculations->push_back(PushNextData);
495 m_dataDefinitions->push_back(
496 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Maximum())
502 else if (token ==
"cubemin") {
503 int cubeIndex = lastPushToCubeStats(inCubes);
505 m_calculations->push_back(PushNextData);
506 m_dataDefinitions->push_back(
507 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->Minimum())
513 else if (token ==
"cubeavg") {
514 int cubeIndex = lastPushToCubeStats(inCubes);
516 m_calculations->push_back(PushNextData);
517 m_dataDefinitions->push_back(
524 else if (token ==
"cubestd") {
525 int cubeIndex = lastPushToCubeStats(inCubes);
527 m_calculations->push_back(PushNextData);
528 m_dataDefinitions->push_back(
529 DataValue(DataValue::Constant, (*m_cubeStats)[cubeIndex]->StandardDeviation())
535 else if ((token ==
"phac") || (token ==
"inac") || (token ==
"emac")) {
536 int cubeIndex = lastPushToCubeCameras(inCubes);
538 double centerLine = inCubes[cubeIndex]->lineCount() / 2.0 + 0.5;
539 double centerSamp = inCubes[cubeIndex]->sampleCount() / 2.0 + 0.5;
540 Camera *cam = (*m_cubeCameras)[cubeIndex];
542 if (cam->
SetImage(centerSamp, centerLine)) {
543 m_calculations->push_back(PushNextData);
544 if (token ==
"inac") {
547 else if (token ==
"emac") {
555 string msg =
"Unable to compute illumination angles at image center for operator [";
556 msg += token +
"] using input file [f" +
IString(cubeIndex + 1) +
"]";
562 else if (token ==
"ina") {
563 int cubeIndex = lastPushToCubeCameras(inCubes);
564 (*m_cameraBuffers)[cubeIndex]->enableInaBuffer();
566 m_calculations->push_back(PushNextData);
567 m_dataDefinitions->push_back(
DataValue(DataValue::InaData, cubeIndex));
571 else if (token ==
"ema") {
572 int cubeIndex = lastPushToCubeCameras(inCubes);
573 (*m_cameraBuffers)[cubeIndex]->enableEmaBuffer();
575 m_calculations->push_back(PushNextData);
576 m_dataDefinitions->push_back(
DataValue(DataValue::EmaData, cubeIndex));
580 else if (token ==
"pha") {
581 int cubeIndex = lastPushToCubeCameras(inCubes);
582 (*m_cameraBuffers)[cubeIndex]->enablePhaBuffer();
584 m_calculations->push_back(PushNextData);
585 m_dataDefinitions->push_back(
DataValue(DataValue::PhaData, cubeIndex));
589 else if (token ==
"inal") {
590 int cubeIndex = lastPushToCubeCameras(inCubes);
591 (*m_cameraBuffers)[cubeIndex]->enableInalBuffer();
593 m_calculations->push_back(PushNextData);
594 m_dataDefinitions->push_back(
DataValue(DataValue::InalData, cubeIndex));
598 else if (token ==
"emal") {
599 int cubeIndex = lastPushToCubeCameras(inCubes);
600 (*m_cameraBuffers)[cubeIndex]->enableEmalBuffer();
602 m_calculations->push_back(PushNextData);
603 m_dataDefinitions->push_back(
DataValue(DataValue::EmalData, cubeIndex));
607 else if (token ==
"phal") {
608 int cubeIndex = lastPushToCubeCameras(inCubes);
609 (*m_cameraBuffers)[cubeIndex]->enablePhalBuffer();
611 m_calculations->push_back(PushNextData);
612 m_dataDefinitions->push_back(
DataValue(DataValue::PhalData, cubeIndex));
616 else if (token ==
"lat") {
617 int cubeIndex = lastPushToCubeCameras(inCubes);
618 (*m_cameraBuffers)[cubeIndex]->enableLatBuffer();
620 m_calculations->push_back(PushNextData);
621 m_dataDefinitions->push_back(
DataValue(DataValue::LatData, cubeIndex));
625 else if (token ==
"lon") {
626 int cubeIndex = lastPushToCubeCameras(inCubes);
627 (*m_cameraBuffers)[cubeIndex]->enableLonBuffer();
629 m_calculations->push_back(PushNextData);
630 m_dataDefinitions->push_back(
DataValue(DataValue::LonData, cubeIndex));
634 else if (token ==
"res") {
635 int cubeIndex = lastPushToCubeCameras(inCubes);
636 (*m_cameraBuffers)[cubeIndex]->enableResBuffer();
638 m_calculations->push_back(PushNextData);
639 m_dataDefinitions->push_back(
DataValue(DataValue::ResData, cubeIndex));
643 else if (token ==
"radius") {
644 int cubeIndex = lastPushToCubeCameras(inCubes);
645 (*m_cameraBuffers)[cubeIndex]->enableRadiusBuffer();
647 m_calculations->push_back(PushNextData);
648 m_dataDefinitions->push_back(
DataValue(DataValue::RadiusData, cubeIndex));
652 else if (token ==
"") {
656 string msg =
"Unidentified operator [";
664 if (!m_calculations->size()) {
665 string msg =
"Not sure which file to get statistics from";
669 if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
670 string msg =
"This function must not contain calculations,";
671 msg +=
" only input cubes may be specified.";
672 throw IException(IException::Unknown, msg,
_FILEINFO_);
675 m_calculations->pop_back();
678 DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
680 if (lastData.getType() != DataValue::CubeData) {
681 string msg =
"This function must not contain constants,";
682 msg +=
" only input cubes may be specified.";
683 throw IException(IException::Unknown, msg,
_FILEINFO_);
686 int cubeStatsIndex = lastData.getCubeIndex();
687 m_dataDefinitions->pop_back();
692 while (m_cubeStats->size() < cubeStatsIndex + 1) {
693 m_cubeStats->push_back(NULL);
698 if ((*m_cubeStats)[cubeStatsIndex] == NULL) {
699 (*m_cubeStats)[cubeStatsIndex] = inCubes[cubeStatsIndex]->statistics();
702 return cubeStatsIndex;
707 if (!m_calculations->size()) {
708 string msg =
"Not sure which file to get cameras from";
709 throw IException(IException::Unknown, msg,
_FILEINFO_);
712 if ((*m_calculations)[m_calculations->size() - 1] != PushNextData) {
713 string msg =
"This function must not contain calculations,";
714 msg +=
" only input cubes may be specified.";
715 throw IException(IException::Unknown, msg,
_FILEINFO_);
718 m_calculations->pop_back();
721 DataValue lastData = (*m_dataDefinitions)[m_dataDefinitions->size() - 1];
723 if (lastData.getType() != DataValue::CubeData) {
724 string msg =
"This function must not contain constants,";
725 msg +=
" only input cubes may be specified.";
726 throw IException(IException::Unknown, msg,
_FILEINFO_);
729 int cubeIndex = lastData.getCubeIndex();
730 m_dataDefinitions->pop_back();
735 while (m_cubeCameras->size() < cubeIndex + 1) {
736 m_cubeCameras->push_back(NULL);
739 while (m_cameraBuffers->size() < cubeIndex + 1) {
740 m_cameraBuffers->push_back(NULL);
745 if ((*m_cubeCameras)[cubeIndex] == NULL) {
748 cam = inCubes[cubeIndex]->camera();
750 string msg =
"This function requires a camera and the input cube does";
751 msg +=
" not have one. You may need to run spiceinit";
752 throw IException(IException::Unknown, msg,
_FILEINFO_);
755 catch (IException &e) {
756 string msg =
"This function requires a camera and the input cube does";
757 msg +=
" not have one. You may need to run spiceinit";
758 throw IException(e, IException::Unknown, msg,
_FILEINFO_);
761 (*m_cubeCameras)[cubeIndex] = cam;
762 (*m_cameraBuffers)[cubeIndex] =
new CameraBuffers(cam);
775 void CubeCalculator::addMethodCall(
void (
Calculator::*method)(
void)) {
776 m_calculations->push_back(CallNextMethod);
777 m_methods->push_back(method);
784 CameraBuffers::CameraBuffers(
Camera *camera) {
795 m_radiusBuffer = NULL;
800 CameraBuffers::~CameraBuffers() {
810 delete m_radiusBuffer;
821 m_radiusBuffer = NULL;
824 void CameraBuffers::enablePhaBuffer() {
828 void CameraBuffers::enableInaBuffer() {
832 void CameraBuffers::enableEmaBuffer() {
836 void CameraBuffers::enableLatBuffer() {
840 void CameraBuffers::enableLonBuffer() {
844 void CameraBuffers::enableResBuffer() {
848 void CameraBuffers::enableRadiusBuffer() {
852 void CameraBuffers::enablePhalBuffer() {
856 void CameraBuffers::enableInalBuffer() {
860 void CameraBuffers::enableEmalBuffer() {
864 QVector<double> *CameraBuffers::getPhaBuffer(
int currentLine,
int ns) {
865 loadBuffers(currentLine,ns);
869 QVector<double> *CameraBuffers::getInaBuffer(
int currentLine,
int ns) {
870 loadBuffers(currentLine,ns);
874 QVector<double> *CameraBuffers::getEmaBuffer(
int currentLine,
int ns) {
875 loadBuffers(currentLine,ns);
879 QVector<double> *CameraBuffers::getLatBuffer(
int currentLine,
int ns) {
880 loadBuffers(currentLine,ns);
884 QVector<double> *CameraBuffers::getLonBuffer(
int currentLine,
int ns) {
885 loadBuffers(currentLine,ns);
889 QVector<double> *CameraBuffers::getResBuffer(
int currentLine,
int ns) {
890 loadBuffers(currentLine,ns);
894 QVector<double> *CameraBuffers::getRadiusBuffer(
int currentLine,
int ns) {
895 loadBuffers(currentLine,ns);
896 return m_radiusBuffer;
899 QVector<double> *CameraBuffers::getPhalBuffer(
int currentLine,
int ns) {
900 loadBuffers(currentLine,ns);
904 QVector<double> *CameraBuffers::getInalBuffer(
int currentLine,
int ns) {
905 loadBuffers(currentLine,ns);
909 QVector<double> *CameraBuffers::getEmalBuffer(
int currentLine,
int ns) {
910 loadBuffers(currentLine,ns);
914 void CameraBuffers::loadBuffers(
int currentLine,
int ns) {
915 if (currentLine != m_lastLine) {
916 m_lastLine = currentLine;
919 if (m_phaBuffer) m_phaBuffer->resize(ns);
920 if (m_inaBuffer) m_inaBuffer->resize(ns);
921 if (m_emaBuffer) m_emaBuffer->resize(ns);
922 if (m_latBuffer) m_latBuffer->resize(ns);
923 if (m_lonBuffer) m_lonBuffer->resize(ns);
924 if (m_resBuffer) m_resBuffer->resize(ns);
925 if (m_radiusBuffer) m_radiusBuffer->resize(ns);
926 if (m_phalBuffer) m_phalBuffer->resize(ns);
927 if (m_inalBuffer) m_inalBuffer->resize(ns);
928 if (m_emalBuffer) m_emalBuffer->resize(ns);
930 for (
int i = 0; i < ns; i++) {
931 if (m_camera->SetImage(i + 1, currentLine)) {
932 if (m_phaBuffer) (*m_phaBuffer)[i] = m_camera->PhaseAngle();
933 if (m_inaBuffer) (*m_inaBuffer)[i] = m_camera->IncidenceAngle();
934 if (m_emaBuffer) (*m_emaBuffer)[i] = m_camera->EmissionAngle();
935 if (m_latBuffer) (*m_latBuffer)[i] = m_camera->UniversalLatitude();
936 if (m_lonBuffer) (*m_lonBuffer)[i] = m_camera->UniversalLongitude();
937 if (m_resBuffer) (*m_resBuffer)[i] = m_camera->PixelResolution();
938 if (m_radiusBuffer) (*m_radiusBuffer)[i] = m_camera->LocalRadius().meters();
939 if (m_phalBuffer || m_inalBuffer || m_emalBuffer) {
940 Angle phal, inal, emal;
942 m_camera->LocalPhotometricAngles(phal, inal, emal, okay);
944 if (m_phalBuffer) (*m_phalBuffer)[i] = phal.degrees();
945 if (m_inalBuffer) (*m_inalBuffer)[i] = inal.degrees();
946 if (m_emalBuffer) (*m_emalBuffer)[i] = emal.degrees();
949 if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
950 if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
951 if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;
956 if (m_phaBuffer) (*m_phaBuffer)[i] = NAN;
957 if (m_inaBuffer) (*m_inaBuffer)[i] = NAN;
958 if (m_emaBuffer) (*m_emaBuffer)[i] = NAN;
959 if (m_latBuffer) (*m_latBuffer)[i] = NAN;
960 if (m_lonBuffer) (*m_lonBuffer)[i] = NAN;
961 if (m_resBuffer) (*m_resBuffer)[i] = NAN;
962 if (m_radiusBuffer) (*m_radiusBuffer)[i] = NAN;
963 if (m_phalBuffer) (*m_phalBuffer)[i] = NAN;
964 if (m_inalBuffer) (*m_inalBuffer)[i] = NAN;
965 if (m_emalBuffer) (*m_emalBuffer)[i] = NAN;