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