1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.estimation.measurements;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.IdentityHashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.function.Function;
25
26 import org.orekit.propagation.SpacecraftState;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.utils.ParameterDriver;
29 import org.orekit.utils.ParameterDriversList;
30 import org.orekit.utils.TimeSpanMap;
31 import org.orekit.utils.TimeStampedPVCoordinates;
32 import org.orekit.utils.TimeSpanMap.Span;
33
34
35
36
37
38
39
40
41
42 public class MultiplexedMeasurement extends AbstractMeasurement<MultiplexedMeasurement> {
43
44
45 public static final String MEASUREMENT_TYPE = "MultiplexedMeasurement";
46
47
48 private final List<ObservedMeasurement<?>> observedMeasurements;
49
50
51
52 private final List<EstimatedMeasurementBase<?>> estimatedMeasurementsWithoutDerivatives;
53
54
55 private final List<EstimatedMeasurement<?>> estimatedMeasurements;
56
57
58 private ParameterDriversList parametersDrivers;
59
60
61 private final int dimension;
62
63
64 private final int nbSat;
65
66
67 private final int[][] mapping;
68
69
70
71
72
73 public MultiplexedMeasurement(final List<ObservedMeasurement<?>> measurements) {
74 super(measurements.get(0).getDate(),
75 multiplex(measurements, m -> m.getObservedValue()),
76 multiplex(measurements, m -> m.getTheoreticalStandardDeviation()),
77 multiplex(measurements, m -> m.getBaseWeight()),
78 multiplex(measurements));
79
80 this.observedMeasurements = measurements;
81 this.estimatedMeasurementsWithoutDerivatives = new ArrayList<>();
82 this.estimatedMeasurements = new ArrayList<>();
83 this.parametersDrivers = new ParameterDriversList();
84
85
86 int dim = 0;
87 for (final ObservedMeasurement<?> m : measurements) {
88 for (final ParameterDriver driver : m.getParametersDrivers()) {
89 parametersDrivers.add(driver);
90 }
91 dim += m.getDimension();
92 }
93 parametersDrivers.sort();
94 for (final ParameterDriver driver : parametersDrivers.getDrivers()) {
95 addParameterDriver(driver);
96 }
97 this.dimension = dim;
98
99
100 final List<ObservableSatellite> deduplicated = getSatellites();
101 this.nbSat = deduplicated.size();
102 this.mapping = new int[measurements.size()][];
103 for (int i = 0; i < mapping.length; ++i) {
104 final List<ObservableSatellite> satellites = measurements.get(i).getSatellites();
105 mapping[i] = new int[satellites.size()];
106 for (int j = 0; j < mapping[i].length; ++j) {
107 final int index = satellites.get(j).getPropagatorIndex();
108 for (int k = 0; k < nbSat; ++k) {
109 if (deduplicated.get(k).getPropagatorIndex() == index) {
110 mapping[i][j] = k;
111 break;
112 }
113 }
114 }
115 }
116
117 }
118
119
120
121
122 public List<ObservedMeasurement<?>> getMeasurements() {
123 return observedMeasurements;
124 }
125
126
127
128
129
130 public List<EstimatedMeasurementBase<?>> getEstimatedMeasurementsWithoutDerivatives() {
131 return estimatedMeasurementsWithoutDerivatives;
132 }
133
134
135
136
137 public List<EstimatedMeasurement<?>> getEstimatedMeasurements() {
138 return estimatedMeasurements;
139 }
140
141
142 @Override
143 protected EstimatedMeasurementBase<MultiplexedMeasurement> theoreticalEvaluationWithoutDerivatives(final int iteration,
144 final int evaluation,
145 final SpacecraftState[] states) {
146
147 final SpacecraftState[] evaluationStates = new SpacecraftState[nbSat];
148 final List<TimeStampedPVCoordinates> participants = new ArrayList<>();
149 final double[] value = new double[dimension];
150
151
152 estimatedMeasurementsWithoutDerivatives.clear();
153 int index = 0;
154 for (int i = 0; i < observedMeasurements.size(); ++i) {
155
156
157 final SpacecraftState[] filteredStates = new SpacecraftState[mapping[i].length];
158 for (int j = 0; j < mapping[i].length; ++j) {
159 filteredStates[j] = states[mapping[i][j]];
160 }
161
162
163 final EstimatedMeasurementBase<?> eI = observedMeasurements.get(i).estimateWithoutDerivatives(iteration, evaluation, filteredStates);
164 estimatedMeasurementsWithoutDerivatives.add(eI);
165
166
167 final double[] valueI = eI.getEstimatedValue();
168 System.arraycopy(valueI, 0, value, index, valueI.length);
169 index += valueI.length;
170
171
172 final SpacecraftState[] statesI = eI.getStates();
173 for (int j = 0; j < mapping[i].length; ++j) {
174 evaluationStates[mapping[i][j]] = statesI[j];
175 }
176
177 }
178
179
180 final EstimatedMeasurementBase<MultiplexedMeasurement> multiplexed =
181 new EstimatedMeasurementBase<>(this, iteration, evaluation,
182 evaluationStates,
183 participants.toArray(new TimeStampedPVCoordinates[0]));
184
185
186 multiplexed.setEstimatedValue(value);
187
188 return multiplexed;
189
190 }
191
192
193 @Override
194 protected EstimatedMeasurement<MultiplexedMeasurement> theoreticalEvaluation(final int iteration, final int evaluation,
195 final SpacecraftState[] states) {
196
197 final SpacecraftState[] evaluationStates = new SpacecraftState[nbSat];
198 final List<TimeStampedPVCoordinates> participants = new ArrayList<>();
199 final double[] value = new double[dimension];
200
201
202 estimatedMeasurements.clear();
203 int index = 0;
204 for (int i = 0; i < observedMeasurements.size(); ++i) {
205
206
207 final SpacecraftState[] filteredStates = new SpacecraftState[mapping[i].length];
208 for (int j = 0; j < mapping[i].length; ++j) {
209 filteredStates[j] = states[mapping[i][j]];
210 }
211
212
213 final EstimatedMeasurement<?> eI = observedMeasurements.get(i).estimate(iteration, evaluation, filteredStates);
214 estimatedMeasurements.add(eI);
215
216
217 final double[] valueI = eI.getEstimatedValue();
218 System.arraycopy(valueI, 0, value, index, valueI.length);
219 index += valueI.length;
220
221
222 final SpacecraftState[] statesI = eI.getStates();
223 for (int j = 0; j < mapping[i].length; ++j) {
224 evaluationStates[mapping[i][j]] = statesI[j];
225 }
226
227 }
228
229
230 final EstimatedMeasurement<MultiplexedMeasurement> multiplexed =
231 new EstimatedMeasurement<>(this, iteration, evaluation,
232 evaluationStates,
233 participants.toArray(new TimeStampedPVCoordinates[0]));
234
235
236 multiplexed.setEstimatedValue(value);
237
238
239 final int stateSize = estimatedMeasurements.get(0).getStateSize();
240 final double[] zeroDerivative = new double[stateSize];
241 final double[][][] stateDerivatives = new double[nbSat][dimension][];
242 for (final double[][] m : stateDerivatives) {
243 Arrays.fill(m, zeroDerivative);
244 }
245
246 final Map<ParameterDriver, TimeSpanMap<double[]>> parametersDerivatives = new IdentityHashMap<>();
247 index = 0;
248 for (int i = 0; i < observedMeasurements.size(); ++i) {
249
250 final EstimatedMeasurement<?> eI = estimatedMeasurements.get(i);
251 final int idx = index;
252 final int dimI = eI.getObservedMeasurement().getDimension();
253
254
255 for (int j = 0; j < mapping[i].length; ++j) {
256 System.arraycopy(eI.getStateDerivatives(j), 0,
257 stateDerivatives[mapping[i][j]], index,
258 dimI);
259 }
260
261
262 eI.getDerivativesDrivers().forEach(driver -> {
263 final ParameterDriversList.DelegatingDriver delegating = parametersDrivers.findByName(driver.getName());
264
265 if (parametersDerivatives.get(delegating) == null) {
266 final TimeSpanMap<double[]> derivativeSpanMap = new TimeSpanMap<double[]>(new double[dimension]);
267 parametersDerivatives.put(delegating, derivativeSpanMap);
268 }
269
270 final TimeSpanMap<Double> driverNameSpan = delegating.getValueSpanMap();
271 for (Span<Double> span = driverNameSpan.getSpan(driverNameSpan.getFirstSpan().getEnd()); span != null; span = span.next()) {
272
273 double[] derivatives = parametersDerivatives.get(delegating).get(span.getStart());
274 if (derivatives == null) {
275 derivatives = new double[dimension];
276 }
277 if (!parametersDerivatives.get(delegating).getSpan(span.getStart()).getStart().equals(span.getStart())) {
278 if ((span.getStart()).equals(AbsoluteDate.PAST_INFINITY)) {
279 parametersDerivatives.get(delegating).addValidBefore(derivatives, span.getEnd(), false);
280 } else {
281 parametersDerivatives.get(delegating).addValidAfter(derivatives, span.getStart(), false);
282 }
283
284 }
285
286 System.arraycopy(eI.getParameterDerivatives(driver, span.getStart()), 0, derivatives, idx, dimI);
287
288 }
289
290 });
291
292 index += dimI;
293
294 }
295
296
297 for (int i = 0; i < nbSat; ++i) {
298 multiplexed.setStateDerivatives(i, stateDerivatives[i]);
299 }
300
301
302 parametersDerivatives.
303 entrySet().
304 stream().
305 forEach(e -> multiplexed.setParameterDerivatives(e.getKey(), e.getValue()));
306
307 return multiplexed;
308
309 }
310
311
312
313
314
315
316 private static double[] multiplex(final List<ObservedMeasurement<?>> measurements,
317 final Function<ObservedMeasurement<?>, double[]> extractor) {
318
319
320 final List<double[]> parts = new ArrayList<> (measurements.size());
321 int n = 0;
322 for (final ObservedMeasurement<?> measurement : measurements) {
323 final double[] p = extractor.apply(measurement);
324 parts.add(p);
325 n += p.length;
326 }
327
328
329 final double[] multiplexed = new double[n];
330 int index = 0;
331 for (final double[] p : parts) {
332 System.arraycopy(p, 0, multiplexed, index, p.length);
333 index += p.length;
334 }
335
336 return multiplexed;
337
338 }
339
340
341
342
343
344 private static List<ObservableSatellite> multiplex(final List<ObservedMeasurement<?>> measurements) {
345
346 final List<ObservableSatellite> satellites = new ArrayList<>();
347
348
349 for (final ObservedMeasurement<?> measurement : measurements) {
350 for (final ObservableSatellite satellite : measurement.getSatellites()) {
351 boolean searching = true;
352 for (int i = 0; i < satellites.size() && searching; ++i) {
353
354 searching = satellite.getPropagatorIndex() != satellites.get(i).getPropagatorIndex();
355 }
356 if (searching) {
357
358 satellites.add(satellite);
359 }
360 }
361 }
362
363 return satellites;
364
365 }
366
367 }