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.utils.ParameterDriver;
28 import org.orekit.utils.ParameterDriversList;
29 import org.orekit.utils.TimeStampedPVCoordinates;
30
31
32
33
34
35
36
37
38
39 public class MultiplexedMeasurement extends AbstractMeasurement<MultiplexedMeasurement> {
40
41
42 private final List<ObservedMeasurement<?>> observedMeasurements;
43
44
45 private final List<EstimatedMeasurement<?>> estimatedMeasurements;
46
47
48 private ParameterDriversList parametersDrivers;
49
50
51 private final int dimension;
52
53
54 private final int nbSat;
55
56
57 private final int[][] mapping;
58
59
60
61
62
63 public MultiplexedMeasurement(final List<ObservedMeasurement<?>> measurements) {
64 super(measurements.get(0).getDate(),
65 multiplex(measurements, m -> m.getObservedValue()),
66 multiplex(measurements, m -> m.getTheoreticalStandardDeviation()),
67 multiplex(measurements, m -> m.getBaseWeight()),
68 multiplex(measurements));
69
70 this.observedMeasurements = measurements;
71 this.estimatedMeasurements = new ArrayList<>();
72 this.parametersDrivers = new ParameterDriversList();
73
74
75 int dim = 0;
76 for (final ObservedMeasurement<?> m : measurements) {
77 for (final ParameterDriver driver : m.getParametersDrivers()) {
78 parametersDrivers.add(driver);
79 }
80 dim += m.getDimension();
81 }
82 parametersDrivers.sort();
83 for (final ParameterDriver driver : parametersDrivers.getDrivers()) {
84 addParameterDriver(driver);
85 }
86 this.dimension = dim;
87
88
89 final List<ObservableSatellite> deduplicated = getSatellites();
90 this.nbSat = deduplicated.size();
91 this.mapping = new int[measurements.size()][];
92 for (int i = 0; i < mapping.length; ++i) {
93 final List<ObservableSatellite> satellites = measurements.get(i).getSatellites();
94 mapping[i] = new int[satellites.size()];
95 for (int j = 0; j < mapping[i].length; ++j) {
96 final int index = satellites.get(j).getPropagatorIndex();
97 for (int k = 0; k < nbSat; ++k) {
98 if (deduplicated.get(k).getPropagatorIndex() == index) {
99 mapping[i][j] = k;
100 break;
101 }
102 }
103 }
104 }
105
106 }
107
108
109
110
111 public List<ObservedMeasurement<?>> getMeasurements() {
112 return observedMeasurements;
113 }
114
115
116
117
118 public List<EstimatedMeasurement<?>> getEstimatedMeasurements() {
119 return estimatedMeasurements;
120 }
121
122
123 @Override
124 protected EstimatedMeasurement<MultiplexedMeasurement> theoreticalEvaluation(final int iteration, final int evaluation,
125 final SpacecraftState[] states) {
126
127 final SpacecraftState[] evaluationStates = new SpacecraftState[nbSat];
128 final List<TimeStampedPVCoordinates> participants = new ArrayList<>();
129 final double[] value = new double[dimension];
130
131
132 estimatedMeasurements.clear();
133 int index = 0;
134 for (int i = 0; i < observedMeasurements.size(); ++i) {
135
136
137 final SpacecraftState[] filteredStates = new SpacecraftState[mapping[i].length];
138 for (int j = 0; j < mapping[i].length; ++j) {
139 filteredStates[j] = states[mapping[i][j]];
140 }
141
142
143 final EstimatedMeasurement<?> eI = observedMeasurements.get(i).estimate(iteration, evaluation, filteredStates);
144 estimatedMeasurements.add(eI);
145
146
147 final double[] valueI = eI.getEstimatedValue();
148 System.arraycopy(valueI, 0, value, index, valueI.length);
149 index += valueI.length;
150
151
152 final SpacecraftState[] statesI = eI.getStates();
153 for (int j = 0; j < mapping[i].length; ++j) {
154 evaluationStates[mapping[i][j]] = statesI[j];
155 }
156
157 }
158
159
160 final EstimatedMeasurement<MultiplexedMeasurement> multiplexed =
161 new EstimatedMeasurement<>(this, iteration, evaluation,
162 evaluationStates,
163 participants.toArray(new TimeStampedPVCoordinates[0]));
164
165
166 multiplexed.setEstimatedValue(value);
167
168
169 final int stateSize = estimatedMeasurements.get(0).getStateSize();
170 final double[] zeroDerivative = new double[stateSize];
171 final double[][][] stateDerivatives = new double[nbSat][dimension][];
172 for (final double[][] m : stateDerivatives) {
173 Arrays.fill(m, zeroDerivative);
174 }
175
176 final Map<ParameterDriver, double[]> parametersDerivatives = new IdentityHashMap<>();
177 index = 0;
178 for (int i = 0; i < observedMeasurements.size(); ++i) {
179
180 final EstimatedMeasurement<?> eI = estimatedMeasurements.get(i);
181 final int idx = index;
182 final int dimI = eI.getObservedMeasurement().getDimension();
183
184
185 for (int j = 0; j < mapping[i].length; ++j) {
186 System.arraycopy(eI.getStateDerivatives(j), 0,
187 stateDerivatives[mapping[i][j]], index,
188 dimI);
189 }
190
191
192 eI.getDerivativesDrivers().forEach(driver -> {
193 final ParameterDriversList.DelegatingDriver delegating = parametersDrivers.findByName(driver.getName());
194 double[] derivatives = parametersDerivatives.get(delegating);
195 if (derivatives == null) {
196 derivatives = new double[dimension];
197 parametersDerivatives.put(delegating, derivatives);
198 }
199 System.arraycopy(eI.getParameterDerivatives(driver), 0, derivatives, idx, dimI);
200 });
201
202 index += dimI;
203
204 }
205
206
207 for (int i = 0; i < nbSat; ++i) {
208 multiplexed.setStateDerivatives(i, stateDerivatives[i]);
209 }
210
211
212 parametersDerivatives.
213 entrySet().
214 stream().
215 forEach(e -> multiplexed.setParameterDerivatives(e.getKey(), e.getValue()));
216
217 return multiplexed;
218
219 }
220
221
222
223
224
225
226 private static double[] multiplex(final List<ObservedMeasurement<?>> measurements,
227 final Function<ObservedMeasurement<?>, double[]> extractor) {
228
229
230 final List<double[]> parts = new ArrayList<> (measurements.size());
231 int n = 0;
232 for (final ObservedMeasurement<?> measurement : measurements) {
233 final double[] p = extractor.apply(measurement);
234 parts.add(p);
235 n += p.length;
236 }
237
238
239 final double[] multiplexed = new double[n];
240 int index = 0;
241 for (final double[] p : parts) {
242 System.arraycopy(p, 0, multiplexed, index, p.length);
243 index += p.length;
244 }
245
246 return multiplexed;
247
248 }
249
250
251
252
253
254 private static List<ObservableSatellite> multiplex(final List<ObservedMeasurement<?>> measurements) {
255
256 final List<ObservableSatellite> satellites = new ArrayList<>();
257
258
259 for (final ObservedMeasurement<?> measurement : measurements) {
260 for (final ObservableSatellite satellite : measurement.getSatellites()) {
261 boolean searching = true;
262 for (int i = 0; i < satellites.size() && searching; ++i) {
263
264 searching = satellite.getPropagatorIndex() != satellites.get(i).getPropagatorIndex();
265 }
266 if (searching) {
267
268 satellites.add(satellite);
269 }
270 }
271 }
272
273 return satellites;
274
275 }
276
277 }