From 66472ee1018fdba7346fd0207041b4eed98735ee Mon Sep 17 00:00:00 2001
From: mvanel <melina.vanel@csgroup.eu>
Date: Thu, 23 Mar 2023 11:18:06 +0100
Subject: [PATCH] Adding some functionalities to AbsoluteDateArrayHandling for
 pyrugged inverse optical location vectorisation

---
 .../utils/AbsoluteDateArrayHandling.java      | 111 ++++++++++++++++--
 .../AbsoluteDateForVectorisationTest.java     |  54 ++++++++-
 2 files changed, 151 insertions(+), 14 deletions(-)

diff --git a/src/main/java/org/orekit/rugged/utils/AbsoluteDateArrayHandling.java b/src/main/java/org/orekit/rugged/utils/AbsoluteDateArrayHandling.java
index b3be2f97..19785067 100644
--- a/src/main/java/org/orekit/rugged/utils/AbsoluteDateArrayHandling.java
+++ b/src/main/java/org/orekit/rugged/utils/AbsoluteDateArrayHandling.java
@@ -16,15 +16,18 @@
  */
 package org.orekit.rugged.utils;
 
+import org.hipparchus.exception.LocalizedCoreFormats;
+import org.orekit.errors.OrekitException;
 import org.orekit.time.AbsoluteDate;
 
