1 package org.opentrafficsim.core.egtf;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
6 /**
7 * Data source for the EGTF. These are obtained using {@code EGTF.getDataSource()}.
8 * <p>
9 * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
11 * </p>
12 * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
13 */
14 public final class DataSource
15 {
16 /** Unique name. */
17 private final String name;
18
19 /** Data stream of this data source. */
20 private final Map<String, DataStream<?>> streams = new LinkedHashMap<>();
21
22 /**
23 * Constructor.
24 * @param name String; unique name
25 */
26 DataSource(final String name)
27 {
28 this.name = name;
29 }
30
31 /**
32 * Returns the name.
33 * @return String; name
34 */
35 public String getName()
36 {
37 return this.name;
38 }
39
40 /**
41 * Add a non-speed stream for the quantity to this data source.
42 * @param quantity Quantity<T, ?>; quantity
43 * @param thetaCong T; standard deviation of this quantity of measurements in congestion by this data source
44 * @param thetaFree T; standard deviation of this quantity of measurements in free flow by this data source
45 * @param <T> implicit data type
46 * @return DataStream; the created data stream
47 * @throws IllegalArgumentException if the quantity is speed
48 */
49 public <T extends Number> DataStream<T> addStream(final Quantity<T, ?> quantity, final T thetaCong, final T thetaFree)
50 {
51 return addStreamSI(quantity, thetaCong.doubleValue(), thetaFree.doubleValue());
52 }
53
54 /**
55 * Add a stream for the quantity to this data source.
56 * @param quantity Quantity<T, ?>; quantity
57 * @param thetaCong double; standard deviation of this quantity of measurements in congestion by this data source in SI
58 * @param thetaFree double; standard deviation of this quantity of measurements in free flow by this data source in SI
59 * @param <T> implicit data type
60 * @return DataStream; the created data stream
61 */
62 public <T extends Number> DataStream<T> addStreamSI(final Quantity<T, ?> quantity, final double thetaCong,
63 final double thetaFree)
64 {
65 if (this.streams.containsKey(quantity.getName()))
66 {
67 throw new IllegalStateException(
68 String.format("Data source %s already has a stream for quantity %s.", this.name, quantity.getName()));
69 }
70 if (thetaCong <= 0.0 || thetaFree <= 0.0)
71 {
72 throw new IllegalArgumentException("Standard deviation must be positive and above 0.");
73 }
74 DataStream<T> dataStream = new DataStream<>(this, quantity, thetaCong, thetaFree);
75 this.streams.put(quantity.getName(), dataStream);
76 return dataStream;
77 }
78
79 /**
80 * Get a stream for the quantity of this data source. If no stream has been created, one will be created with 1.0 standard
81 * deviation.
82 * @param quantity Quantity<T, ?>; quantity
83 * @return DataStream<T>; stream for the quantity of this data source
84 * @param <T> implicit data type
85 */
86 @SuppressWarnings({"unchecked"})
87 public <T extends Number> DataStream<T> getStream(final Quantity<T, ?> quantity)
88 {
89 if (!this.streams.containsKey(quantity.getName()))
90 {
91 addStreamSI(quantity, 1.0, 1.0);
92 }
93 return (DataStream<T>) this.streams.get(quantity.getName());
94 }
95
96 /** {@inheritDoc} */
97 @Override
98 public int hashCode()
99 {
100 final int prime = 31;
101 int result = 1;
102 result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
103 return result;
104 }
105
106 /** {@inheritDoc} */
107 @Override
108 public boolean equals(final Object obj)
109 {
110 if (this == obj)
111 {
112 return true;
113 }
114 if (obj == null)
115 {
116 return false;
117 }
118 if (getClass() != obj.getClass())
119 {
120 return false;
121 }
122 DataSource other = (DataSource) obj;
123 if (this.name == null)
124 {
125 if (other.name != null)
126 {
127 return false;
128 }
129 }
130 else if (!this.name.equals(other.name))
131 {
132 return false;
133 }
134 return true;
135 }
136
137 /** {@inheritDoc} */
138 @Override
139 public String toString()
140 {
141 return "DataSource [" + this.name + "]";
142 }
143
144 }