1 /* Copyright 2002-2024 Thales Alenia Space
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.files.rinex.observation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.util.FastMath;
24 import org.orekit.errors.OrekitIllegalArgumentException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.files.rinex.RinexFile;
27 import org.orekit.time.AbsoluteDate;
28
29 /** Container for Rinex observation file.
30 * @author Luc Maisonobe
31 * @since 12.0
32 */
33 public class RinexObservation extends RinexFile<RinexObservationHeader> {
34
35 /** Observations. */
36 private final List<ObservationDataSet> observations;
37
38 /** Simple constructor.
39 */
40 public RinexObservation() {
41 super(new RinexObservationHeader());
42 this.observations = new ArrayList<>();
43 }
44
45 /** Get an unmodifiable view of the observations.
46 * @return unmodifiable view of the observations
47 */
48 public List<ObservationDataSet> getObservationDataSets() {
49 return Collections.unmodifiableList(observations);
50 }
51
52 /** Add an observations data set.
53 * <p>
54 * Observations must be added chronologically, within header date range, and separated
55 * by an integer multiple of the {@link RinexObservationHeader#getInterval() interval}
56 * (ideally one interval, but entries at same dates and missing entries are allowed so
57 * any non-negative integer is allowed).
58 * </p>
59 * @param observationsDataSet observations data set
60 */
61 public void addObservationDataSet(final ObservationDataSet observationsDataSet) {
62
63 final RinexObservationHeader header = getHeader();
64 final AbsoluteDate current = observationsDataSet.getDate();
65
66 // check interval from previous observation
67 if (!observations.isEmpty()) {
68 final AbsoluteDate previous = observations.get(observations.size() - 1).getDate();
69 final double factor = current.durationFrom(previous) / header.getInterval();
70 final double acceptable = FastMath.max(0.0, FastMath.rint(factor));
71 if (FastMath.abs(factor - acceptable) > 0.001) {
72 throw new OrekitIllegalArgumentException(OrekitMessages.INCONSISTENT_SAMPLING_DATE,
73 previous.shiftedBy(acceptable * header.getInterval()),
74 current);
75 }
76 }
77
78 // check global range
79 final AbsoluteDate first = header.getTFirstObs();
80 final AbsoluteDate last = header.getTLastObs();
81 if (!current.isBetweenOrEqualTo(first, last)) {
82 throw new OrekitIllegalArgumentException(OrekitMessages.OUT_OF_RANGE_DATE,
83 current, first, last);
84 }
85
86 observations.add(observationsDataSet);
87
88 }
89
90 }