1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package de.fu_berlin.ties.eval;
23
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import org.apache.commons.lang.StringUtils;
28
29 /***
30 * Type-safe enumeration of possible evaluation states for predictions
31 * (unknown, correct, spurious etc.) and answer keys (missing etc.).
32 *
33 * @author Christian Siefkes
34 * @version $Revision: 1.4 $, $Date: 2004/11/07 18:21:27 $, $Author: siefkes $
35 */
36 public final class EvalStatus {
37
38 /***
39 * A map of all instantiated instances of this class. The name of the
40 * instance is mapped to the instance itself. There is no need to
41 * synchronize this map as it is only modified during the static
42 * initialization of this class.
43 */
44 private static final Map<String, EvalStatus> ALL_INSTANCES =
45 new HashMap<String, EvalStatus>();
46
47 /***
48 * Serialization key recommended for instances of this class.
49 */
50 public static final String KEY_EVAL_STATUS = "EvalStatus";
51
52 /***
53 * Constant for predictions whose evaluation status is unknown (not
54 * yet evaluated).
55 */
56 public static final EvalStatus UNKNOWN =
57 new EvalStatus("unknown", true, false);
58
59 /***
60 * Constant for items defined to be true (answer keys, "gold standard").
61 */
62 public static final EvalStatus TRUTH = new EvalStatus("truth", false, true);
63
64 /***
65 * Constant for correct predictions (true positives) resp for answer
66 * keys matched by a prediction. This is the only instance that is suitable
67 * for both {@link #isAnswerState() answer keys} and
68 * {@link #isPredictionState() predictions}.
69 */
70 public static final EvalStatus CORRECT =
71 new EvalStatus("correct", true, true);
72
73 /***
74 * Constant for missing answer keys (false negatives).
75 */
76 public static final EvalStatus MISSING =
77 new EvalStatus("missing", false, true);
78
79 /***
80 * Constant for spurious predictions (false positives).
81 */
82 public static final EvalStatus SPURIOUS =
83 new EvalStatus("spurious", true, false);
84
85 /***
86 * Constant for answer keys that could have proposed as predictions but
87 * were not. When there is only a single instance of each type to predict
88 * ("best match" mode), one of the answer keys should be tagged as
89 * {@link #CORRECT} resp. {@link #MISSING}; the others should be tagged
90 * as {@link #ALTERNATIVE}s.
91 */
92 public static final EvalStatus ALTERNATIVE =
93 new EvalStatus("alternative", false, true);
94
95 /***
96 * Constant for predictions that were ignored. When there is only a single
97 * instance of each type to predict ("best match" mode), the most probably
98 * prediction will be evaluated, while the others of the same type will be
99 * ignored.
100 */
101 public static final EvalStatus IGNORED =
102 new EvalStatus("ignored", true, false);
103
104 /***
105 * Parses a textual representation into an eval status, without using a
106 * default object. This method can convert to results of {@link #getName()}
107 * and {@link #toString()} back into the corresponding instance.
108 *
109 * @param representation the textual representation to parse
110 * @return the eval status object corresponding to the given string
111 * @throws IllegalArgumentException if a given string does not represent a
112 * known evaluation status
113 */
114 public static EvalStatus parse(final String representation)
115 throws IllegalArgumentException {
116 return parse(representation, false);
117 }
118
119 /***
120 * Parses a textual representation into an eval status. This method can
121 * convert to results of {@link #getName()} and {@link #toString()} back
122 * into the corresponding instance.
123 *
124 * @param representation the textual representation to parse
125 * @param useDefault if <code>true</code>, {@link #UNKNOWN} is returned if
126 * the representation is an unparsable (invalid) or <code>null</code>;
127 * otherwise an exception is thrown in this case
128 * @return the eval status object corresponding to the given string
129 * @throws IllegalArgumentException if a given string does not represent a
130 * known evaluation status and <code>useDefault</code> is <code>false</code>
131 */
132 public static EvalStatus parse(final String representation,
133 final boolean useDefault) throws IllegalArgumentException {
134
135 final EvalStatus result =
136 ALL_INSTANCES.get(StringUtils.trim(representation));
137
138 if (result != null) {
139 return result;
140 } else {
141 if (useDefault) {
142 return EvalStatus.UNKNOWN;
143 } else {
144 throw new IllegalArgumentException(
145 "Cannot parse to eval status: " + representation);
146 }
147 }
148 }
149
150 /***
151 * The name of this instance.
152 */
153 private final String name;
154
155 /***
156 * Whether this state is suitable for an answer key.
157 */
158 private final boolean answerState;
159
160 /***
161 * Whether this state is suitable for a prediction.
162 */
163 private final boolean predictionState;
164
165 /***
166 * Private constructor to prevent creation of further instances.
167 * The static constants defined in this class are the only instantiations.
168 *
169 * @param newName the name of this instance
170 * @param predState whether this state is suitable for a prediction
171 * @param ansState whether this state is suitable for an answer key
172 * @throws IllegalArgumentException if the specified name is already used
173 * by another instance
174 */
175 private EvalStatus(final String newName, final boolean predState,
176 final boolean ansState) throws IllegalArgumentException {
177 super();
178 name = newName;
179 predictionState = predState;
180 answerState = ansState;
181
182
183 final EvalStatus previousValue = ALL_INSTANCES.put(newName, this);
184 if (previousValue != null) {
185 throw new IllegalArgumentException(
186 "Name " + newName + " already in use!");
187 }
188 }
189
190 /***
191 * Returns the name of this instance.
192 * @return the value of the attribute
193 */
194 public String getName() {
195 return name;
196 }
197
198 /***
199 * Returns a string representation, printing the
200 * {@linkplain #getName() name} of this instance.
201 *
202 * @return a textual representation
203 */
204 public String toString() {
205 return name;
206 }
207
208 /***
209 * Whether this state is suitable for an answer key.
210 * @return <code>true</code> iff this state is suitable for an answer key
211 */
212 public boolean isAnswerState() {
213 return answerState;
214 }
215
216 /***
217 * Whether this state is suitable for a prediction.
218 * @return <code>true</code> iff this state is suitable for a prediction
219 */
220 public boolean isPredictionState() {
221 return predictionState;
222 }
223
224 }