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