From 84db83adc6a0f536f49cf9e9e514dc92446c4002 Mon Sep 17 00:00:00 2001
From: Jesse Mapel <jmapel@usgs.gov>
Date: Fri, 10 Apr 2020 16:02:03 -0700
Subject: [PATCH] Made States use NaNs if it doesn't have velocity (#349)

* Made States use NaNs if it doesn't have velocity

* Switched to ors
---
 include/ale/States.h         | 11 +++++++++++
 src/States.cpp               | 10 ++++------
 tests/ctests/IsdTests.cpp    | 14 ++++----------
 tests/ctests/StatesTests.cpp |  7 +------
 4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/include/ale/States.h b/include/ale/States.h
index c4e5e81..ffcf5b5 100644
--- a/include/ale/States.h
+++ b/include/ale/States.h
@@ -1,6 +1,8 @@
 #ifndef ALE_STATES_H
 #define ALE_STATES_H
 
+#include <cmath>
+#include <limits>
 #include <vector>
 #include <stdexcept>
 
@@ -23,8 +25,17 @@ namespace ale {
       velocity = {vec[3], vec[4], vec[5]};
     };
 
+    State(Vec3d position) : position(position) {
+      velocity = {std::numeric_limits<double>::quiet_NaN(),
+                  std::numeric_limits<double>::quiet_NaN(),
+                  std::numeric_limits<double>::quiet_NaN()};
+    };
     State(Vec3d position, Vec3d velocity) : position(position), velocity(velocity) {};
     State() {};
+
+    bool hasVelocity() const {
+      return !(std::isnan(velocity.x) || std::isnan(velocity.y) || std::isnan(velocity.z));
+    }
   };
 
   class States {
diff --git a/src/States.cpp b/src/States.cpp
index a059780..f5b6e5a 100644
--- a/src/States.cpp
+++ b/src/States.cpp
@@ -23,9 +23,8 @@ namespace ale {
       throw std::invalid_argument("Length of times must match number of positions");
     }
 
-    Vec3d velocities = {0.0, 0.0, 0.0};
     for (Vec3d position : positions) {
-      m_states.push_back(State(position, velocities));
+      m_states.push_back(State(position));
     }
   }
 
@@ -93,10 +92,9 @@ namespace ale {
 
 
   bool States::hasVelocity() const {
-    std::vector<Vec3d> velocities = getVelocities();
-    bool allZero = std::all_of(velocities.begin(), velocities.end(), [](Vec3d vec)
-                               { return vec.x==0.0 && vec.y==0.0 && vec.z==0.0; });
-    return !allZero;
+    bool allVelocity = std::all_of(m_states.begin(), m_states.end(), [](State vec)
+                                   { return vec.hasVelocity(); });
+    return allVelocity;
   }
 
 
diff --git a/tests/ctests/IsdTests.cpp b/tests/ctests/IsdTests.cpp
index b0dee7b..5c001bf 100644
--- a/tests/ctests/IsdTests.cpp
+++ b/tests/ctests/IsdTests.cpp
@@ -158,7 +158,6 @@ TEST(Isd, GetSunPositions) {
 
   ale::States sunPosObj = ale::getSunPosition(jsunpos);
   std::vector<ale::Vec3d> position = sunPosObj.getPositions();
-  std::vector<ale::Vec3d> velocity = sunPosObj.getVelocities();
 
   ASSERT_EQ(sunPosObj.getStates().size(), 1);
   ASSERT_EQ(sunPosObj.getReferenceFrame(), 2);
@@ -168,14 +167,12 @@ TEST(Isd, GetSunPositions) {
   ASSERT_EQ(position[0].y, 12);
   ASSERT_EQ(position[0].z, 13);
 
-  ASSERT_EQ(velocity[0].x, 0);
-  ASSERT_EQ(velocity[0].y, 0);
-  ASSERT_EQ(velocity[0].z, 0);
+  ASSERT_FALSE(sunPosObj.hasVelocity());
 
   jsunpos["sun_position"]["velocities"] = {{1, 2, 3}};
 
   sunPosObj = ale::getSunPosition(jsunpos);
-  velocity = sunPosObj.getVelocities();
+  std::vector<ale::Vec3d> velocity = sunPosObj.getVelocities();
 
   ASSERT_EQ(velocity[0].x, 1);
   ASSERT_EQ(velocity[0].y, 2);
@@ -206,7 +203,6 @@ TEST(Isd, GetInstrumentPositions) {
 
   ale::States instPosObj = ale::getInstrumentPosition(jinstpos);
   std::vector<ale::Vec3d> positions = instPosObj.getPositions();
-  std::vector<ale::Vec3d> velocities = instPosObj.getVelocities();
 
   ASSERT_EQ(instPosObj.getStates().size(), 2);
   ASSERT_EQ(instPosObj.getReferenceFrame(), 4);
@@ -222,14 +218,12 @@ TEST(Isd, GetInstrumentPositions) {
   ASSERT_EQ(positions[1].y, 12);
   ASSERT_EQ(positions[1].z, 13);
 
-  ASSERT_EQ(velocities[0].x, 0);
-  ASSERT_EQ(velocities[0].y, 0);
-  ASSERT_EQ(velocities[0].z, 0);
+  ASSERT_FALSE(instPosObj.hasVelocity());
 
   jinstpos["instrument_position"]["velocities"] = {{0, 1, 2}, {3, 4, 5}};
 
   instPosObj = ale::getInstrumentPosition(jinstpos);
-  velocities = instPosObj.getVelocities();
+  std::vector<ale::Vec3d> velocities = instPosObj.getVelocities();
 
   ASSERT_EQ(velocities[0].x, 0);
   ASSERT_EQ(velocities[0].y, 1);
diff --git a/tests/ctests/StatesTests.cpp b/tests/ctests/StatesTests.cpp
index 25ca539..59a6161 100644
--- a/tests/ctests/StatesTests.cpp
+++ b/tests/ctests/StatesTests.cpp
@@ -29,15 +29,10 @@ TEST(StatesTest, ConstructorPositionNoVelocity) {
   EXPECT_NEAR(states[0].position.x, 4.0, 1e-10);
   EXPECT_NEAR(states[0].position.y, 1.0, 1e-10);
   EXPECT_NEAR(states[0].position.z, 4.0, 1e-10);
-  EXPECT_NEAR(states[0].velocity.x, 0.0, 1e-10);
-  EXPECT_NEAR(states[0].velocity.y, 0.0, 1e-10);
-  EXPECT_NEAR(states[0].velocity.z, 0.0, 1e-10);
   EXPECT_NEAR(states[3].position.x, 7.0, 1e-10);
   EXPECT_NEAR(states[3].position.y, 4.0, 1e-10);
   EXPECT_NEAR(states[3].position.z, 1.0, 1e-10);
-  EXPECT_NEAR(states[3].velocity.x, 0.0, 1e-10);
-  EXPECT_NEAR(states[3].velocity.y, 0.0, 1e-10);
-  EXPECT_NEAR(states[3].velocity.z, 0.0, 1e-10);
+  EXPECT_FALSE(noVelocityState.hasVelocity());
 }
 
 TEST(StatesTest, ConstructorPositionAndVelocity) {
-- 
GitLab