1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.propagation.events;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
21  import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
22  import org.junit.jupiter.api.AfterEach;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.BeforeEach;
25  import org.junit.jupiter.api.Test;
26  import org.orekit.Utils;
27  import org.orekit.bodies.CelestialBodyFactory;
28  import org.orekit.bodies.OneAxisEllipsoid;
29  import org.orekit.errors.OrekitException;
30  import org.orekit.frames.FramesFactory;
31  import org.orekit.orbits.EquinoctialOrbit;
32  import org.orekit.orbits.Orbit;
33  import org.orekit.propagation.SpacecraftState;
34  import org.orekit.propagation.events.handlers.CountAndContinue;
35  import org.orekit.propagation.numerical.NumericalPropagator;
36  import org.orekit.time.AbsoluteDate;
37  import org.orekit.time.TimeScalesFactory;
38  import org.orekit.utils.IERSConventions;
39  import org.orekit.utils.PVCoordinates;
40  
41  import java.util.List;
42  
43  public class EventsLoggerTest {
44  
45      private double               mu;
46      private AbsoluteDate         iniDate;
47      private SpacecraftState      initialState;
48      private NumericalPropagator  propagator;
49      private CountAndContinue countAndContinue;
50      private AbstractDetector<EclipseDetector>        umbraDetector;
51      private AbstractDetector<EclipseDetector>         penumbraDetector;
52  
53      @Test
54      public void testLogUmbra() {
55          EventsLogger logger = new EventsLogger();
56          EventDetector monitored = logger.monitorDetector(umbraDetector.withMaxIter(200));
57          Assertions.assertEquals(100, umbraDetector.getMaxIterationCount());
58          Assertions.assertEquals(200, monitored.getMaxIterationCount());
59          propagator.addEventDetector(monitored);
60          propagator.addEventDetector(penumbraDetector);
61          countAndContinue.reset();
62          propagator.propagate(iniDate.shiftedBy(16215)).getDate();
63          Assertions.assertEquals(11, countAndContinue.getCount());
64          checkCounts(logger, 3, 3, 0, 0);
65      }
66  
67      @Test
68      public void testLogPenumbra() {
69          EventsLogger logger = new EventsLogger();
70          propagator.addEventDetector(umbraDetector);
71          propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
72          countAndContinue.reset();
73          propagator.propagate(iniDate.shiftedBy(16215)).getDate();
74          Assertions.assertEquals(11, countAndContinue.getCount());
75          checkCounts(logger, 0, 0, 2, 3);
76      }
77  
78      @Test
79      public void testLogAll() {
80          EventsLogger logger = new EventsLogger();
81          propagator.addEventDetector(logger.monitorDetector(umbraDetector));
82          propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
83          countAndContinue.reset();
84          propagator.propagate(iniDate.shiftedBy(16215));
85          Assertions.assertEquals(11, countAndContinue.getCount());
86          checkCounts(logger, 3, 3, 2, 3);
87      }
88  
89      @Test
90      public void testImmutableList() {
91          EventsLogger logger = new EventsLogger();
92          propagator.addEventDetector(logger.monitorDetector(umbraDetector));
93          propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
94          countAndContinue.reset();
95          propagator.propagate(iniDate.shiftedBy(16215));
96          List<EventsLogger.LoggedEvent> firstList = logger.getLoggedEvents();
97          Assertions.assertEquals(11, firstList.size());
98          propagator.propagate(iniDate.shiftedBy(30000));
99          List<EventsLogger.LoggedEvent> secondList = logger.getLoggedEvents();
100         Assertions.assertEquals(11, firstList.size());
101         Assertions.assertEquals(20, secondList.size());
102         for (int i = 0; i < firstList.size(); ++i) {
103 
104             EventsLogger.LoggedEvent e1 = firstList.get(i);
105             EventsLogger.LoggedEvent e2 = secondList.get(i);
106             PVCoordinates pv1 = e1.getState().getPVCoordinates();
107             PVCoordinates pv2 = e2.getState().getPVCoordinates();
108 
109             Assertions.assertTrue(e1.getEventDetector() == e2.getEventDetector());
110             Assertions.assertEquals(0, pv1.getPosition().subtract(pv2.getPosition()).getNorm(), 1.0e-10);
111             Assertions.assertEquals(0, pv1.getVelocity().subtract(pv2.getVelocity()).getNorm(), 1.0e-10);
112             Assertions.assertEquals(e1.isIncreasing(), e2.isIncreasing());
113 
114         }
115     }
116 
117     @Test
118     public void testClearLog() {
119         EventsLogger logger = new EventsLogger();
120         propagator.addEventDetector(logger.monitorDetector(umbraDetector));
121         propagator.addEventDetector(logger.monitorDetector(penumbraDetector));
122         countAndContinue.reset();
123         propagator.propagate(iniDate.shiftedBy(16215));
124         List<EventsLogger.LoggedEvent> firstList = logger.getLoggedEvents();
125         Assertions.assertEquals(11, firstList.size());
126         logger.clearLoggedEvents();
127         propagator.propagate(iniDate.shiftedBy(30000));
128         List<EventsLogger.LoggedEvent> secondList = logger.getLoggedEvents();
129         Assertions.assertEquals(11, firstList.size());
130         Assertions.assertEquals( 9, secondList.size());
131     }
132 
133     private void checkCounts(EventsLogger logger,
134                              int expectedUmbraIncreasingCount, int expectedUmbraDecreasingCount,
135                              int expectedPenumbraIncreasingCount, int expectedPenumbraDecreasingCount) {
136         int umbraIncreasingCount = 0;
137         int umbraDecreasingCount = 0;
138         int penumbraIncreasingCount = 0;
139         int penumbraDecreasingCount = 0;
140         for (EventsLogger.LoggedEvent event : logger.getLoggedEvents()) {
141             final EclipseDetector eclipseDetector = (EclipseDetector) (event.getEventDetector());
142             if (eclipseDetector.getTotalEclipse()) {
143                 if (event.isIncreasing()) {
144                     ++umbraIncreasingCount;
145                 } else {
146                     ++umbraDecreasingCount;
147                 }
148             }
149             else {
150                 if (event.isIncreasing()) {
151                     ++penumbraIncreasingCount;
152                 } else {
153                     ++penumbraDecreasingCount;
154                 }
155             }
156         }
157         Assertions.assertEquals(expectedUmbraIncreasingCount,    umbraIncreasingCount);
158         Assertions.assertEquals(expectedUmbraDecreasingCount,    umbraDecreasingCount);
159         Assertions.assertEquals(expectedPenumbraIncreasingCount, penumbraIncreasingCount);
160         Assertions.assertEquals(expectedPenumbraDecreasingCount, penumbraDecreasingCount);
161     }
162 
163     private EclipseDetector buildDetector(final boolean totalEclipse) {
164 
165         EclipseDetector detector =
166                 new EclipseDetector(CelestialBodyFactory.getSun(), 696000000,
167                                     new OneAxisEllipsoid(6400000,
168                                                          0.0,
169                                                          FramesFactory.getITRF(IERSConventions.IERS_2010, true))).
170                 withMaxCheck(60.0).
171                 withThreshold(1.0e-3);
172 
173         if (totalEclipse) {
174             detector = detector.withUmbra();
175         } else {
176             detector = detector.withPenumbra();
177         }
178 
179         detector = detector.withHandler(countAndContinue);
180 
181         return detector;
182 
183     }
184 
185     @BeforeEach
186     public void setUp() {
187         try {
188             Utils.setDataRoot("regular-data");
189             mu  = 3.9860047e14;
190             final Vector3D position  = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
191             final Vector3D velocity  = new Vector3D(505.8479685, 942.7809215, 7435.922231);
192             iniDate = new AbsoluteDate(1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
193             final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position,  velocity),
194                                                      FramesFactory.getEME2000(), iniDate, mu);
195             initialState = new SpacecraftState(orbit);
196             double[] absTolerance = {
197                 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
198             };
199             double[] relTolerance = {
200                 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
201             };
202             AdaptiveStepsizeIntegrator integrator =
203                 new DormandPrince853Integrator(0.001, 1000, absTolerance, relTolerance);
204             integrator.setInitialStepSize(60);
205             propagator = new NumericalPropagator(integrator);
206             propagator.setInitialState(initialState);
207             countAndContinue = new CountAndContinue();
208             umbraDetector = buildDetector(true);
209             penumbraDetector = buildDetector(false);
210         } catch (OrekitException oe) {
211             Assertions.fail(oe.getLocalizedMessage());
212         }
213     }
214 
215     @AfterEach
216     public void tearDown() {
217         iniDate = null;
218         initialState = null;
219         propagator = null;
220         countAndContinue = null;
221         umbraDetector = null;
222         penumbraDetector = null;
223     }
224 
225 }
226