Skip to main content

endf_mat/
mat.rs

1//! ENDF MAT (material) number lookup.
2//!
3//! MAT numbers are the ENDF material identifiers used to retrieve evaluated
4//! nuclear data files. This table covers 535 ground-state isotopes from the
5//! ENDF/B-VIII.0 neutrons sublibrary.
6//!
7//! Data source: PLEIADES `neutrons.list` (ENDF/B-VIII.0), metastable states excluded.
8
9/// Look up the ENDF MAT number for a ground-state isotope (Z, A).
10///
11/// Returns `None` if the isotope is not in the ENDF/B-VIII.0 neutrons sublibrary.
12///
13/// # Examples
14/// ```
15/// assert_eq!(endf_mat::mat_number(92, 235), Some(9228));
16/// assert_eq!(endf_mat::mat_number(92, 238), Some(9237));
17/// assert_eq!(endf_mat::mat_number(26, 56), Some(2631));
18/// ```
19pub fn mat_number(z: u32, a: u32) -> Option<u32> {
20    // Binary search on (Z, A) key. Table is sorted by Z then A.
21    ENDF_MAT_TABLE
22        .binary_search_by(|&(tz, ta, _)| (tz, ta).cmp(&(z, a)))
23        .ok()
24        .map(|idx| ENDF_MAT_TABLE[idx].2)
25}
26
27/// Reverse lookup: MAT number → (Z, A).
28///
29/// Returns `None` if the MAT number is not in the table.
30///
31/// # Examples
32/// ```
33/// assert_eq!(endf_mat::isotope_from_mat(9228), Some((92, 235)));
34/// assert_eq!(endf_mat::isotope_from_mat(9999), None);
35/// ```
36pub fn isotope_from_mat(mat: u32) -> Option<(u32, u32)> {
37    // Linear scan — reverse lookups are rare.
38    ENDF_MAT_TABLE
39        .iter()
40        .find(|&&(_, _, m)| m == mat)
41        .map(|&(z, a, _)| (z, a))
42}
43
44/// All mass numbers with ENDF/B-VIII.0 evaluations for element Z.
45///
46/// Returns every A value in the MAT table for the given atomic number Z,
47/// including synthetic and transuranic isotopes. Returns an empty `Vec`
48/// for elements with no evaluations.
49///
50/// # Examples
51/// ```
52/// let pu = endf_mat::known_isotopes(94);
53/// assert!(pu.contains(&239));
54///
55/// let tc = endf_mat::known_isotopes(43);
56/// assert_eq!(tc, vec![98, 99]);
57/// ```
58pub fn known_isotopes(z: u32) -> Vec<u32> {
59    let start = ENDF_MAT_TABLE.partition_point(|&(tz, _, _)| tz < z);
60    ENDF_MAT_TABLE[start..]
61        .iter()
62        .take_while(|&&(tz, _, _)| tz == z)
63        .map(|&(_, a, _)| a)
64        .collect()
65}
66
67/// Whether the ENDF/B-VIII.0 neutrons sublibrary has an evaluation for (Z, A).
68///
69/// # Examples
70/// ```
71/// assert!(endf_mat::has_endf_evaluation(94, 239));  // Pu-239
72/// assert!(!endf_mat::has_endf_evaluation(94, 999)); // no such isotope
73/// ```
74pub fn has_endf_evaluation(z: u32, a: u32) -> bool {
75    mat_number(z, a).is_some()
76}
77
78// Auto-generated from ENDF/B-VIII.0 neutrons.list
79// 535 ground-state isotopes (metastable states excluded)
80// Format: (Z, A, MAT) — sorted by (Z, A)
81#[rustfmt::skip]
82static ENDF_MAT_TABLE: &[(u32, u32, u32)] = &[
83    (0, 1, 25),
84    (1, 1, 125),
85    (1, 2, 128),
86    (1, 3, 131),
87    (2, 3, 225),
88    (2, 4, 228),
89    (3, 6, 325),
90    (3, 7, 328),
91    (4, 7, 419),
92    (4, 9, 425),
93    (5, 10, 525),
94    (5, 11, 528),
95    (6, 12, 625),
96    (6, 13, 628),
97    (7, 14, 725),
98    (7, 15, 728),
99    (8, 16, 825),
100    (8, 17, 828),
101    (8, 18, 831),
102    (9, 19, 925),
103    (10, 20, 1025),
104    (10, 21, 1028),
105    (10, 22, 1031),
106    (11, 22, 1122),
107    (11, 23, 1125),
108    (12, 24, 1225),
109    (12, 25, 1228),
110    (12, 26, 1231),
111    (13, 27, 1325),
112    (14, 28, 1425),
113    (14, 29, 1428),
114    (14, 30, 1431),
115    (14, 31, 1434),
116    (14, 32, 1437),
117    (15, 31, 1525),
118    (16, 32, 1625),
119    (16, 33, 1628),
120    (16, 34, 1631),
121    (16, 35, 1634),
122    (16, 36, 1637),
123    (17, 35, 1725),
124    (17, 36, 1728),
125    (17, 37, 1731),
126    (18, 36, 1825),
127    (18, 37, 1828),
128    (18, 38, 1831),
129    (18, 39, 1834),
130    (18, 40, 1837),
131    (18, 41, 1840),
132    (19, 39, 1925),
133    (19, 40, 1928),
134    (19, 41, 1931),
135    (20, 40, 2025),
136    (20, 41, 2028),
137    (20, 42, 2031),
138    (20, 43, 2034),
139    (20, 44, 2037),
140    (20, 45, 2040),
141    (20, 46, 2043),
142    (20, 47, 2046),
143    (20, 48, 2049),
144    (21, 45, 2125),
145    (22, 46, 2225),
146    (22, 47, 2228),
147    (22, 48, 2231),
148    (22, 49, 2234),
149    (22, 50, 2237),
150    (23, 49, 2322),
151    (23, 50, 2325),
152    (23, 51, 2328),
153    (24, 50, 2425),
154    (24, 51, 2428),
155    (24, 52, 2431),
156    (24, 53, 2434),
157    (24, 54, 2437),
158    (25, 54, 2522),
159    (25, 55, 2525),
160    (26, 54, 2625),
161    (26, 55, 2628),
162    (26, 56, 2631),
163    (26, 57, 2634),
164    (26, 58, 2637),
165    (27, 58, 2722),
166    (27, 59, 2725),
167    (28, 58, 2825),
168    (28, 59, 2828),
169    (28, 60, 2831),
170    (28, 61, 2834),
171    (28, 62, 2837),
172    (28, 63, 2840),
173    (28, 64, 2843),
174    (29, 63, 2925),
175    (29, 64, 2928),
176    (29, 65, 2931),
177    (30, 64, 3025),
178    (30, 65, 3028),
179    (30, 66, 3031),
180    (30, 67, 3034),
181    (30, 68, 3037),
182    (30, 69, 3040),
183    (30, 70, 3043),
184    (31, 69, 3125),
185    (31, 70, 3128),
186    (31, 71, 3131),
187    (32, 70, 3225),
188    (32, 71, 3228),
189    (32, 72, 3231),
190    (32, 73, 3234),
191    (32, 74, 3237),
192    (32, 75, 3240),
193    (32, 76, 3243),
194    (33, 73, 3319),
195    (33, 74, 3322),
196    (33, 75, 3325),
197    (34, 74, 3425),
198    (34, 75, 3428),
199    (34, 76, 3431),
200    (34, 77, 3434),
201    (34, 78, 3437),
202    (34, 79, 3440),
203    (34, 80, 3443),
204    (34, 81, 3446),
205    (34, 82, 3449),
206    (35, 79, 3525),
207    (35, 80, 3528),
208    (35, 81, 3531),
209    (36, 78, 3625),
210    (36, 79, 3628),
211    (36, 80, 3631),
212    (36, 81, 3634),
213    (36, 82, 3637),
214    (36, 83, 3640),
215    (36, 84, 3643),
216    (36, 85, 3646),
217    (36, 86, 3649),
218    (37, 85, 3725),
219    (37, 86, 3728),
220    (37, 87, 3731),
221    (38, 84, 3825),
222    (38, 85, 3828),
223    (38, 86, 3831),
224    (38, 87, 3834),
225    (38, 88, 3837),
226    (38, 89, 3840),
227    (38, 90, 3843),
228    (39, 89, 3925),
229    (39, 90, 3928),
230    (39, 91, 3931),
231    (40, 90, 4025),
232    (40, 91, 4028),
233    (40, 92, 4031),
234    (40, 93, 4034),
235    (40, 94, 4037),
236    (40, 95, 4040),
237    (40, 96, 4043),
238    (41, 93, 4125),
239    (41, 94, 4128),
240    (41, 95, 4131),
241    (42, 92, 4225),
242    (42, 93, 4228),
243    (42, 94, 4231),
244    (42, 95, 4234),
245    (42, 96, 4237),
246    (42, 97, 4240),
247    (42, 98, 4243),
248    (42, 99, 4246),
249    (42, 100, 4249),
250    (43, 98, 4322),
251    (43, 99, 4325),
252    (44, 96, 4425),
253    (44, 97, 4428),
254    (44, 98, 4431),
255    (44, 99, 4434),
256    (44, 100, 4437),
257    (44, 101, 4440),
258    (44, 102, 4443),
259    (44, 103, 4446),
260    (44, 104, 4449),
261    (44, 105, 4452),
262    (44, 106, 4455),
263    (45, 103, 4525),
264    (45, 104, 4528),
265    (45, 105, 4531),
266    (46, 102, 4625),
267    (46, 103, 4628),
268    (46, 104, 4631),
269    (46, 105, 4634),
270    (46, 106, 4637),
271    (46, 107, 4640),
272    (46, 108, 4643),
273    (46, 109, 4646),
274    (46, 110, 4649),
275    (47, 107, 4725),
276    (47, 108, 4728),
277    (47, 109, 4731),
278    (47, 111, 4737),
279    (47, 112, 4740),
280    (47, 113, 4743),
281    (47, 114, 4746),
282    (47, 115, 4749),
283    (47, 116, 4752),
284    (47, 117, 4755),
285    (48, 106, 4825),
286    (48, 107, 4828),
287    (48, 108, 4831),
288    (48, 109, 4834),
289    (48, 110, 4837),
290    (48, 111, 4840),
291    (48, 112, 4843),
292    (48, 113, 4846),
293    (48, 114, 4849),
294    (48, 116, 4855),
295    (49, 113, 4925),
296    (49, 114, 4928),
297    (49, 115, 4931),
298    (50, 112, 5025),
299    (50, 113, 5028),
300    (50, 114, 5031),
301    (50, 115, 5034),
302    (50, 116, 5037),
303    (50, 117, 5040),
304    (50, 118, 5043),
305    (50, 119, 5046),
306    (50, 120, 5049),
307    (50, 122, 5055),
308    (50, 123, 5058),
309    (50, 124, 5061),
310    (50, 125, 5064),
311    (50, 126, 5067),
312    (51, 121, 5125),
313    (51, 122, 5128),
314    (51, 123, 5131),
315    (51, 124, 5134),
316    (51, 125, 5137),
317    (51, 126, 5140),
318    (52, 120, 5225),
319    (52, 121, 5228),
320    (52, 122, 5231),
321    (52, 123, 5234),
322    (52, 124, 5237),
323    (52, 125, 5240),
324    (52, 126, 5243),
325    (52, 128, 5249),
326    (52, 130, 5255),
327    (52, 131, 5258),
328    (52, 132, 5261),
329    (53, 127, 5325),
330    (53, 128, 5328),
331    (53, 129, 5331),
332    (53, 130, 5334),
333    (53, 131, 5337),
334    (53, 132, 5340),
335    (53, 133, 5343),
336    (53, 134, 5346),
337    (53, 135, 5349),
338    (54, 123, 5422),
339    (54, 124, 5425),
340    (54, 125, 5428),
341    (54, 126, 5431),
342    (54, 127, 5434),
343    (54, 128, 5437),
344    (54, 129, 5440),
345    (54, 130, 5443),
346    (54, 131, 5446),
347    (54, 132, 5449),
348    (54, 133, 5452),
349    (54, 134, 5455),
350    (54, 135, 5458),
351    (54, 136, 5461),
352    (55, 133, 5525),
353    (55, 134, 5528),
354    (55, 135, 5531),
355    (55, 136, 5534),
356    (55, 137, 5537),
357    (56, 130, 5625),
358    (56, 131, 5628),
359    (56, 132, 5631),
360    (56, 133, 5634),
361    (56, 134, 5637),
362    (56, 135, 5640),
363    (56, 136, 5643),
364    (56, 137, 5646),
365    (56, 138, 5649),
366    (56, 139, 5652),
367    (56, 140, 5655),
368    (57, 138, 5725),
369    (57, 139, 5728),
370    (57, 140, 5731),
371    (58, 136, 5825),
372    (58, 137, 5828),
373    (58, 138, 5831),
374    (58, 139, 5834),
375    (58, 140, 5837),
376    (58, 141, 5840),
377    (58, 142, 5843),
378    (58, 143, 5846),
379    (58, 144, 5849),
380    (59, 141, 5925),
381    (59, 142, 5928),
382    (59, 143, 5931),
383    (60, 142, 6025),
384    (60, 143, 6028),
385    (60, 144, 6031),
386    (60, 145, 6034),
387    (60, 146, 6037),
388    (60, 147, 6040),
389    (60, 148, 6043),
390    (60, 149, 6046),
391    (60, 150, 6049),
392    (61, 143, 6137),
393    (61, 144, 6140),
394    (61, 145, 6143),
395    (61, 146, 6146),
396    (61, 147, 6149),
397    (61, 148, 6152),
398    (61, 149, 6155),
399    (61, 150, 6158),
400    (61, 151, 6161),
401    (62, 144, 6225),
402    (62, 145, 6228),
403    (62, 146, 6231),
404    (62, 147, 6234),
405    (62, 148, 6237),
406    (62, 149, 6240),
407    (62, 150, 6243),
408    (62, 151, 6246),
409    (62, 152, 6249),
410    (62, 153, 6252),
411    (62, 154, 6255),
412    (63, 151, 6325),
413    (63, 152, 6328),
414    (63, 153, 6331),
415    (63, 154, 6334),
416    (63, 155, 6337),
417    (63, 156, 6340),
418    (63, 157, 6343),
419    (64, 152, 6425),
420    (64, 153, 6428),
421    (64, 154, 6431),
422    (64, 155, 6434),
423    (64, 156, 6437),
424    (64, 157, 6440),
425    (64, 158, 6443),
426    (64, 159, 6446),
427    (64, 160, 6449),
428    (65, 158, 6522),
429    (65, 159, 6525),
430    (65, 160, 6528),
431    (65, 161, 6531),
432    (66, 154, 6619),
433    (66, 155, 6622),
434    (66, 156, 6625),
435    (66, 157, 6628),
436    (66, 158, 6631),
437    (66, 159, 6634),
438    (66, 160, 6637),
439    (66, 161, 6640),
440    (66, 162, 6643),
441    (66, 163, 6646),
442    (66, 164, 6649),
443    (67, 165, 6725),
444    (68, 162, 6825),
445    (68, 163, 6828),
446    (68, 164, 6831),
447    (68, 165, 6834),
448    (68, 166, 6837),
449    (68, 167, 6840),
450    (68, 168, 6843),
451    (68, 169, 6846),
452    (68, 170, 6849),
453    (69, 168, 6922),
454    (69, 169, 6925),
455    (69, 170, 6928),
456    (69, 171, 6931),
457    (70, 168, 7025),
458    (70, 169, 7028),
459    (70, 170, 7031),
460    (70, 171, 7034),
461    (70, 172, 7037),
462    (70, 173, 7040),
463    (70, 174, 7043),
464    (70, 175, 7046),
465    (70, 176, 7049),
466    (71, 175, 7125),
467    (71, 176, 7128),
468    (72, 174, 7225),
469    (72, 175, 7228),
470    (72, 176, 7231),
471    (72, 177, 7234),
472    (72, 178, 7237),
473    (72, 179, 7240),
474    (72, 180, 7243),
475    (72, 181, 7246),
476    (72, 182, 7249),
477    (73, 180, 7325),
478    (73, 181, 7328),
479    (73, 182, 7331),
480    (74, 180, 7425),
481    (74, 181, 7428),
482    (74, 182, 7431),
483    (74, 183, 7434),
484    (74, 184, 7437),
485    (74, 185, 7440),
486    (74, 186, 7443),
487    (75, 185, 7525),
488    (75, 187, 7531),
489    (76, 184, 7625),
490    (76, 185, 7628),
491    (76, 186, 7631),
492    (76, 187, 7634),
493    (76, 188, 7637),
494    (76, 189, 7640),
495    (76, 190, 7643),
496    (76, 191, 7646),
497    (76, 192, 7649),
498    (77, 191, 7725),
499    (77, 192, 7728),
500    (77, 193, 7731),
501    (78, 190, 7825),
502    (78, 191, 7828),
503    (78, 192, 7831),
504    (78, 193, 7834),
505    (78, 194, 7837),
506    (78, 195, 7840),
507    (78, 196, 7843),
508    (78, 197, 7846),
509    (78, 198, 7849),
510    (79, 197, 7925),
511    (80, 196, 8025),
512    (80, 197, 8028),
513    (80, 198, 8031),
514    (80, 199, 8034),
515    (80, 200, 8037),
516    (80, 201, 8040),
517    (80, 202, 8043),
518    (80, 203, 8046),
519    (80, 204, 8049),
520    (81, 203, 8125),
521    (81, 204, 8128),
522    (81, 205, 8131),
523    (82, 204, 8225),
524    (82, 205, 8228),
525    (82, 206, 8231),
526    (82, 207, 8234),
527    (82, 208, 8237),
528    (83, 209, 8325),
529    (84, 208, 8431),
530    (84, 209, 8434),
531    (84, 210, 8437),
532    (88, 223, 8825),
533    (88, 224, 8828),
534    (88, 225, 8831),
535    (88, 226, 8834),
536    (89, 225, 8925),
537    (89, 226, 8928),
538    (89, 227, 8931),
539    (90, 227, 9025),
540    (90, 228, 9028),
541    (90, 229, 9031),
542    (90, 230, 9034),
543    (90, 231, 9037),
544    (90, 232, 9040),
545    (90, 233, 9043),
546    (90, 234, 9046),
547    (91, 229, 9125),
548    (91, 230, 9128),
549    (91, 231, 9131),
550    (91, 232, 9134),
551    (91, 233, 9137),
552    (92, 230, 9213),
553    (92, 231, 9216),
554    (92, 232, 9219),
555    (92, 233, 9222),
556    (92, 234, 9225),
557    (92, 235, 9228),
558    (92, 236, 9231),
559    (92, 237, 9234),
560    (92, 238, 9237),
561    (92, 239, 9240),
562    (92, 240, 9243),
563    (92, 241, 9246),
564    (93, 234, 9337),
565    (93, 235, 9340),
566    (93, 236, 9343),
567    (93, 237, 9346),
568    (93, 238, 9349),
569    (93, 239, 9352),
570    (94, 236, 9428),
571    (94, 237, 9431),
572    (94, 238, 9434),
573    (94, 239, 9437),
574    (94, 240, 9440),
575    (94, 241, 9443),
576    (94, 242, 9446),
577    (94, 243, 9449),
578    (94, 244, 9452),
579    (94, 245, 9455),
580    (94, 246, 9458),
581    (95, 240, 9540),
582    (95, 241, 9543),
583    (95, 242, 9546),
584    (95, 243, 9549),
585    (95, 244, 9552),
586    (96, 240, 9625),
587    (96, 241, 9628),
588    (96, 242, 9631),
589    (96, 243, 9634),
590    (96, 244, 9637),
591    (96, 245, 9640),
592    (96, 246, 9643),
593    (96, 247, 9646),
594    (96, 248, 9649),
595    (96, 249, 9652),
596    (96, 250, 9655),
597    (97, 245, 9740),
598    (97, 246, 9743),
599    (97, 247, 9746),
600    (97, 248, 9749),
601    (97, 249, 9752),
602    (97, 250, 9755),
603    (98, 246, 9843),
604    (98, 247, 9846),
605    (98, 248, 9849),
606    (98, 249, 9852),
607    (98, 250, 9855),
608    (98, 251, 9858),
609    (98, 252, 9861),
610    (98, 253, 9864),
611    (98, 254, 9867),
612    (99, 251, 9911),
613    (99, 252, 9912),
614    (99, 253, 9913),
615    (99, 254, 9914),
616    (99, 255, 9916),
617    (100, 255, 9936),
618];
619
620#[cfg(test)]
621mod tests {
622    use super::*;
623
624    #[test]
625    fn test_mat_number_known_values() {
626        assert_eq!(mat_number(92, 235), Some(9228));
627        assert_eq!(mat_number(92, 238), Some(9237));
628        assert_eq!(mat_number(26, 56), Some(2631));
629        assert_eq!(mat_number(1, 1), Some(125));
630        assert_eq!(mat_number(0, 1), Some(25)); // neutron
631        assert_eq!(mat_number(94, 239), Some(9437));
632    }
633
634    #[test]
635    fn test_mat_number_tungsten() {
636        assert_eq!(mat_number(74, 182), Some(7431));
637        assert_eq!(mat_number(74, 183), Some(7434));
638        assert_eq!(mat_number(74, 184), Some(7437));
639        assert_eq!(mat_number(74, 186), Some(7443));
640    }
641
642    #[test]
643    fn test_mat_number_tin_expansion() {
644        // Tin isotopes — NOT in the old 47-entry table, proves expansion works
645        assert_eq!(mat_number(50, 120), Some(5049));
646        assert_eq!(mat_number(50, 116), Some(5037));
647        assert_eq!(mat_number(50, 118), Some(5043));
648    }
649
650    #[test]
651    fn test_mat_number_corrected_regressions() {
652        // Regression tests for isotopes whose MAT values were incorrect in the
653        // old hand-coded 47-entry table (off by one isotope offset each).
654        // Correct values sourced from PLEIADES neutrons.list (ENDF/B-VIII.0).
655
656        // Cd-113: old table had 4849 (actually Cd-114), correct is 4846
657        assert_eq!(mat_number(48, 113), Some(4846));
658        assert_eq!(isotope_from_mat(4846), Some((48, 113)));
659
660        // Hf-177: old table had 7231 (actually Hf-176), correct is 7234
661        assert_eq!(mat_number(72, 177), Some(7234));
662        assert_eq!(isotope_from_mat(7234), Some((72, 177)));
663
664        // Hf-178: old table had 7234 (actually Hf-177), correct is 7237
665        assert_eq!(mat_number(72, 178), Some(7237));
666        assert_eq!(isotope_from_mat(7237), Some((72, 178)));
667
668        // W-182/183/184/186: old table was shifted by one isotope
669        assert_eq!(mat_number(74, 182), Some(7431));
670        assert_eq!(mat_number(74, 183), Some(7434));
671        assert_eq!(mat_number(74, 184), Some(7437));
672        assert_eq!(mat_number(74, 186), Some(7443));
673    }
674
675    #[test]
676    fn test_mat_number_unknown() {
677        assert_eq!(mat_number(200, 400), None);
678        assert_eq!(mat_number(0, 0), None);
679    }
680
681    #[test]
682    fn test_isotope_from_mat() {
683        assert_eq!(isotope_from_mat(9228), Some((92, 235)));
684        assert_eq!(isotope_from_mat(9237), Some((92, 238)));
685        assert_eq!(isotope_from_mat(2631), Some((26, 56)));
686        assert_eq!(isotope_from_mat(25), Some((0, 1))); // neutron
687    }
688
689    #[test]
690    fn test_isotope_from_mat_unknown() {
691        assert_eq!(isotope_from_mat(9999), None);
692        assert_eq!(isotope_from_mat(0), None);
693    }
694
695    #[test]
696    fn test_mat_roundtrip() {
697        for &(z, a, mat) in ENDF_MAT_TABLE.iter() {
698            assert_eq!(
699                mat_number(z, a),
700                Some(mat),
701                "mat_number({}, {}) failed",
702                z,
703                a
704            );
705            assert_eq!(
706                isotope_from_mat(mat),
707                Some((z, a)),
708                "isotope_from_mat({}) failed",
709                mat
710            );
711        }
712    }
713
714    #[test]
715    fn test_table_size() {
716        assert_eq!(ENDF_MAT_TABLE.len(), 535);
717    }
718
719    #[test]
720    fn test_known_isotopes_plutonium() {
721        let pu = known_isotopes(94);
722        assert_eq!(
723            pu,
724            vec![236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246]
725        );
726    }
727
728    #[test]
729    fn test_known_isotopes_technetium() {
730        // Tc (Z=43) is synthetic — no natural isotopes but has ENDF evaluations
731        let tc = known_isotopes(43);
732        assert_eq!(tc, vec![98, 99]);
733    }
734
735    #[test]
736    fn test_known_isotopes_iron() {
737        let fe = known_isotopes(26);
738        assert_eq!(fe, vec![54, 55, 56, 57, 58]);
739    }
740
741    #[test]
742    fn test_known_isotopes_unknown() {
743        assert!(known_isotopes(200).is_empty());
744        assert!(known_isotopes(119).is_empty());
745    }
746
747    #[test]
748    fn test_known_isotopes_superset_of_natural() {
749        use crate::abundances::natural_isotopes;
750        for z in 1..=92 {
751            let natural_a: Vec<u32> = natural_isotopes(z).into_iter().map(|(a, _)| a).collect();
752            let known_a = known_isotopes(z);
753            for a in &natural_a {
754                assert!(
755                    known_a.contains(a),
756                    "Z={z}, A={a} is natural but not in known_isotopes"
757                );
758            }
759        }
760    }
761
762    #[test]
763    fn test_has_endf_evaluation() {
764        assert!(has_endf_evaluation(94, 239)); // Pu-239
765        assert!(has_endf_evaluation(92, 235)); // U-235
766        assert!(!has_endf_evaluation(94, 999)); // no such isotope
767        assert!(!has_endf_evaluation(200, 400));
768    }
769
770    #[test]
771    fn test_table_sorted() {
772        for i in 1..ENDF_MAT_TABLE.len() {
773            let (z1, a1, _) = ENDF_MAT_TABLE[i - 1];
774            let (z2, a2, _) = ENDF_MAT_TABLE[i];
775            assert!(
776                (z1, a1) < (z2, a2),
777                "Table not sorted at index {}: ({}, {}) >= ({}, {})",
778                i,
779                z1,
780                a1,
781                z2,
782                a2
783            );
784        }
785    }
786}