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.hipparchus.linear.MatrixUtils;
27 import org.hipparchus.linear.RealMatrix;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.utils.ParameterDriver;
31 import org.orekit.utils.ParameterDriversList;
32 import org.orekit.utils.TimeSpanMap;
33 import org.orekit.utils.TimeSpanMap.Span;
34 import org.orekit.utils.TimeStampedPVCoordinates;
35
36
37
38
39
40
41
42
43
44 public class MultiplexedMeasurement extends AbstractMeasurement<MultiplexedMeasurement> {
45
46
47 public static final String MEASUREMENT_TYPE = "MultiplexedMeasurement";
48
49
50 private final List<ObservedMeasurement<?>> observedMeasurements;
51
52
53
54 private final List<EstimatedMeasurementBase<?>> estimatedMeasurementsWithoutDerivatives;
55
56
57 private final List<EstimatedMeasurement<?>> estimatedMeasurements;
58
59
60 private final ParameterDriversList parametersDrivers;
61
62
63 private final int dimension;
64
65
66 private final int nbSat;
67
68
69 private final int[][] multiplexedToUnderlying;
70
71
72 private final int[][] underlyingToMultiplexed;
73
74
75
76
77
78 public MultiplexedMeasurement(final List<ObservedMeasurement<?>> measurements) {
79 super(measurements.getFirst().getDate(),
80 multiplex(measurements, ComparableMeasurement::getObservedValue),
81 multiplexMeasurementQuality(measurements), 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.getFirst().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 private static MeasurementQuality multiplexMeasurementQuality(final List<ObservedMeasurement<?>> measurements) {
338
339 final int totalSize = measurements.stream().mapToInt(ObservedMeasurement::getDimension).sum();
340 final double[] weights = new double[totalSize];
341 final RealMatrix covarianceMatrix = MatrixUtils.createRealMatrix(totalSize, totalSize);
342 int n = 0;
343 for (final ObservedMeasurement<?> measurement : measurements) {
344 System.arraycopy(measurement.getBaseWeight(), 0, weights, n, measurement.getDimension());
345 covarianceMatrix.setSubMatrix(measurement.getMeasurementQuality().getCovarianceMatrix().getData(), n, n);
346 n += measurement.getDimension();
347 }
348
349 return new MeasurementQuality(covarianceMatrix.getData(), weights);
350
351 }
352
353
354
355
356
357
358 private static double[] multiplex(final List<ObservedMeasurement<?>> measurements,
359 final Function<ObservedMeasurement<?>, double[]> extractor) {
360
361
362 final List<double[]> parts = new ArrayList<> (measurements.size());
363 int n = 0;
364 for (final ObservedMeasurement<?> measurement : measurements) {
365 final double[] p = extractor.apply(measurement);
366 parts.add(p);
367 n += p.length;
368 }
369
370
371 final double[] multiplexed = new double[n];
372 int index = 0;
373 for (final double[] p : parts) {
374 System.arraycopy(p, 0, multiplexed, index, p.length);
375 index += p.length;
376 }
377
378 return multiplexed;
379
380 }
381
382
383
384
385
386 private static List<ObservableSatellite> multiplex(final List<ObservedMeasurement<?>> measurements) {
387
388 final List<ObservableSatellite> satellites = new ArrayList<>();
389
390
391 for (final ObservedMeasurement<?> measurement : measurements) {
392 for (final ObservableSatellite satellite : measurement.getSatellites()) {
393 boolean searching = true;
394 for (int i = 0; i < satellites.size() && searching; ++i) {
395
396 searching = satellite.getPropagatorIndex() != satellites.get(i).getPropagatorIndex();
397 }
398 if (searching) {
399
400 satellites.add(satellite);
401 }
402 }
403 }
404
405 return satellites;
406
407 }
408
409 }