Skip to main content

anno_eval/eval/
config_builder.rs

1//! Configuration Builder Pattern
2//!
3//! Provides builder pattern for evaluation configurations to reduce complexity
4//! and improve usability.
5
6#[cfg(feature = "eval-bias")]
7use crate::eval::bias_config::BiasDatasetConfig;
8#[cfg(feature = "eval")]
9use crate::eval::loader::DatasetId;
10#[cfg(feature = "eval")]
11use crate::eval::task_mapping::Task;
12
13/// Builder for TaskEvalConfig.
14#[derive(Debug, Clone)]
15#[cfg(feature = "eval")]
16pub struct TaskEvalConfigBuilder {
17    tasks: Vec<Task>,
18    datasets: Vec<DatasetId>,
19    backends: Vec<String>,
20    max_examples: Option<usize>,
21    seed: Option<u64>,
22    require_cached: bool,
23    relation_threshold: f32,
24    robustness: bool,
25    compute_familiarity: bool,
26    temporal_stratification: bool,
27    confidence_intervals: bool,
28    coref_use_gold_mentions: bool,
29}
30
31#[cfg(feature = "eval")]
32impl TaskEvalConfigBuilder {
33    /// Create a new builder with defaults.
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    /// Set tasks to evaluate.
39    pub fn with_tasks(mut self, tasks: Vec<Task>) -> Self {
40        self.tasks = tasks;
41        self
42    }
43
44    /// Add a task.
45    pub fn add_task(mut self, task: Task) -> Self {
46        self.tasks.push(task);
47        self
48    }
49
50    /// Set datasets to use.
51    pub fn with_datasets(mut self, datasets: Vec<DatasetId>) -> Self {
52        self.datasets = datasets;
53        self
54    }
55
56    /// Add a dataset.
57    pub fn add_dataset(mut self, dataset: DatasetId) -> Self {
58        self.datasets.push(dataset);
59        self
60    }
61
62    /// Set backends to test.
63    pub fn with_backends(mut self, backends: Vec<String>) -> Self {
64        self.backends = backends;
65        self
66    }
67
68    /// Add a backend.
69    pub fn add_backend(mut self, backend: String) -> Self {
70        self.backends.push(backend);
71        self
72    }
73
74    /// Set maximum examples per dataset.
75    ///
76    /// If `max` is 0, this is treated as unlimited (None).
77    /// Otherwise, limits evaluation to the specified number of examples per dataset.
78    pub fn with_max_examples(mut self, max: usize) -> Self {
79        if max > 0 {
80            self.max_examples = Some(max);
81        } else {
82            self.max_examples = None; // 0 means unlimited
83        }
84        self
85    }
86
87    /// Set random seed.
88    pub fn with_seed(mut self, seed: u64) -> Self {
89        self.seed = Some(seed);
90        self
91    }
92
93    /// Require datasets to be cached (skip downloads).
94    pub fn require_cached(mut self, require: bool) -> Self {
95        self.require_cached = require;
96        self
97    }
98
99    /// Set relation extraction threshold.
100    pub fn with_relation_threshold(mut self, threshold: f32) -> Self {
101        self.relation_threshold = threshold;
102        self
103    }
104
105    /// Enable robustness testing.
106    pub fn with_robustness(mut self, enable: bool) -> Self {
107        self.robustness = enable;
108        self
109    }
110
111    /// Enable familiarity computation.
112    pub fn with_familiarity(mut self, enable: bool) -> Self {
113        self.compute_familiarity = enable;
114        self
115    }
116
117    /// Enable temporal stratification.
118    pub fn with_temporal_stratification(mut self, enable: bool) -> Self {
119        self.temporal_stratification = enable;
120        self
121    }
122
123    /// Enable confidence intervals.
124    pub fn with_confidence_intervals(mut self, enable: bool) -> Self {
125        self.confidence_intervals = enable;
126        self
127    }
128
129    /// Coreference evaluation: use gold mentions (evaluate clustering only).
130    pub fn with_coref_use_gold_mentions(mut self, enable: bool) -> Self {
131        self.coref_use_gold_mentions = enable;
132        self
133    }
134
135    /// Build the configuration.
136    pub fn build(self) -> crate::eval::task_evaluator::TaskEvalConfig {
137        crate::eval::task_evaluator::TaskEvalConfig {
138            tasks: self.tasks,
139            datasets: self.datasets,
140            backends: self.backends,
141            max_examples: self.max_examples,
142            seed: self.seed,
143            require_cached: self.require_cached,
144            relation_threshold: self.relation_threshold,
145            robustness: self.robustness,
146            compute_familiarity: self.compute_familiarity,
147            temporal_stratification: self.temporal_stratification,
148            confidence_intervals: self.confidence_intervals,
149            custom_coref_resolver: None,
150            coref_use_gold_mentions: self.coref_use_gold_mentions,
151        }
152    }
153}
154
155#[cfg(feature = "eval")]
156impl Default for TaskEvalConfigBuilder {
157    fn default() -> Self {
158        Self {
159            tasks: vec![],
160            datasets: vec![],
161            backends: vec![],
162            max_examples: None,
163            seed: Some(42),
164            require_cached: false,
165            relation_threshold: 0.5f32,
166            robustness: false,
167            compute_familiarity: true,
168            temporal_stratification: false,
169            confidence_intervals: true,
170            coref_use_gold_mentions: false,
171        }
172    }
173}
174
175/// Builder for BiasDatasetConfig.
176#[derive(Debug, Clone)]
177#[cfg(feature = "eval-bias")]
178pub struct BiasDatasetConfigBuilder {
179    frequency_weighted: bool,
180    validate_distributions: bool,
181    min_samples_per_category: usize,
182    evaluation_seeds: Vec<u64>,
183    confidence_level: f64,
184    detailed: bool,
185}
186
187#[cfg(feature = "eval-bias")]
188impl BiasDatasetConfigBuilder {
189    /// Create a new builder with defaults.
190    pub fn new() -> Self {
191        Self::default()
192    }
193
194    /// Enable frequency-weighted evaluation.
195    pub fn with_frequency_weighting(mut self, enable: bool) -> Self {
196        self.frequency_weighted = enable;
197        self
198    }
199
200    /// Enable distribution validation.
201    pub fn with_validation(mut self, enable: bool) -> Self {
202        self.validate_distributions = enable;
203        self
204    }
205
206    /// Set minimum samples per category.
207    pub fn with_min_samples(mut self, min: usize) -> Self {
208        self.min_samples_per_category = min;
209        self
210    }
211
212    /// Set evaluation seeds.
213    pub fn with_seeds(mut self, seeds: Vec<u64>) -> Self {
214        self.evaluation_seeds = seeds;
215        self
216    }
217
218    /// Add a seed.
219    pub fn add_seed(mut self, seed: u64) -> Self {
220        self.evaluation_seeds.push(seed);
221        self
222    }
223
224    /// Set confidence level (e.g., 0.95 for 95% CI).
225    pub fn with_confidence_level(mut self, level: f64) -> Self {
226        self.confidence_level = level;
227        self
228    }
229
230    /// Enable detailed results.
231    pub fn with_detailed(mut self, detailed: bool) -> Self {
232        self.detailed = detailed;
233        self
234    }
235
236    /// Build the configuration.
237    pub fn build(self) -> BiasDatasetConfig {
238        BiasDatasetConfig {
239            frequency_weighted: self.frequency_weighted,
240            validate_distributions: self.validate_distributions,
241            min_samples_per_category: self.min_samples_per_category,
242            evaluation_seeds: self.evaluation_seeds,
243            confidence_level: self.confidence_level,
244            detailed: self.detailed,
245        }
246    }
247}
248
249#[cfg(feature = "eval-bias")]
250impl Default for BiasDatasetConfigBuilder {
251    fn default() -> Self {
252        Self {
253            frequency_weighted: false,
254            validate_distributions: false,
255            min_samples_per_category: 10,
256            evaluation_seeds: vec![42],
257            confidence_level: 0.95,
258            detailed: false,
259        }
260    }
261}