1use std::{fmt::Display, ops::Deref, sync::Arc};
2
3use indexmap::IndexMap;
4use serde::{Deserialize, Serialize};
5
6#[cfg(feature = "mpi")]
7use super::dataset::MpiDatasetLayout;
8use super::{Dataset, DatasetMetadata};
9use crate::{
10 variables::Variable,
11 vectors::{Vec3, Vec4},
12};
13
14pub fn test_event() -> EventData {
18 let pol_magnitude = 0.38562805;
19 let pol_angle = 0.05708078;
20 EventData {
21 p4s: vec![
22 Vec3::new(0.0, 0.0, 8.747).with_mass(0.0),
23 Vec3::new(0.119, 0.374, 0.222).with_mass(1.007),
24 Vec3::new(-0.112, 0.293, 3.081).with_mass(0.498),
25 Vec3::new(-0.007, -0.667, 5.446).with_mass(0.498),
26 ],
27 aux: vec![pol_magnitude, pol_angle],
28 weight: 0.48,
29 }
30}
31
32#[derive(Debug, Clone, Default, Serialize, Deserialize)]
38pub struct EventData {
39 pub p4s: Vec<Vec4>,
41 pub aux: Vec<f64>,
43 pub weight: f64,
45}
46
47impl Display for EventData {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 writeln!(f, "Event:")?;
50 writeln!(f, " p4s:")?;
51 for p4 in &self.p4s {
52 writeln!(f, " {}", p4.to_p4_string())?;
53 }
54 writeln!(f, " aux:")?;
55 for (idx, value) in self.aux.iter().enumerate() {
56 writeln!(f, " aux[{idx}]: {value}")?;
57 }
58 writeln!(f, " weight:")?;
59 writeln!(f, " {}", self.weight)?;
60 Ok(())
61 }
62}
63
64impl EventData {
65 pub fn get_p4_sum<T: AsRef<[usize]>>(&self, indices: T) -> Vec4 {
67 indices.as_ref().iter().map(|i| self.p4s[*i]).sum::<Vec4>()
68 }
69
70 pub fn boost_to_rest_frame_of<T: AsRef<[usize]>>(&self, indices: T) -> Self {
73 let frame = self.get_p4_sum(indices);
74 EventData {
75 p4s: self
76 .p4s
77 .iter()
78 .map(|p4| p4.boost(&(-frame.beta())))
79 .collect(),
80 aux: self.aux.clone(),
81 weight: self.weight,
82 }
83 }
84}
85
86#[derive(Debug, Clone, Default)]
87pub struct ColumnarP4Column {
89 pub(crate) px: Vec<f64>,
90 pub(crate) py: Vec<f64>,
91 pub(crate) pz: Vec<f64>,
92 pub(crate) e: Vec<f64>,
93}
94
95impl ColumnarP4Column {
96 pub fn with_capacity(capacity: usize) -> Self {
98 Self {
99 px: Vec::with_capacity(capacity),
100 py: Vec::with_capacity(capacity),
101 pz: Vec::with_capacity(capacity),
102 e: Vec::with_capacity(capacity),
103 }
104 }
105
106 pub fn push(&mut self, p4: Vec4) {
108 self.px.push(p4.x);
109 self.py.push(p4.y);
110 self.pz.push(p4.z);
111 self.e.push(p4.t);
112 }
113
114 pub fn len(&self) -> usize {
116 self.px.len()
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.px.is_empty()
122 }
123
124 pub fn get(&self, event_index: usize) -> Vec4 {
126 Vec4::new(
127 self.px[event_index],
128 self.py[event_index],
129 self.pz[event_index],
130 self.e[event_index],
131 )
132 }
133}
134
135#[derive(Debug, Default)]
137pub struct DatasetStorage {
138 pub(crate) metadata: Arc<DatasetMetadata>,
139 pub(crate) p4: Vec<ColumnarP4Column>,
140 pub(crate) aux: Vec<Vec<f64>>,
141 pub(crate) weights: Vec<f64>,
142}
143
144impl Clone for DatasetStorage {
145 fn clone(&self) -> Self {
146 Self {
147 metadata: self.metadata.clone(),
148 p4: self.p4.clone(),
149 aux: self.aux.clone(),
150 weights: self.weights.clone(),
151 }
152 }
153}
154
155impl DatasetStorage {
156 pub fn new(
158 metadata: DatasetMetadata,
159 p4: Vec<ColumnarP4Column>,
160 aux: Vec<Vec<f64>>,
161 weights: Vec<f64>,
162 ) -> Self {
163 Self {
164 metadata: Arc::new(metadata),
165 p4,
166 aux,
167 weights,
168 }
169 }
170
171 pub(crate) fn empty_with_capacity(metadata: Arc<DatasetMetadata>, capacity: usize) -> Self {
173 Self {
174 p4: (0..metadata.p4_names().len())
175 .map(|_| ColumnarP4Column::with_capacity(capacity))
176 .collect(),
177 aux: (0..metadata.aux_names().len())
178 .map(|_| Vec::with_capacity(capacity))
179 .collect(),
180 weights: Vec::with_capacity(capacity),
181 metadata,
182 }
183 }
184
185 pub(crate) fn push_event_data(&mut self, event: &EventData) {
187 for (column, p4) in self.p4.iter_mut().zip(&event.p4s) {
188 column.push(*p4);
189 }
190 for (column, value) in self.aux.iter_mut().zip(&event.aux) {
191 column.push(*value);
192 }
193 self.weights.push(event.weight);
194 }
195
196 pub(crate) fn set_metadata(&mut self, metadata: Arc<DatasetMetadata>) {
197 self.metadata = metadata;
198 }
199
200 pub(crate) fn push_p4_column(&mut self, values: Vec<Vec4>) {
201 let mut column = ColumnarP4Column::with_capacity(values.len());
202 for value in values {
203 column.push(value);
204 }
205 self.p4.push(column);
206 }
207
208 pub(crate) fn push_aux_column(&mut self, values: Vec<f64>) {
209 self.aux.push(values);
210 }
211
212 pub fn to_dataset(&self) -> Dataset {
214 let events = (0..self.n_events())
215 .map(|event_index| Arc::new(self.event_data(event_index)))
216 .collect::<Vec<_>>();
217 #[cfg(not(feature = "mpi"))]
218 let dataset = Dataset::new_local(events, self.metadata.clone());
219 #[cfg(feature = "mpi")]
220 let mut dataset = Dataset::new_local(events, self.metadata.clone());
221 #[cfg(feature = "mpi")]
222 {
223 if let Some(world) = crate::mpi::get_world() {
224 dataset.mpi_layout = Some(MpiDatasetLayout::Canonical);
225 dataset.set_cached_global_event_count_from_world(&world);
226 dataset.set_cached_global_weighted_sum_from_world(&world);
227 }
228 }
229 dataset
230 }
231
232 pub(crate) fn metadata(&self) -> &DatasetMetadata {
234 &self.metadata
235 }
236
237 pub(crate) fn n_events(&self) -> usize {
239 self.weights.len()
240 }
241
242 pub(crate) fn p4(&self, event_index: usize, p4_index: usize) -> Vec4 {
244 self.p4[p4_index].get(event_index)
245 }
246
247 pub(crate) fn aux(&self, event_index: usize, aux_index: usize) -> f64 {
249 self.aux[aux_index][event_index]
250 }
251
252 pub(crate) fn weight(&self, event_index: usize) -> f64 {
254 self.weights[event_index]
255 }
256
257 pub(crate) fn event_data(&self, event_index: usize) -> EventData {
258 let mut p4s = Vec::with_capacity(self.p4.len());
259 for p4_index in 0..self.p4.len() {
260 p4s.push(self.p4(event_index, p4_index));
261 }
262 let mut aux = Vec::with_capacity(self.aux.len());
263 for aux_index in 0..self.aux.len() {
264 aux.push(self.aux(event_index, aux_index));
265 }
266 EventData {
267 p4s,
268 aux,
269 weight: self.weight(event_index),
270 }
271 }
272
273 fn row_view(&self, event_index: usize) -> ColumnarEventView<'_> {
274 ColumnarEventView {
275 storage: self,
276 event_index,
277 }
278 }
279
280 #[allow(dead_code)]
281 pub(crate) fn for_each_event_local<F>(&self, mut op: F)
282 where
283 F: FnMut(usize, Event<'_>),
284 {
285 for event_index in 0..self.n_events() {
286 let row = self.row_view(event_index);
287 let view = Event {
288 row: EventRow::Columnar(row),
289 metadata: &self.metadata,
290 };
291 op(event_index, view);
292 }
293 }
294
295 pub(crate) fn event_view(&self, event_index: usize) -> Event<'_> {
296 let row = self.row_view(event_index);
297 Event {
298 row: EventRow::Columnar(row),
299 metadata: self.metadata(),
300 }
301 }
302}
303
304#[derive(Debug)]
305struct ColumnarEventView<'a> {
306 storage: &'a DatasetStorage,
307 event_index: usize,
308}
309
310#[allow(dead_code)]
311impl ColumnarEventView<'_> {
312 fn p4(&self, p4_index: usize) -> Vec4 {
313 self.storage.p4(self.event_index, p4_index)
314 }
315
316 fn aux(&self, aux_index: usize) -> f64 {
317 self.storage.aux(self.event_index, aux_index)
318 }
319
320 fn weight(&self) -> f64 {
321 self.storage.weight(self.event_index)
322 }
323}
324
325#[derive(Debug)]
326enum EventRow<'a> {
327 Columnar(ColumnarEventView<'a>),
328 Owned(&'a EventData),
329}
330
331impl EventRow<'_> {
332 fn p4(&self, p4_index: usize) -> Vec4 {
333 match self {
334 Self::Columnar(row) => row.p4(p4_index),
335 Self::Owned(event) => event.p4s[p4_index],
336 }
337 }
338
339 fn aux(&self, aux_index: usize) -> f64 {
340 match self {
341 Self::Columnar(row) => row.aux(aux_index),
342 Self::Owned(event) => event.aux[aux_index],
343 }
344 }
345
346 fn weight(&self) -> f64 {
347 match self {
348 Self::Columnar(row) => row.weight(),
349 Self::Owned(event) => event.weight,
350 }
351 }
352
353 fn n_p4(&self) -> usize {
354 match self {
355 Self::Columnar(row) => row.storage.p4.len(),
356 Self::Owned(event) => event.p4s.len(),
357 }
358 }
359
360 fn n_aux(&self) -> usize {
361 match self {
362 Self::Columnar(row) => row.storage.aux.len(),
363 Self::Owned(event) => event.aux.len(),
364 }
365 }
366}
367
368#[derive(Debug)]
370pub struct Event<'a> {
371 row: EventRow<'a>,
372 metadata: &'a DatasetMetadata,
373}
374
375pub trait EventLike {
377 fn p4_at(&self, p4_index: usize) -> Vec4;
379
380 fn aux_at(&self, aux_index: usize) -> f64;
382
383 fn n_p4(&self) -> usize;
385
386 fn n_aux(&self) -> usize;
388
389 fn weight(&self) -> f64;
391
392 fn metadata(&self) -> &DatasetMetadata;
394
395 fn p4(&self, name: &str) -> Option<Vec4> {
397 let selection = self.metadata().p4_selection(name)?;
398 Some(
399 selection
400 .indices()
401 .iter()
402 .map(|index| self.p4_at(*index))
403 .sum(),
404 )
405 }
406
407 fn aux(&self, name: &str) -> Option<f64> {
409 let index = self.metadata().aux_index(name)?;
410 Some(self.aux_at(index))
411 }
412
413 fn get_p4_sum<N>(&self, names: N) -> Option<Vec4>
415 where
416 Self: Sized,
417 N: IntoIterator,
418 N::Item: AsRef<str>,
419 {
420 names
421 .into_iter()
422 .map(|name| self.p4(name.as_ref()))
423 .collect::<Option<Vec<_>>>()
424 .map(|momenta| momenta.into_iter().sum())
425 }
426}
427
428impl EventLike for Event<'_> {
429 fn p4_at(&self, p4_index: usize) -> Vec4 {
431 self.row.p4(p4_index)
432 }
433
434 fn aux_at(&self, aux_index: usize) -> f64 {
436 self.row.aux(aux_index)
437 }
438
439 fn n_p4(&self) -> usize {
441 self.row.n_p4()
442 }
443
444 fn n_aux(&self) -> usize {
446 self.row.n_aux()
447 }
448
449 fn weight(&self) -> f64 {
451 self.row.weight()
452 }
453
454 fn metadata(&self) -> &DatasetMetadata {
455 self.metadata
456 }
457}
458
459impl Event<'_> {
460 pub fn p4_at(&self, p4_index: usize) -> Vec4 {
462 EventLike::p4_at(self, p4_index)
463 }
464
465 pub fn aux_at(&self, aux_index: usize) -> f64 {
467 EventLike::aux_at(self, aux_index)
468 }
469
470 pub fn n_p4(&self) -> usize {
472 EventLike::n_p4(self)
473 }
474
475 pub fn n_aux(&self) -> usize {
477 EventLike::n_aux(self)
478 }
479
480 pub fn p4(&self, name: &str) -> Option<Vec4> {
482 EventLike::p4(self, name)
483 }
484
485 pub fn aux(&self, name: &str) -> Option<f64> {
487 EventLike::aux(self, name)
488 }
489
490 pub fn weight(&self) -> f64 {
492 EventLike::weight(self)
493 }
494
495 pub fn to_event_data(&self) -> EventData {
497 EventData {
498 p4s: (0..self.n_p4()).map(|index| self.p4_at(index)).collect(),
499 aux: (0..self.n_aux()).map(|index| self.aux_at(index)).collect(),
500 weight: self.weight(),
501 }
502 }
503
504 pub fn get_p4_sum<N>(&self, names: N) -> Option<Vec4>
506 where
507 N: IntoIterator,
508 N::Item: AsRef<str>,
509 {
510 EventLike::get_p4_sum(self, names)
511 }
512
513 pub fn evaluate<V: Variable>(&self, variable: &V) -> f64 {
515 variable.value(self)
516 }
517}
518
519impl Display for Event<'_> {
520 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
521 writeln!(f, "Event:")?;
522 writeln!(f, " p4s:")?;
523 for index in 0..self.n_p4() {
524 let label = self
525 .metadata
526 .p4_names()
527 .get(index)
528 .map_or_else(|| format!("p4[{index}]"), Clone::clone);
529 writeln!(f, " {label}: {}", self.p4_at(index).to_p4_string())?;
530 }
531 writeln!(f, " aux:")?;
532 for index in 0..self.n_aux() {
533 let label = self
534 .metadata
535 .aux_names()
536 .get(index)
537 .map_or_else(|| format!("aux[{index}]"), Clone::clone);
538 writeln!(f, " {label}: {}", self.aux_at(index))?;
539 }
540 writeln!(f, " weight:")?;
541 writeln!(f, " {}", self.weight())?;
542 Ok(())
543 }
544}
545
546#[derive(Clone, Debug)]
552pub struct OwnedEvent {
553 event: Arc<EventData>,
554 metadata: Arc<DatasetMetadata>,
555}
556
557impl OwnedEvent {
558 pub fn new(event: Arc<EventData>, metadata: Arc<DatasetMetadata>) -> Self {
560 Self { event, metadata }
561 }
562
563 pub fn data(&self) -> &EventData {
565 &self.event
566 }
567
568 pub fn data_arc(&self) -> Arc<EventData> {
570 self.event.clone()
571 }
572
573 pub fn as_event(&self) -> Event<'_> {
575 Event {
576 row: EventRow::Owned(&self.event),
577 metadata: &self.metadata,
578 }
579 }
580
581 pub fn p4s(&self) -> IndexMap<&str, Vec4> {
583 let mut map = IndexMap::with_capacity(self.metadata.p4_names.len());
584 for (idx, name) in self.metadata.p4_names.iter().enumerate() {
585 if let Some(p4) = self.event.p4s.get(idx) {
586 map.insert(name.as_str(), *p4);
587 }
588 }
589 map
590 }
591
592 pub fn aux(&self) -> IndexMap<&str, f64> {
594 let mut map = IndexMap::with_capacity(self.metadata.aux_names.len());
595 for (idx, name) in self.metadata.aux_names.iter().enumerate() {
596 if let Some(value) = self.event.aux.get(idx) {
597 map.insert(name.as_str(), *value);
598 }
599 }
600 map
601 }
602
603 pub fn weight(&self) -> f64 {
605 self.event.weight
606 }
607
608 pub fn metadata(&self) -> &DatasetMetadata {
610 &self.metadata
611 }
612
613 pub fn metadata_arc(&self) -> Arc<DatasetMetadata> {
615 self.metadata.clone()
616 }
617
618 pub fn p4(&self, name: &str) -> Option<Vec4> {
620 EventLike::p4(self, name)
621 }
622
623 fn resolve_p4_indices<N>(&self, names: N) -> Vec<usize>
624 where
625 N: IntoIterator,
626 N::Item: AsRef<str>,
627 {
628 let mut indices = Vec::new();
629 for name in names {
630 let name_ref = name.as_ref();
631 if let Some(selection) = self.metadata.p4_selection(name_ref) {
632 indices.extend_from_slice(selection.indices());
633 } else {
634 panic!("Unknown particle name '{name}'", name = name_ref);
635 }
636 }
637 indices
638 }
639
640 pub fn get_p4_sum<N>(&self, names: N) -> Vec4
642 where
643 N: IntoIterator,
644 N::Item: AsRef<str>,
645 {
646 let indices = self.resolve_p4_indices(names);
647 self.event.get_p4_sum(&indices)
648 }
649
650 pub fn boost_to_rest_frame_of<N>(&self, names: N) -> EventData
652 where
653 N: IntoIterator,
654 N::Item: AsRef<str>,
655 {
656 let indices = self.resolve_p4_indices(names);
657 self.event.boost_to_rest_frame_of(&indices)
658 }
659}
660
661impl EventLike for OwnedEvent {
662 fn p4_at(&self, p4_index: usize) -> Vec4 {
663 self.event.p4s[p4_index]
664 }
665
666 fn aux_at(&self, aux_index: usize) -> f64 {
667 self.event.aux[aux_index]
668 }
669
670 fn n_p4(&self) -> usize {
671 self.event.p4s.len()
672 }
673
674 fn n_aux(&self) -> usize {
675 self.event.aux.len()
676 }
677
678 fn weight(&self) -> f64 {
679 self.event.weight
680 }
681
682 fn metadata(&self) -> &DatasetMetadata {
683 &self.metadata
684 }
685}
686
687impl Display for OwnedEvent {
688 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
689 self.as_event().fmt(f)
690 }
691}
692
693impl Deref for OwnedEvent {
694 type Target = EventData;
695
696 fn deref(&self) -> &Self::Target {
697 &self.event
698 }
699}
700
701impl AsRef<EventData> for OwnedEvent {
702 fn as_ref(&self) -> &EventData {
703 self.data()
704 }
705}