1 /* Copyright 2002-2024 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.estimation.measurements;
18
19 import org.orekit.propagation.SpacecraftState;
20 import org.orekit.time.AbsoluteDate;
21 import org.orekit.utils.TimeStampedPVCoordinates;
22
23 import java.util.IdentityHashMap;
24
25 /** Class holding an estimated theoretical value associated to an {@link ObservedMeasurement observed measurement}.
26 * @param <T> the type of the measurement
27 * @author Luc Maisonobe
28 * @since 8.0
29 */
30 public class EstimatedMeasurementBase<T extends ObservedMeasurement<T>> implements ComparableMeasurement {
31
32 /** Associated observed measurement. */
33 private final T observedMeasurement;
34
35 /** Iteration number. */
36 private final int iteration;
37
38 /** Evaluations counter. */
39 private final int count;
40
41 /** States of the spacecrafts. */
42 private final SpacecraftState[] states;
43
44 /** Coordinates of the participants in signal travel order. */
45 private final TimeStampedPVCoordinates[] participants;
46
47 /** Original estimated value prior to any modification.
48 * @since 12.1
49 */
50 private double[] originalEstimatedValue;
51
52 /** Estimated value. */
53 private double[] estimatedValue;
54
55 /** Applied modifiers effects.
56 * @since 12.1
57 */
58 private final IdentityHashMap<EstimationModifier<T>, double[]> appliedEffects;
59
60 /** Measurement status. */
61 private Status status;
62
63 /** Simple constructor.
64 * @param observedMeasurement associated observed measurement
65 * @param iteration iteration number
66 * @param count evaluations counter
67 * @param states states of the spacecrafts
68 * @param participants coordinates of the participants in signal travel order
69 * in inertial frame
70 */
71 public EstimatedMeasurementBase(final T observedMeasurement,
72 final int iteration, final int count,
73 final SpacecraftState[] states,
74 final TimeStampedPVCoordinates[] participants) {
75 this.observedMeasurement = observedMeasurement;
76 this.iteration = iteration;
77 this.count = count;
78 this.states = states.clone();
79 this.participants = participants.clone();
80 this.status = Status.PROCESSED;
81 this.appliedEffects = new IdentityHashMap<>();
82 }
83
84 /** Get the associated observed measurement.
85 * @return associated observed measurement
86 */
87 public T getObservedMeasurement() {
88 return observedMeasurement;
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public AbsoluteDate getDate() {
94 return observedMeasurement.getDate();
95 }
96
97 /** Get the iteration number.
98 * @return iteration number
99 */
100 public int getIteration() {
101 return iteration;
102 }
103
104 /** Get the evaluations counter.
105 * @return evaluations counter
106 */
107 public int getCount() {
108 return count;
109 }
110
111 /** Get the states of the spacecrafts.
112 * @return states of the spacecrafts
113 */
114 public SpacecraftState[] getStates() {
115 return states.clone();
116 }
117
118 /** Get the coordinates of the measurements participants in signal travel order.
119 * <p>
120 * First participant (at index 0) emits the signal (it is for example a ground
121 * station for two-way range measurement). Last participant receives the signal
122 * (it is also the ground station for two-way range measurement, but a few
123 * milliseconds later). Intermediate participants relfect the signal (it is the
124 * spacecraft for two-way range measurement).
125 * </p>
126 * @return coordinates of the measurements participants in signal travel order
127 * in inertial frame
128 */
129 public TimeStampedPVCoordinates[] getParticipants() {
130 return participants.clone();
131 }
132
133 /** Get the time offset from first state date to measurement date.
134 * @return time offset from first state date to measurement date
135 */
136 public double getTimeOffset() {
137 return observedMeasurement.getDate().durationFrom(states[0].getDate());
138 }
139
140 /** {@inheritDoc} */
141 @Override
142 public double[] getObservedValue() {
143 return observedMeasurement.getObservedValue();
144 }
145
146 /** Get the original estimated value prior to any modification.
147 * @return original estimated value prior to any modification
148 * @since 12.1
149 */
150 public double[] getOriginalEstimatedValue() {
151 return originalEstimatedValue.clone();
152 }
153
154 /** Get the applied effects of modifiers.
155 * <p>
156 * The effects have already accounted for in {@link #getEstimatedValue()}
157 * </p>
158 * @return applied modifier effects
159 * @since 12.1
160 */
161 public IdentityHashMap<EstimationModifier<T>, double[]> getAppliedEffects() {
162 return appliedEffects;
163 }
164
165 /** Get the estimated value.
166 * @return estimated value
167 */
168 public double[] getEstimatedValue() {
169 return estimatedValue.clone();
170 }
171
172 /** Set the estimated value.
173 * @param estimatedValue estimated value
174 * @see #modifyEstimatedValue(EstimationModifier, double...)
175 */
176 public void setEstimatedValue(final double... estimatedValue) {
177 if (originalEstimatedValue == null) {
178 this.originalEstimatedValue = estimatedValue.clone();
179 }
180 this.estimatedValue = estimatedValue.clone();
181 }
182
183 /** Modify the estimated value.
184 * @param modifier modifier that generates this estimated value
185 * @param newEstimatedValue new estimated value
186 * @since 12.1
187 */
188 public void modifyEstimatedValue(final EstimationModifier<T> modifier, final double... newEstimatedValue) {
189
190 if (modifier == null) {
191 setEstimatedValue(newEstimatedValue);
192 } else {
193 final double[] effect = new double[newEstimatedValue.length];
194 for (int i = 0; i < effect.length; ++i) {
195 // compute effect
196 effect[i] = newEstimatedValue[i] - estimatedValue[i];
197 // update value
198 estimatedValue[i] = newEstimatedValue[i];
199 }
200
201 // store effect
202 appliedEffects.put(modifier, effect);
203 }
204
205 }
206
207 /** Get the status.
208 * <p>
209 * The status is set to {@link Status#PROCESSED PROCESSED} at construction, and
210 * can be reset to {@link Status#REJECTED REJECTED} later on, typically by
211 * {@link org.orekit.estimation.measurements.modifiers.OutlierFilter OutlierFilter}
212 * or {@link org.orekit.estimation.measurements.modifiers.DynamicOutlierFilter DynamicOutlierFilter}
213 * </p>
214 * @return status
215 */
216 public Status getStatus() {
217 return status;
218 }
219
220 /** Set the status.
221 * @param status status to set
222 */
223 public void setStatus(final Status status) {
224 this.status = status;
225 }
226
227 /** Enumerate for the status of the measurement. */
228 public enum Status {
229
230 /** Status for processed measurements. */
231 PROCESSED,
232
233 /** Status for rejected measurements. */
234 REJECTED
235
236 }
237
238 }