1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
4pub enum NmrNucleus {
5 H1,
6 H2,
7 H3,
8 He3,
9 Li6,
10 Li7,
11 Be9,
12 B10,
13 B11,
14 C13,
15 N14,
16 N15,
17 O17,
18 F19,
19 Na23,
20 Mg25,
21 Al27,
22 Si29,
23 P31,
24 S33,
25 Cl35,
26 Cl37,
27 K39,
28 K40,
29 K41,
30 Ca43,
31 Sc45,
32 Ti47,
33 Ti49,
34 V50,
35 V51,
36 Cr53,
37 Fe57,
38 Co59,
39 Ni61,
40 Cu63,
41 Cu65,
42 Zn67,
43 Ga69,
44 Ga71,
45 Ge73,
46 As75,
47 Se77,
48 Br79,
49 Br81,
50 Rb85,
51 Rb87,
52 Sr87,
53 Zr91,
54 Nb93,
55 Mo95,
56 Mo97,
57 Ru99,
58 Ru101,
59 Rh103,
60 Pd105,
61 Ag107,
62 Ag109,
63 Cd111,
64 Cd113,
65 In113,
66 In115,
67 Sn115,
68 Sn117,
69 Sn119,
70 Sb121,
71 Sb123,
72 Te123,
73 Te125,
74 I127,
75 Xe129,
76 Xe131,
77 Cs133,
78 Ba135,
79 Ba137,
80 W183,
81 Pt195,
82 Au197,
83 Hg199,
84 Hg201,
85 Tl203,
86 Tl205,
87 Pb207,
88 Bi209,
89 Mn55,
90}
91
92impl NmrNucleus {
93 pub const ALL: [NmrNucleus; 85] = [
94 NmrNucleus::H1,
95 NmrNucleus::H2,
96 NmrNucleus::H3,
97 NmrNucleus::He3,
98 NmrNucleus::Li6,
99 NmrNucleus::Li7,
100 NmrNucleus::Be9,
101 NmrNucleus::B10,
102 NmrNucleus::B11,
103 NmrNucleus::C13,
104 NmrNucleus::N14,
105 NmrNucleus::N15,
106 NmrNucleus::O17,
107 NmrNucleus::F19,
108 NmrNucleus::Na23,
109 NmrNucleus::Mg25,
110 NmrNucleus::Al27,
111 NmrNucleus::Si29,
112 NmrNucleus::P31,
113 NmrNucleus::S33,
114 NmrNucleus::Cl35,
115 NmrNucleus::Cl37,
116 NmrNucleus::K39,
117 NmrNucleus::K40,
118 NmrNucleus::K41,
119 NmrNucleus::Ca43,
120 NmrNucleus::Sc45,
121 NmrNucleus::Ti47,
122 NmrNucleus::Ti49,
123 NmrNucleus::V50,
124 NmrNucleus::V51,
125 NmrNucleus::Cr53,
126 NmrNucleus::Mn55,
127 NmrNucleus::Fe57,
128 NmrNucleus::Co59,
129 NmrNucleus::Ni61,
130 NmrNucleus::Cu63,
131 NmrNucleus::Cu65,
132 NmrNucleus::Zn67,
133 NmrNucleus::Ga69,
134 NmrNucleus::Ga71,
135 NmrNucleus::Ge73,
136 NmrNucleus::As75,
137 NmrNucleus::Se77,
138 NmrNucleus::Br79,
139 NmrNucleus::Br81,
140 NmrNucleus::Rb85,
141 NmrNucleus::Rb87,
142 NmrNucleus::Sr87,
143 NmrNucleus::Zr91,
144 NmrNucleus::Nb93,
145 NmrNucleus::Mo95,
146 NmrNucleus::Mo97,
147 NmrNucleus::Ru99,
148 NmrNucleus::Ru101,
149 NmrNucleus::Rh103,
150 NmrNucleus::Pd105,
151 NmrNucleus::Ag107,
152 NmrNucleus::Ag109,
153 NmrNucleus::Cd111,
154 NmrNucleus::Cd113,
155 NmrNucleus::In113,
156 NmrNucleus::In115,
157 NmrNucleus::Sn115,
158 NmrNucleus::Sn117,
159 NmrNucleus::Sn119,
160 NmrNucleus::Sb121,
161 NmrNucleus::Sb123,
162 NmrNucleus::Te123,
163 NmrNucleus::Te125,
164 NmrNucleus::I127,
165 NmrNucleus::Xe129,
166 NmrNucleus::Xe131,
167 NmrNucleus::Cs133,
168 NmrNucleus::Ba135,
169 NmrNucleus::Ba137,
170 NmrNucleus::W183,
171 NmrNucleus::Pt195,
172 NmrNucleus::Au197,
173 NmrNucleus::Hg199,
174 NmrNucleus::Hg201,
175 NmrNucleus::Tl203,
176 NmrNucleus::Tl205,
177 NmrNucleus::Pb207,
178 NmrNucleus::Bi209,
179 ];
180
181 pub fn parse(alias: &str) -> Result<Self, String> {
182 let normalized: String = alias
183 .chars()
184 .filter(|character| character.is_ascii_alphanumeric())
185 .flat_map(|character| character.to_lowercase())
186 .collect();
187
188 let nucleus = match normalized.as_str() {
189 "1h" | "h1" | "proton" | "hydrogen" => Self::H1,
190 "2h" | "h2" | "deuterium" => Self::H2,
191 "3h" | "h3" | "tritium" => Self::H3,
192 "3he" | "he3" | "helium" => Self::He3,
193 "6li" | "li6" => Self::Li6,
194 "7li" | "li7" | "lithium" => Self::Li7,
195 "9be" | "be9" | "beryllium" => Self::Be9,
196 "10b" | "b10" => Self::B10,
197 "11b" | "b11" | "boron" => Self::B11,
198 "13c" | "c13" | "carbon" => Self::C13,
199 "14n" | "n14" => Self::N14,
200 "15n" | "n15" | "nitrogen" => Self::N15,
201 "17o" | "o17" | "oxygen" => Self::O17,
202 "19f" | "f19" | "fluorine" => Self::F19,
203 "23na" | "na23" | "sodium" => Self::Na23,
204 "25mg" | "mg25" | "magnesium" => Self::Mg25,
205 "27al" | "al27" | "aluminium" | "aluminum" => Self::Al27,
206 "29si" | "si29" | "silicon" => Self::Si29,
207 "31p" | "p31" | "phosphorus" => Self::P31,
208 "33s" | "s33" | "sulfur" | "sulphur" => Self::S33,
209 "35cl" | "cl35" | "chlorine" => Self::Cl35,
210 "37cl" | "cl37" => Self::Cl37,
211 "39k" | "k39" | "potassium" => Self::K39,
212 "40k" | "k40" => Self::K40,
213 "41k" | "k41" => Self::K41,
214 "43ca" | "ca43" | "calcium" => Self::Ca43,
215 "45sc" | "sc45" | "scandium" => Self::Sc45,
216 "47ti" | "ti47" => Self::Ti47,
217 "49ti" | "ti49" | "titanium" => Self::Ti49,
218 "50v" | "v50" => Self::V50,
219 "51v" | "v51" | "vanadium" => Self::V51,
220 "53cr" | "cr53" | "chromium" => Self::Cr53,
221 "55mn" | "mn55" | "manganese" => Self::Mn55,
222 "57fe" | "fe57" | "iron" => Self::Fe57,
223 "59co" | "co59" | "cobalt" => Self::Co59,
224 "61ni" | "ni61" | "nickel" => Self::Ni61,
225 "63cu" | "cu63" | "copper" => Self::Cu63,
226 "65cu" | "cu65" => Self::Cu65,
227 "67zn" | "zn67" | "zinc" => Self::Zn67,
228 "69ga" | "ga69" | "gallium" => Self::Ga69,
229 "71ga" | "ga71" => Self::Ga71,
230 "73ge" | "ge73" | "germanium" => Self::Ge73,
231 "75as" | "as75" | "arsenic" | "arsenico" => Self::As75,
232 "77se" | "se77" | "selenium" => Self::Se77,
233 "79br" | "br79" | "bromine" => Self::Br79,
234 "81br" | "br81" => Self::Br81,
235 "85rb" | "rb85" => Self::Rb85,
236 "87rb" | "rb87" | "rubidium" => Self::Rb87,
237 "87sr" | "sr87" | "strontium" => Self::Sr87,
238 "91zr" | "zr91" | "zirconium" => Self::Zr91,
239 "93nb" | "nb93" | "niobium" => Self::Nb93,
240 "95mo" | "mo95" | "molybdenum" => Self::Mo95,
241 "97mo" | "mo97" => Self::Mo97,
242 "99ru" | "ru99" => Self::Ru99,
243 "101ru" | "ru101" | "ruthenium" => Self::Ru101,
244 "103rh" | "rh103" | "rhodium" => Self::Rh103,
245 "105pd" | "pd105" | "palladium" => Self::Pd105,
246 "107ag" | "ag107" | "silver" => Self::Ag107,
247 "109ag" | "ag109" => Self::Ag109,
248 "111cd" | "cd111" | "cadmium" => Self::Cd111,
249 "113cd" | "cd113" => Self::Cd113,
250 "113in" | "in113" => Self::In113,
251 "115in" | "in115" | "indium" => Self::In115,
252 "115sn" | "sn115" => Self::Sn115,
253 "117sn" | "sn117" => Self::Sn117,
254 "119sn" | "sn119" | "tin" => Self::Sn119,
255 "121sb" | "sb121" | "antimony" => Self::Sb121,
256 "123sb" | "sb123" => Self::Sb123,
257 "123te" | "te123" => Self::Te123,
258 "125te" | "te125" | "tellurium" => Self::Te125,
259 "127i" | "i127" | "iodine" => Self::I127,
260 "129xe" | "xe129" | "xenon" => Self::Xe129,
261 "131xe" | "xe131" => Self::Xe131,
262 "133cs" | "cs133" | "cesium" | "caesium" => Self::Cs133,
263 "135ba" | "ba135" => Self::Ba135,
264 "137ba" | "ba137" | "barium" => Self::Ba137,
265 "183w" | "w183" | "tungsten" | "wolfram" => Self::W183,
266 "195pt" | "pt195" | "platinum" => Self::Pt195,
267 "197au" | "au197" | "gold" => Self::Au197,
268 "199hg" | "hg199" | "mercury" => Self::Hg199,
269 "201hg" | "hg201" => Self::Hg201,
270 "203tl" | "tl203" => Self::Tl203,
271 "205tl" | "tl205" | "thallium" => Self::Tl205,
272 "207pb" | "pb207" | "lead" => Self::Pb207,
273 "209bi" | "bi209" | "bismuth" => Self::Bi209,
274 _ => {
275 return Err(format!(
276 "Unknown nucleus '{}'. Supported: {}",
277 alias,
278 Self::supported_labels().join(", ")
279 ))
280 }
281 };
282
283 Ok(nucleus)
284 }
285
286 pub fn supported_labels() -> Vec<&'static str> {
287 Self::ALL
288 .iter()
289 .map(|nucleus| nucleus.canonical())
290 .collect()
291 }
292
293 pub fn atomic_number(self) -> u8 {
294 match self {
295 Self::H1 | Self::H2 | Self::H3 => 1,
296 Self::He3 => 2,
297 Self::Li6 | Self::Li7 => 3,
298 Self::Be9 => 4,
299 Self::B10 | Self::B11 => 5,
300 Self::C13 => 6,
301 Self::N14 | Self::N15 => 7,
302 Self::O17 => 8,
303 Self::F19 => 9,
304 Self::Na23 => 11,
305 Self::Mg25 => 12,
306 Self::Al27 => 13,
307 Self::Si29 => 14,
308 Self::P31 => 15,
309 Self::S33 => 16,
310 Self::Cl35 | Self::Cl37 => 17,
311 Self::K39 | Self::K40 | Self::K41 => 19,
312 Self::Ca43 => 20,
313 Self::Sc45 => 21,
314 Self::Ti47 | Self::Ti49 => 22,
315 Self::V50 | Self::V51 => 23,
316 Self::Cr53 => 24,
317 Self::Mn55 => 25,
318 Self::Fe57 => 26,
319 Self::Co59 => 27,
320 Self::Ni61 => 28,
321 Self::Cu63 | Self::Cu65 => 29,
322 Self::Zn67 => 30,
323 Self::Ga69 | Self::Ga71 => 31,
324 Self::Ge73 => 32,
325 Self::As75 => 33,
326 Self::Se77 => 34,
327 Self::Br79 | Self::Br81 => 35,
328 Self::Rb85 | Self::Rb87 => 37,
329 Self::Sr87 => 38,
330 Self::Zr91 => 40,
331 Self::Nb93 => 41,
332 Self::Mo95 | Self::Mo97 => 42,
333 Self::Ru99 | Self::Ru101 => 44,
334 Self::Rh103 => 45,
335 Self::Pd105 => 46,
336 Self::Ag107 | Self::Ag109 => 47,
337 Self::Cd111 | Self::Cd113 => 48,
338 Self::In113 | Self::In115 => 49,
339 Self::Sn115 | Self::Sn117 | Self::Sn119 => 50,
340 Self::Sb121 | Self::Sb123 => 51,
341 Self::Te123 | Self::Te125 => 52,
342 Self::I127 => 53,
343 Self::Xe129 | Self::Xe131 => 54,
344 Self::Cs133 => 55,
345 Self::Ba135 | Self::Ba137 => 56,
346 Self::W183 => 74,
347 Self::Pt195 => 78,
348 Self::Au197 => 79,
349 Self::Hg199 | Self::Hg201 => 80,
350 Self::Tl203 | Self::Tl205 => 81,
351 Self::Pb207 => 82,
352 Self::Bi209 => 83,
353 }
354 }
355
356 pub fn mass_number(self) -> u16 {
357 match self {
358 Self::H1 => 1,
359 Self::H2 => 2,
360 Self::H3 => 3,
361 Self::He3 => 3,
362 Self::Li6 => 6,
363 Self::Li7 => 7,
364 Self::Be9 => 9,
365 Self::B10 => 10,
366 Self::B11 => 11,
367 Self::C13 => 13,
368 Self::N14 => 14,
369 Self::N15 => 15,
370 Self::O17 => 17,
371 Self::F19 => 19,
372 Self::Na23 => 23,
373 Self::Mg25 => 25,
374 Self::Al27 => 27,
375 Self::Si29 => 29,
376 Self::P31 => 31,
377 Self::S33 => 33,
378 Self::Cl35 => 35,
379 Self::Cl37 => 37,
380 Self::K39 => 39,
381 Self::K40 => 40,
382 Self::K41 => 41,
383 Self::Ca43 => 43,
384 Self::Sc45 => 45,
385 Self::Ti47 => 47,
386 Self::Ti49 => 49,
387 Self::V50 => 50,
388 Self::V51 => 51,
389 Self::Cr53 => 53,
390 Self::Mn55 => 55,
391 Self::Fe57 => 57,
392 Self::Co59 => 59,
393 Self::Ni61 => 61,
394 Self::Cu63 => 63,
395 Self::Cu65 => 65,
396 Self::Zn67 => 67,
397 Self::Ga69 => 69,
398 Self::Ga71 => 71,
399 Self::Ge73 => 73,
400 Self::As75 => 75,
401 Self::Se77 => 77,
402 Self::Br79 => 79,
403 Self::Br81 => 81,
404 Self::Rb85 => 85,
405 Self::Rb87 => 87,
406 Self::Sr87 => 87,
407 Self::Zr91 => 91,
408 Self::Nb93 => 93,
409 Self::Mo95 => 95,
410 Self::Mo97 => 97,
411 Self::Ru99 => 99,
412 Self::Ru101 => 101,
413 Self::Rh103 => 103,
414 Self::Pd105 => 105,
415 Self::Ag107 => 107,
416 Self::Ag109 => 109,
417 Self::Cd111 => 111,
418 Self::Cd113 => 113,
419 Self::In113 => 113,
420 Self::In115 => 115,
421 Self::Sn115 => 115,
422 Self::Sn117 => 117,
423 Self::Sn119 => 119,
424 Self::Sb121 => 121,
425 Self::Sb123 => 123,
426 Self::Te123 => 123,
427 Self::Te125 => 125,
428 Self::I127 => 127,
429 Self::Xe129 => 129,
430 Self::Xe131 => 131,
431 Self::Cs133 => 133,
432 Self::Ba135 => 135,
433 Self::Ba137 => 137,
434 Self::W183 => 183,
435 Self::Pt195 => 195,
436 Self::Au197 => 197,
437 Self::Hg199 => 199,
438 Self::Hg201 => 201,
439 Self::Tl203 => 203,
440 Self::Tl205 => 205,
441 Self::Pb207 => 207,
442 Self::Bi209 => 209,
443 }
444 }
445
446 pub fn canonical(self) -> &'static str {
447 match self {
448 Self::H1 => "1H",
449 Self::H2 => "2H",
450 Self::H3 => "3H",
451 Self::He3 => "3He",
452 Self::Li6 => "6Li",
453 Self::Li7 => "7Li",
454 Self::Be9 => "9Be",
455 Self::B10 => "10B",
456 Self::B11 => "11B",
457 Self::C13 => "13C",
458 Self::N14 => "14N",
459 Self::N15 => "15N",
460 Self::O17 => "17O",
461 Self::F19 => "19F",
462 Self::Na23 => "23Na",
463 Self::Mg25 => "25Mg",
464 Self::Al27 => "27Al",
465 Self::Si29 => "29Si",
466 Self::P31 => "31P",
467 Self::S33 => "33S",
468 Self::Cl35 => "35Cl",
469 Self::Cl37 => "37Cl",
470 Self::K39 => "39K",
471 Self::K40 => "40K",
472 Self::K41 => "41K",
473 Self::Ca43 => "43Ca",
474 Self::Sc45 => "45Sc",
475 Self::Ti47 => "47Ti",
476 Self::Ti49 => "49Ti",
477 Self::V50 => "50V",
478 Self::V51 => "51V",
479 Self::Cr53 => "53Cr",
480 Self::Mn55 => "55Mn",
481 Self::Fe57 => "57Fe",
482 Self::Co59 => "59Co",
483 Self::Ni61 => "61Ni",
484 Self::Cu63 => "63Cu",
485 Self::Cu65 => "65Cu",
486 Self::Zn67 => "67Zn",
487 Self::Ga69 => "69Ga",
488 Self::Ga71 => "71Ga",
489 Self::Ge73 => "73Ge",
490 Self::As75 => "75As",
491 Self::Se77 => "77Se",
492 Self::Br79 => "79Br",
493 Self::Br81 => "81Br",
494 Self::Rb85 => "85Rb",
495 Self::Rb87 => "87Rb",
496 Self::Sr87 => "87Sr",
497 Self::Zr91 => "91Zr",
498 Self::Nb93 => "93Nb",
499 Self::Mo95 => "95Mo",
500 Self::Mo97 => "97Mo",
501 Self::Ru99 => "99Ru",
502 Self::Ru101 => "101Ru",
503 Self::Rh103 => "103Rh",
504 Self::Pd105 => "105Pd",
505 Self::Ag107 => "107Ag",
506 Self::Ag109 => "109Ag",
507 Self::Cd111 => "111Cd",
508 Self::Cd113 => "113Cd",
509 Self::In113 => "113In",
510 Self::In115 => "115In",
511 Self::Sn115 => "115Sn",
512 Self::Sn117 => "117Sn",
513 Self::Sn119 => "119Sn",
514 Self::Sb121 => "121Sb",
515 Self::Sb123 => "123Sb",
516 Self::Te123 => "123Te",
517 Self::Te125 => "125Te",
518 Self::I127 => "127I",
519 Self::Xe129 => "129Xe",
520 Self::Xe131 => "131Xe",
521 Self::Cs133 => "133Cs",
522 Self::Ba135 => "135Ba",
523 Self::Ba137 => "137Ba",
524 Self::W183 => "183W",
525 Self::Pt195 => "195Pt",
526 Self::Au197 => "197Au",
527 Self::Hg199 => "199Hg",
528 Self::Hg201 => "201Hg",
529 Self::Tl203 => "203Tl",
530 Self::Tl205 => "205Tl",
531 Self::Pb207 => "207Pb",
532 Self::Bi209 => "209Bi",
533 }
534 }
535
536 pub fn unicode_label(self) -> &'static str {
537 match self {
538 Self::H1 => "¹H",
539 Self::H2 => "²H",
540 Self::H3 => "³H",
541 Self::He3 => "³He",
542 Self::Li6 => "⁶Li",
543 Self::Li7 => "⁷Li",
544 Self::Be9 => "⁹Be",
545 Self::B10 => "¹⁰B",
546 Self::B11 => "¹¹B",
547 Self::C13 => "¹³C",
548 Self::N14 => "¹⁴N",
549 Self::N15 => "¹⁵N",
550 Self::O17 => "¹⁷O",
551 Self::F19 => "¹⁹F",
552 Self::Na23 => "²³Na",
553 Self::Mg25 => "²⁵Mg",
554 Self::Al27 => "²⁷Al",
555 Self::Si29 => "²⁹Si",
556 Self::P31 => "³¹P",
557 Self::S33 => "³³S",
558 Self::Cl35 => "³⁵Cl",
559 Self::Cl37 => "³⁷Cl",
560 Self::K39 => "³⁹K",
561 Self::K40 => "⁴⁰K",
562 Self::K41 => "⁴¹K",
563 Self::Ca43 => "⁴³Ca",
564 Self::Sc45 => "⁴⁵Sc",
565 Self::Ti47 => "⁴⁷Ti",
566 Self::Ti49 => "⁴⁹Ti",
567 Self::V50 => "⁵⁰V",
568 Self::V51 => "⁵¹V",
569 Self::Cr53 => "⁵³Cr",
570 Self::Mn55 => "⁵⁵Mn",
571 Self::Fe57 => "⁵⁷Fe",
572 Self::Co59 => "⁵⁹Co",
573 Self::Ni61 => "⁶¹Ni",
574 Self::Cu63 => "⁶³Cu",
575 Self::Cu65 => "⁶⁵Cu",
576 Self::Zn67 => "⁶⁷Zn",
577 Self::Ga69 => "⁶⁹Ga",
578 Self::Ga71 => "⁷¹Ga",
579 Self::Ge73 => "⁷³Ge",
580 Self::As75 => "⁷⁵As",
581 Self::Se77 => "⁷⁷Se",
582 Self::Br79 => "⁷⁹Br",
583 Self::Br81 => "⁸¹Br",
584 Self::Rb85 => "⁸⁵Rb",
585 Self::Rb87 => "⁸⁷Rb",
586 Self::Sr87 => "⁸⁷Sr",
587 Self::Zr91 => "⁹¹Zr",
588 Self::Nb93 => "⁹³Nb",
589 Self::Mo95 => "⁹⁵Mo",
590 Self::Mo97 => "⁹⁷Mo",
591 Self::Ru99 => "⁹⁹Ru",
592 Self::Ru101 => "¹⁰¹Ru",
593 Self::Rh103 => "¹⁰³Rh",
594 Self::Pd105 => "¹⁰⁵Pd",
595 Self::Ag107 => "¹⁰⁷Ag",
596 Self::Ag109 => "¹⁰⁹Ag",
597 Self::Cd111 => "¹¹¹Cd",
598 Self::Cd113 => "¹¹³Cd",
599 Self::In113 => "¹¹³In",
600 Self::In115 => "¹¹⁵In",
601 Self::Sn115 => "¹¹⁵Sn",
602 Self::Sn117 => "¹¹⁷Sn",
603 Self::Sn119 => "¹¹⁹Sn",
604 Self::Sb121 => "¹²¹Sb",
605 Self::Sb123 => "¹²³Sb",
606 Self::Te123 => "¹²³Te",
607 Self::Te125 => "¹²⁵Te",
608 Self::I127 => "¹²⁷I",
609 Self::Xe129 => "¹²⁹Xe",
610 Self::Xe131 => "¹³¹Xe",
611 Self::Cs133 => "¹³³Cs",
612 Self::Ba135 => "¹³⁵Ba",
613 Self::Ba137 => "¹³⁷Ba",
614 Self::W183 => "¹⁸³W",
615 Self::Pt195 => "¹⁹⁵Pt",
616 Self::Au197 => "¹⁹⁷Au",
617 Self::Hg199 => "¹⁹⁹Hg",
618 Self::Hg201 => "²⁰¹Hg",
619 Self::Tl203 => "²⁰³Tl",
620 Self::Tl205 => "²⁰⁵Tl",
621 Self::Pb207 => "²⁰⁷Pb",
622 Self::Bi209 => "²⁰⁹Bi",
623 }
624 }
625
626 pub fn element_symbol(self) -> &'static str {
627 match self.atomic_number() {
628 1 => "H",
629 2 => "He",
630 3 => "Li",
631 4 => "Be",
632 5 => "B",
633 6 => "C",
634 7 => "N",
635 8 => "O",
636 9 => "F",
637 11 => "Na",
638 12 => "Mg",
639 13 => "Al",
640 14 => "Si",
641 15 => "P",
642 16 => "S",
643 17 => "Cl",
644 19 => "K",
645 20 => "Ca",
646 21 => "Sc",
647 22 => "Ti",
648 23 => "V",
649 24 => "Cr",
650 25 => "Mn",
651 26 => "Fe",
652 27 => "Co",
653 28 => "Ni",
654 29 => "Cu",
655 30 => "Zn",
656 31 => "Ga",
657 32 => "Ge",
658 33 => "As",
659 34 => "Se",
660 35 => "Br",
661 37 => "Rb",
662 38 => "Sr",
663 40 => "Zr",
664 41 => "Nb",
665 42 => "Mo",
666 44 => "Ru",
667 45 => "Rh",
668 46 => "Pd",
669 47 => "Ag",
670 48 => "Cd",
671 49 => "In",
672 50 => "Sn",
673 51 => "Sb",
674 52 => "Te",
675 53 => "I",
676 54 => "Xe",
677 55 => "Cs",
678 56 => "Ba",
679 74 => "W",
680 78 => "Pt",
681 79 => "Au",
682 80 => "Hg",
683 81 => "Tl",
684 82 => "Pb",
685 83 => "Bi",
686 _ => "X",
687 }
688 }
689
690 pub fn is_primary_target(self) -> bool {
691 matches!(self, Self::H1 | Self::C13)
692 }
693
694 pub fn is_quadrupolar(self) -> bool {
695 !matches!(
696 self,
697 Self::H1
698 | Self::H3
699 | Self::He3
700 | Self::C13
701 | Self::N15
702 | Self::F19
703 | Self::Si29
704 | Self::P31
705 | Self::Se77
706 | Self::Ge73
707 | Self::Sn115
708 | Self::Sn117
709 | Self::Sn119
710 | Self::Te123
711 | Self::Te125
712 | Self::Xe129
713 | Self::Tl203
714 | Self::Tl205
715 | Self::Pb207
716 | Self::Pt195
717 | Self::Hg199
718 | Self::Rh103
719 | Self::Ag107
720 | Self::Ag109
721 | Self::Cd111
722 | Self::Cd113
723 )
724 }
725
726 pub fn default_for_element(atomic_number: u8) -> Option<Self> {
727 let nucleus = match atomic_number {
728 1 => Self::H1,
729 2 => Self::He3,
730 3 => Self::Li7,
731 4 => Self::Be9,
732 5 => Self::B11,
733 6 => Self::C13,
734 7 => Self::N15,
735 8 => Self::O17,
736 9 => Self::F19,
737 11 => Self::Na23,
738 12 => Self::Mg25,
739 13 => Self::Al27,
740 14 => Self::Si29,
741 15 => Self::P31,
742 16 => Self::S33,
743 17 => Self::Cl35,
744 19 => Self::K39,
745 20 => Self::Ca43,
746 21 => Self::Sc45,
747 22 => Self::Ti49,
748 23 => Self::V51,
749 24 => Self::Cr53,
750 25 => Self::Mn55,
751 26 => Self::Fe57,
752 27 => Self::Co59,
753 28 => Self::Ni61,
754 29 => Self::Cu63,
755 30 => Self::Zn67,
756 31 => Self::Ga69,
757 32 => Self::Ge73,
758 33 => Self::As75,
759 34 => Self::Se77,
760 35 => Self::Br79,
761 37 => Self::Rb87,
762 38 => Self::Sr87,
763 40 => Self::Zr91,
764 41 => Self::Nb93,
765 42 => Self::Mo95,
766 44 => Self::Ru101,
767 45 => Self::Rh103,
768 46 => Self::Pd105,
769 47 => Self::Ag107,
770 48 => Self::Cd111,
771 49 => Self::In115,
772 50 => Self::Sn119,
773 51 => Self::Sb121,
774 52 => Self::Te125,
775 53 => Self::I127,
776 54 => Self::Xe129,
777 55 => Self::Cs133,
778 56 => Self::Ba137,
779 74 => Self::W183,
780 78 => Self::Pt195,
781 79 => Self::Au197,
782 80 => Self::Hg199,
783 81 => Self::Tl205,
784 82 => Self::Pb207,
785 83 => Self::Bi209,
786 _ => return None,
787 };
788
789 Some(nucleus)
790 }
791
792 pub fn default_frequency_mhz(self) -> f64 {
793 match self {
794 Self::H1 => 400.0,
795 Self::H2 => 61.4,
796 Self::H3 => 426.0,
797 Self::He3 => 304.6,
798 Self::Li6 => 58.9,
799 Self::Li7 => 155.5,
800 Self::Be9 => 56.3,
801 Self::B10 => 42.9,
802 Self::B11 => 128.4,
803 Self::C13 => 100.6,
804 Self::N14 => 28.9,
805 Self::N15 => 40.6,
806 Self::O17 => 54.2,
807 Self::F19 => 376.5,
808 Self::Na23 => 105.8,
809 Self::Mg25 => 24.5,
810 Self::Al27 => 104.2,
811 Self::Si29 => 79.5,
812 Self::P31 => 162.0,
813 Self::S33 => 30.7,
814 Self::Cl35 => 39.2,
815 Self::Cl37 => 32.7,
816 Self::K39 => 18.7,
817 Self::K40 => 2.2,
818 Self::K41 => 10.9,
819 Self::Ca43 => 26.9,
820 Self::Sc45 => 97.2,
821 Self::Ti47 => 22.6,
822 Self::Ti49 => 23.2,
823 Self::V50 => 42.1,
824 Self::V51 => 105.2,
825 Self::Cr53 => 22.6,
826 Self::Mn55 => 100.0,
827 Self::Fe57 => 54.2,
828 Self::Co59 => 95.0,
829 Self::Ni61 => 35.2,
830 Self::Cu63 => 106.3,
831 Self::Cu65 => 113.9,
832 Self::Zn67 => 25.1,
833 Self::Ga69 => 122.1,
834 Self::Ga71 => 152.5,
835 Self::Ge73 => 14.1,
836 Self::As75 => 52.2,
837 Self::Se77 => 76.3,
838 Self::Br79 => 100.2,
839 Self::Br81 => 108.3,
840 Self::Rb85 => 130.9,
841 Self::Rb87 => 186.9,
842 Self::Sr87 => 74.2,
843 Self::Zr91 => 24.5,
844 Self::Nb93 => 98.2,
845 Self::Mo95 => 26.1,
846 Self::Mo97 => 26.6,
847 Self::Ru99 => 17.3,
848 Self::Ru101 => 22.2,
849 Self::Rh103 => 15.8,
850 Self::Pd105 => 17.2,
851 Self::Ag107 => 18.6,
852 Self::Ag109 => 21.4,
853 Self::Cd111 => 88.8,
854 Self::Cd113 => 93.3,
855 Self::In113 => 88.6,
856 Self::In115 => 92.9,
857 Self::Sn115 => 149.0,
858 Self::Sn117 => 149.3,
859 Self::Sn119 => 149.2,
860 Self::Sb121 => 102.7,
861 Self::Sb123 => 54.3,
862 Self::Te123 => 126.0,
863 Self::Te125 => 126.3,
864 Self::I127 => 80.0,
865 Self::Xe129 => 110.7,
866 Self::Xe131 => 32.9,
867 Self::Cs133 => 52.4,
868 Self::Ba135 => 28.0,
869 Self::Ba137 => 42.0,
870 Self::W183 => 16.7,
871 Self::Pt195 => 85.8,
872 Self::Au197 => 8.7,
873 Self::Hg199 => 74.7,
874 Self::Hg201 => 22.1,
875 Self::Tl203 => 96.6,
876 Self::Tl205 => 100.2,
877 Self::Pb207 => 83.7,
878 Self::Bi209 => 84.2,
879 }
880 }
881
882 pub fn default_fwhm_hz(self) -> f64 {
883 match self {
884 Self::H1 => 1.0,
885 Self::C13 | Self::F19 | Self::Si29 | Self::Ge73 => 5.0,
886 Self::P31 | Self::N15 | Self::Se77 | Self::Te123 | Self::Te125 => 12.0,
887 Self::H3 | Self::He3 | Self::Xe129 => 15.0,
888 Self::Pt195 | Self::Hg199 | Self::Pb207 | Self::W183 => 25.0,
889 Self::Tl203 | Self::Tl205 | Self::Cd111 | Self::Cd113 => 30.0,
890 Self::Ag107 | Self::Ag109 | Self::Sn115 | Self::Sn117 | Self::Sn119 => 35.0,
891 Self::H2 => 30.0,
892 Self::Li6 | Self::Li7 => 15.0,
893 Self::B11 => 35.0,
894 Self::B10 => 70.0,
895 Self::N14 => 90.0,
896 Self::Na23 | Self::Mg25 | Self::Ca43 | Self::Sr87 => 80.0,
897 Self::Al27 | Self::Sc45 => 120.0,
898 Self::K39 | Self::K41 | Self::Rb87 | Self::Cs133 | Self::Ba135 | Self::Ba137 => 140.0,
899 Self::K40 | Self::Rb85 => 220.0,
900 Self::O17 | Self::S33 => 180.0,
901 Self::Cl35 | Self::Cl37 => 260.0,
902 Self::Br79 | Self::Br81 => 600.0,
903 Self::I127 => 1500.0,
904 Self::Xe131 | Self::Hg201 => 120.0,
905 Self::V50 | Self::V51 | Self::Cu63 | Self::Cu65 | Self::Ga69 | Self::Ga71 => 180.0,
906 Self::Ti47 | Self::Ti49 | Self::Zn67 | Self::As75 | Self::Sb121 | Self::Sb123 => 150.0,
907 Self::Cr53 | Self::Mn55 | Self::Co59 | Self::Nb93 => 260.0,
908 Self::Mo95 | Self::Mo97 | Self::Ru99 | Self::Ru101 | Self::In113 | Self::In115 => 200.0,
909 Self::Bi209 | Self::Au197 => 320.0,
910 _ if self.is_quadrupolar() => 120.0,
911 _ => 15.0,
912 }
913 }
914
915 pub fn empirical_range(self) -> (f64, f64) {
916 match self {
917 Self::H1 | Self::H2 | Self::H3 => (-2.0, 14.0),
918 Self::C13 => (-10.0, 230.0),
919 Self::F19 => (-260.0, 100.0),
920 Self::P31 => (-250.0, 250.0),
921 Self::N14 | Self::N15 => (-400.0, 700.0),
922 Self::B10 | Self::B11 => (-120.0, 120.0),
923 Self::Si29 => (-200.0, 200.0),
924 Self::Se77 => (-1000.0, 2000.0),
925 Self::O17 => (-100.0, 1200.0),
926 Self::S33 => (-500.0, 800.0),
927 Self::Cl35 | Self::Cl37 => (-1000.0, 1500.0),
928 Self::Br79 | Self::Br81 => (-2500.0, 5000.0),
929 Self::I127 => (-4000.0, 9000.0),
930 Self::Te123 | Self::Te125 => (-2000.0, 3000.0),
931 Self::Xe129 | Self::Xe131 => (-500.0, 500.0),
932 Self::Li6 | Self::Li7 | Self::Na23 => (-80.0, 80.0),
933 Self::K39 | Self::K40 | Self::K41 => (-200.0, 200.0),
934 Self::Be9 | Self::Mg25 | Self::Ca43 | Self::Sr87 => (-100.0, 200.0),
935 Self::Rb85 | Self::Rb87 | Self::Cs133 | Self::Ba135 | Self::Ba137 => (-150.0, 250.0),
936 Self::He3 => (-50.0, 50.0),
937 Self::Al27 => (-50.0, 120.0),
938 Self::Sc45 | Self::Ti47 | Self::Ti49 | Self::V50 | Self::V51 => (-2500.0, 2500.0),
939 Self::Cr53 | Self::Mn55 | Self::Fe57 | Self::Co59 | Self::Ni61 => (-5000.0, 10000.0),
940 Self::Cu63 | Self::Cu65 | Self::Zn67 | Self::Ga69 | Self::Ga71 => (-1500.0, 1500.0),
941 Self::Ge73 | Self::As75 => (-1500.0, 1500.0),
942 Self::Zr91 | Self::Nb93 | Self::Mo95 | Self::Mo97 => (-4000.0, 4000.0),
943 Self::Ru99 | Self::Ru101 | Self::Rh103 | Self::Pd105 => (-6000.0, 6000.0),
944 Self::Ag107 | Self::Ag109 => (-2000.0, 2000.0),
945 Self::Cd111 | Self::Cd113 => (-1200.0, 1200.0),
946 Self::In113 | Self::In115 => (-1000.0, 1500.0),
947 Self::Sn115 | Self::Sn117 | Self::Sn119 => (-2500.0, 1500.0),
948 Self::Sb121 | Self::Sb123 => (-3000.0, 3000.0),
949 Self::W183 => (-4000.0, 2000.0),
950 Self::Pt195 => (-7000.0, 2000.0),
951 Self::Au197 => (-2000.0, 8000.0),
952 Self::Hg199 | Self::Hg201 => (-4000.0, 4000.0),
953 Self::Tl203 | Self::Tl205 => (-3000.0, 2000.0),
954 Self::Pb207 => (-6000.0, 6000.0),
955 Self::Bi209 => (-8000.0, 8000.0),
956 }
957 }
958
959 pub fn empirical_center(self) -> f64 {
960 match self {
961 Self::H1 | Self::H2 | Self::H3 => 2.5,
962 Self::C13 => 80.0,
963 Self::N14 | Self::N15 => 120.0,
964 Self::O17 => 180.0,
965 Self::F19 => -120.0,
966 Self::P31 => 10.0,
967 Self::B10 | Self::B11 => 15.0,
968 Self::Si29 => -20.0,
969 Self::Se77 => 120.0,
970 Self::S33 => 80.0,
971 Self::Cl35 | Self::Cl37 | Self::Br79 | Self::Br81 | Self::I127 => 0.0,
972 Self::Te123 | Self::Te125 => 100.0,
973 Self::Al27 => 35.0,
974 Self::Sc45 | Self::Ti47 | Self::Ti49 | Self::V50 | Self::V51 => 0.0,
975 Self::Cr53 | Self::Mn55 | Self::Fe57 | Self::Co59 | Self::Ni61 => 1500.0,
976 Self::Cu63 | Self::Cu65 | Self::Zn67 | Self::Ga69 | Self::Ga71 => 0.0,
977 Self::Ge73 | Self::As75 => 100.0,
978 Self::Zr91 | Self::Nb93 | Self::Mo95 | Self::Mo97 => 0.0,
979 Self::Ru99 | Self::Ru101 | Self::Rh103 | Self::Pd105 => -250.0,
980 Self::Ag107 | Self::Ag109 => 0.0,
981 Self::Cd111 | Self::Cd113 => 0.0,
982 Self::In113 | Self::In115 => 250.0,
983 Self::Sn115 | Self::Sn117 | Self::Sn119 => -300.0,
984 Self::Sb121 | Self::Sb123 => -150.0,
985 Self::W183 => -800.0,
986 Self::Pt195 => -3200.0,
987 Self::Au197 => 1200.0,
988 Self::Hg199 | Self::Hg201 => -200.0,
989 Self::Tl203 | Self::Tl205 => 150.0,
990 Self::Pb207 => 500.0,
991 Self::Bi209 => 1200.0,
992 Self::He3
993 | Self::Li6
994 | Self::Li7
995 | Self::Be9
996 | Self::Na23
997 | Self::Mg25
998 | Self::K39
999 | Self::K40
1000 | Self::K41
1001 | Self::Ca43
1002 | Self::Rb85
1003 | Self::Rb87
1004 | Self::Sr87
1005 | Self::Cs133
1006 | Self::Ba135
1007 | Self::Ba137
1008 | Self::Xe129
1009 | Self::Xe131 => 0.0,
1010 }
1011 }
1012
1013 pub fn reference_shielding(self) -> f64 {
1014 match self {
1015 Self::H1 | Self::H2 | Self::H3 => 31.7,
1016 Self::C13 => 188.0,
1017 Self::N14 | Self::N15 => 244.0,
1018 Self::O17 => 324.0,
1019 Self::F19 => 328.0,
1020 Self::P31 => 328.0,
1021 Self::B10 | Self::B11 => 105.0,
1022 Self::Si29 => 420.0,
1023 Self::Se77 => 860.0,
1024 Self::S33 => 1000.0,
1025 _ => self.free_atom_diamagnetic() * 0.85,
1026 }
1027 }
1028
1029 pub fn free_atom_diamagnetic(self) -> f64 {
1030 match self.atomic_number() {
1031 1 => 17.75,
1032 2 => 59.93,
1033 3 => 97.0,
1034 4 => 140.0,
1035 5 => 185.0,
1036 6 => 260.7,
1037 7 => 325.5,
1038 8 => 398.0,
1039 9 => 479.0,
1040 11 => 610.0,
1041 12 => 690.0,
1042 13 => 780.0,
1043 14 => 872.0,
1044 15 => 993.0,
1045 16 => 1118.0,
1046 17 => 1253.0,
1047 atomic_number => atomic_number as f64 * 17.0,
1048 }
1049 }
1050}