-/** AbsoluteDateForVectorisation consist of additions to AbsoluteDate to handle arrays for vectorization
+/** AbsoluteDateForVectorisation consist of additions to AbsoluteDate to handle arrays for
+ * vectorization.
  * @author Melina Vanel
  */
 public class AbsoluteDateArrayHandling {
-    
-    /** Dates array on which we want to apply time shift or compute duration */
-    public AbsoluteDate[] dates;
+
+    /** Dates array on which we want to apply time shift or compute duration. */
+    private AbsoluteDate[] dates;
 
     /** Simple constructor.
      * @param dates is an array of absolute dates on which we want to apply time shift or
@@ -33,8 +36,23 @@ public class AbsoluteDateArrayHandling {
     public AbsoluteDateArrayHandling(final AbsoluteDate[] dates) {
         this.dates = dates.clone();
     }
-    
+
+    /** Get instance dates array.
+     * @return dates array
+     */
+    public AbsoluteDate[] getDates() {
+        return this.dates;
+    }
+
     /** Get time-shifted dates for several dates or several time shifts.
+     * If instance dates = [date1, date2, ..., daten] and argument
+     * dts = [dts1, dts2, ..., dtsn] then this function will return a matrix
+     * [[date1 shiftedby dts1, date1 shiftedBy dts2, ..., date1 shiftedBy dtsn],
+     * [date2 shiftedby dts1, date2 shiftedBy dts2, ..., date2 shiftedBy dtsn],
+     * [...]
+     * [daten shiftedby dts1, daten shiftedBy dts2, ..., date1 shiftedBy dtsn]].
+     * If ones want to apply only 1 time shift corresponding to 1 date see
+     * {@link #shiftedByCorrespondingTimeShift}.
      * @param dts time shifts array in seconds we want to apply to dates
      * @return a matrix of new dates, shifted with respect to wanted time
      * shifts. If instance dates = [date1, date2, ..., daten] each line
@@ -43,11 +61,11 @@ public class AbsoluteDateArrayHandling {
      */
     public AbsoluteDate[][] shiftedBySeveralTimeShift(final double[] dts) {
 
-        AbsoluteDate[][] datesShifted = new AbsoluteDate[dates.length][dts.length];
+        final AbsoluteDate[][] datesShifted = new AbsoluteDate[dates.length][dts.length];
         int index_dates = 0;
 
         for (AbsoluteDate date: this.dates) {
-            AbsoluteDate[] dateShifted = new AbsoluteDate[dts.length];
+            final AbsoluteDate[] dateShifted = new AbsoluteDate[dts.length];
             int index_dts = 0;
             for (double dt: dts) {
                 dateShifted[index_dts] = date.shiftedBy(dt);
@@ -60,23 +78,61 @@ public class AbsoluteDateArrayHandling {
         return (AbsoluteDate[][]) datesShifted;
     }
 
+    /** Get time-shifted dates for several dates and corresponding time shifts.
+     * If instance dates = [date1, date2, ..., daten] and argument
+     * dts = [dts1, dts2, ..., dtsn] then this function will return
+     * [date1 shiftedby dts1, date2 shiftedBy dts2, ..., daten shiftedBy dtsn]. If
+     * several time shift want to be applied on each date see
+     * {@link #shiftedBySeveralTimeShift}.
+     * @param dts time shifts array in seconds we want to apply to corresponding dates.
+     * Warning, must be same length as dates.
+     * @return an 1D array of new dates, shifted with respect to wanted corresponding time
+     * shifts.
+     */
+    public AbsoluteDate[] shiftedByCorrespondingTimeShift(final double[] dts) {
+
+        // Check same dimensions
+        if (dates.length != dts.length) {
+            throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
+                                      dates.length, dts.length);
+        }
+
+        final AbsoluteDate[] datesShifted = new AbsoluteDate[dates.length];
+        int index_dates = 0;
+
+        for (AbsoluteDate date: this.dates) {
+            datesShifted[index_dates] = date.shiftedBy(dts[index_dates]);
+            index_dates += 1;
+
+        }
+        return datesShifted;
+    }
+
     /** Get array with durations between instances dates and given dates
+     * If instance dates = [date1, date2, ..., daten] and argument
+     * datesForDuration = [d1, d2, ..., dn] then this function will return a matrix
+     * [[date1 durationFrom d1, date1 durationFrom d2, ..., date1 durationFrom dn],
+     * [date2 durationFrom d1, date2 durationFrom d2, ..., date2 durationFrom dn],
+     * [...]
+     * [daten durationFrom d1, daten durationFrom d2, ..., date1 durationFrom dn]].
+     * If ones want to compute duration from only 1 date corresponding to 1 instance date see
+     * {@link #durationsFromCorrespondingDates}.
      * @param datesForDuration dates for which we want to compute the duration form instances dates
-     * @return a matrix of double representing durations from instance dates 
+     * @return a matrix of double representing durations from instance dates
      * If instance dates = [date1, date2, ..., daten] each line
      * correspond to one date (for example date1 duration from all given dates in arguments
      * (building the different columns))
      */
-    public double[][] durationsFromSeveralTimeShifts(final AbsoluteDate[] datesForDuration) {
+    public double[][] durationsFromSeveralDates(final AbsoluteDate[] datesForDuration) {
 
-        double[][] durationsFromDates = new double[dates.length][datesForDuration.length];
+        final double[][] durationsFromDates = new double[dates.length][datesForDuration.length];
         int index_dates = 0;
 
         for (AbsoluteDate date: this.dates) {
-            double[] durationFromDate = new double[datesForDuration.length];
+            final double[] durationFromDate = new double[datesForDuration.length];
             int index_datesForDuration = 0;
             for (AbsoluteDate dateForDuration: datesForDuration) {
-            	durationFromDate[index_datesForDuration] = date.durationFrom(dateForDuration);
+                durationFromDate[index_datesForDuration] = date.durationFrom(dateForDuration);
                 index_datesForDuration += 1;
             }
             durationsFromDates[index_dates] = durationFromDate;
@@ -86,5 +142,34 @@ public class AbsoluteDateArrayHandling {
         return (double[][]) durationsFromDates;
     }
 
-    
+    /** Get array with durations between instances dates and corresponding given dates
+     * If instance dates = [date1, date2, ..., daten] and argument
+     * datesForDuration = [d1, d2, ..., dn] then this function will return
+     * [date1 durationFrom d1, date2 durationFrom d2, ..., daten durationFrom dn]. If
+     * duration from from all arguments dates wants to be compute on each date see
+     * {@link #durationsFromSeveralDates(AbsoluteDate[])}.
+     * @param datesForDuration dates for which we want to compute the duration form instances dates.
+     * Warning must have same length as instance dates.
+     * @return a arry of double representing durations between instance dates and corresponding
+     * argument dates
+     */
+    public double[] durationsFromCorrespondingDates(final AbsoluteDate[] datesForDuration) {
+
+        // Check same dimensions
+        if (dates.length != datesForDuration.length) {
+            throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
+                                      dates.length, datesForDuration.length);
+        }
+
+        final double[] durationsFromDates = new double[dates.length];
+        int index_dates = 0;
+
+        for (AbsoluteDate date: this.dates) {
+            durationsFromDates[index_dates] = date.durationFrom(datesForDuration[index_dates]);
+            index_dates += 1;
+
+        }
+        return durationsFromDates;
+    }
+
 }
diff --git a/src/test/java/org/orekit/rugged/utils/AbsoluteDateForVectorisationTest.java b/src/test/java/org/orekit/rugged/utils/AbsoluteDateForVectorisationTest.java
index 779cde50..34d225ee 100644
--- a/src/test/java/org/orekit/rugged/utils/AbsoluteDateForVectorisationTest.java
+++ b/src/test/java/org/orekit/rugged/utils/AbsoluteDateForVectorisationTest.java
@@ -17,8 +17,10 @@
 package org.orekit.rugged.utils;
 
 
+import org.hipparchus.exception.LocalizedCoreFormats;
 import org.junit.Assert;
 import org.junit.Test;
+import org.orekit.errors.OrekitException;
 import org.orekit.time.AbsoluteDate;
 
 public class AbsoluteDateForVectorisationTest {
@@ -33,6 +35,22 @@ public class AbsoluteDateForVectorisationTest {
 	    Assert.assertEquals(datesShifted[0][0].durationFrom(date1.shiftedBy(10)), 0.0, 1e-5);
 	    Assert.assertEquals(datesShifted[0][1].durationFrom(date1.shiftedBy(20)), 0.0, 1e-5);
 
+    }
+
+	@Test
+    public void testShiftedByCorrespondingTimeShift() {
+
+		AbsoluteDate date1 = new AbsoluteDate();
+		AbsoluteDate date2 = date1.shiftedBy(10000);
+		AbsoluteDate date3 = date1.shiftedBy(20000);
+        AbsoluteDate[] dates = new AbsoluteDate[] {date1, date2, date3};
+        double[] dts = new double[] {10.0, 20.0, 30.0};
+	    AbsoluteDateArrayHandling datesForVect = new AbsoluteDateArrayHandling(dates);
+	    AbsoluteDate[] datesShifted = datesForVect.shiftedByCorrespondingTimeShift(dts);
+	    Assert.assertEquals(datesShifted[0].durationFrom(date1.shiftedBy(10)), 0.0, 1e-5);
+	    Assert.assertEquals(datesShifted[1].durationFrom(date1.shiftedBy(10020)), 0.0, 1e-5);
+	    Assert.assertEquals(datesShifted[2].durationFrom(date1.shiftedBy(20030)), 0.0, 1e-5);
+
     }
 
 	@Test
@@ -61,7 +79,7 @@ public class AbsoluteDateForVectorisationTest {
         AbsoluteDate[] dates = new AbsoluteDate[] {date1, date2, date3};
         AbsoluteDate[] datesComputeDuration = new AbsoluteDate[] {date4, date1};
 	    AbsoluteDateArrayHandling datesForVect = new AbsoluteDateArrayHandling(dates);
-	    double[][] datesDurations = datesForVect.durationsFromSeveralTimeShifts(datesComputeDuration);
+	    double[][] datesDurations = datesForVect.durationsFromSeveralDates(datesComputeDuration);
 	    Assert.assertEquals(datesDurations[0][0], date1.durationFrom(date4), 1e-5);
 	    Assert.assertEquals(datesDurations[0][1], date1.durationFrom(date1), 1e-5);
 	    Assert.assertEquals(datesDurations[1][0], date2.durationFrom(date4), 1e-5);
@@ -71,5 +89,39 @@ public class AbsoluteDateForVectorisationTest {
 
     }
 
+	@Test
+    public void testDurationFromCorrespondingDates() {
+
+		AbsoluteDate date1 = new AbsoluteDate();
+		AbsoluteDate date2 = date1.shiftedBy(10000);
+		AbsoluteDate date3 = date1.shiftedBy(20000);
+		AbsoluteDate date4 = date1.shiftedBy(100000);
+        AbsoluteDate[] dates = new AbsoluteDate[] {date1, date2, date3};
+        AbsoluteDate[] datesComputeDuration = new AbsoluteDate[] {date4, date1, date2};
+	    AbsoluteDateArrayHandling datesForVect = new AbsoluteDateArrayHandling(dates);
+	    double[] datesDurations = datesForVect.durationsFromCorrespondingDates(datesComputeDuration);
+	    Assert.assertEquals(datesDurations[0], date1.durationFrom(date4), 1e-5);
+	    Assert.assertEquals(datesDurations[1], date2.durationFrom(date1), 1e-5);
+	    Assert.assertEquals(datesDurations[2], date3.durationFrom(date2), 1e-5);
+
+    }
+
+	@Test
+    public void testExceptionDimensions() {
+
+		AbsoluteDate date1 = new AbsoluteDate();
+		AbsoluteDate date2 = date1.shiftedBy(10000);
+		AbsoluteDate date3 = date1.shiftedBy(20000);
+		AbsoluteDate date4 = date1.shiftedBy(100000);
+        AbsoluteDate[] dates = new AbsoluteDate[] {date1, date2, date3};
+        AbsoluteDate[] datesComputeDuration = new AbsoluteDate[] {date4, date1};
+	    AbsoluteDateArrayHandling datesForVect = new AbsoluteDateArrayHandling(dates);
+	    try {
+	    	datesForVect.durationsFromCorrespondingDates(datesComputeDuration);
+	    	Assert.fail("an exception should have been thrown");
+        } catch (OrekitException oe) {
+        	Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, oe.getSpecifier());
+        }
+    }
 
 }
-- 
GitLab