diff --git a/metadata/PET_Radionuclide.mkd b/metadata/PET_Radionuclide.mkd index d0dfb4a..adda3d8 100644 --- a/metadata/PET_Radionuclide.mkd +++ b/metadata/PET_Radionuclide.mkd @@ -2,41 +2,41 @@ Table taken from https://dicom.nema.org/medical/Dicom/2016b/output/chtml/part16/sect_CID_4020.html -| Code Value | Code Meaning | -|:----------:|:---------------:| -| C-105A1 | ^11^Carbon | -| C-107A1 | ^13^Nitrogen | -| C-1018C | ^14^Oxygen | -| C-B1038 | ^15^Oxygen | -| C-111A1 | ^18^Fluorine | -| C-155A1 | ^22^Sodium | -| C-135A4 | ^38^Potassium | -| 126605 | ^43^Scandium | -| 126600 | ^44^Scandium | -| C-166A2 | ^45^Titanium | -| 126601 | ^51^Manganese | -| C-130A1 | ^52^Iron | -| C-149A1 | ^52^Manganese | -| 126607 | ^52m^Manganese | -| C-127A4 | ^60^Copper | -| C-127A1 | ^61^Copper | -| C-127A5 | ^62^Copper | -| C-141A1 | ^62^Zinc | -| C-127A | ^64^Copper | -| C-131A1 | ^66^Gallium | -| C-131A3 | ^68^Gallium | -| C-128A2 | ^68^Germanium | -| 126602 | ^70^Arsenic | -| C-115A2 | ^72^Arsenic | -| C-116A2 | ^73^Selenium | -| C-113A1 | ^75^Bromine | -| C-113A2 | ^76^Bromine | -| C-113A3 | ^77^Bromine | -| C-159A2 | ^82^Rubidium | -| C-162A3 | ^86^Yttrium | -| C-168A4 | ^89^Zirconium | -| 126603 | ^90^Niobium | -| C-162A7 | ^90^Yttrium | -| C-163AA | ^94m^Technetium | -| C-114A5 | ^124^Iodine | -| 126606 | ^152^Terbium | +| Code Value | Code Meaning | Isotope Abbreviation | +|:----------:|:---------------:|:--------------------:| +| C-105A1 | ^11^Carbon | 11C | +| C-107A1 | ^13^Nitrogen | 13N | +| C-1018C | ^14^Oxygen | 14O | +| C-B1038 | ^15^Oxygen | 150 | +| C-111A1 | ^18^Fluorine | 18F | +| C-155A1 | ^22^Sodium | 22Na | +| C-135A4 | ^38^Potassium | 38K | +| 126605 | ^43^Scandium | 43Sc | +| 126600 | ^44^Scandium | 44Sc | +| C-166A2 | ^45^Titanium | 45Ti | +| 126601 | ^51^Manganese | 51Mn | +| C-130A1 | ^52^Iron | 52Fe | +| C-149A1 | ^52^Manganese | 52Mn | +| 126607 | ^52m^Manganese | 52mMn | +| C-127A4 | ^60^Copper | 60Cu | +| C-127A1 | ^61^Copper | 61Cu | +| C-127A5 | ^62^Copper | 62Cu | +| C-141A1 | ^62^Zinc | 62Zn | +| C-127A | ^64^Copper | 64Cu | +| C-131A1 | ^66^Gallium | 66Ga | +| C-131A3 | ^68^Gallium | 68Ga | +| C-128A2 | ^68^Germanium | 68Ge | +| 126602 | ^70^Arsenic | 70As | +| C-115A2 | ^72^Arsenic | 72As | +| C-116A2 | ^73^Selenium | 73Se | +| C-113A1 | ^75^Bromine | 75Br | +| C-113A2 | ^76^Bromine | 76Br | +| C-113A3 | ^77^Bromine | 77Br | +| C-159A2 | ^82^Rubidium | 82Rb | +| C-162A3 | ^86^Yttrium | 86Y | +| C-168A4 | ^89^Zirconium | 89Zr | +| 126603 | ^90^Niobium | 90Nb | +| C-162A7 | ^90^Yttrium | 90Y | +| C-163AA | ^94m^Technetium | 94mTc | +| C-114A5 | ^124^Iodine | 124I | +| 126606 | ^152^Terbium | 152Tb | diff --git a/pypet2bids/pypet2bids/helper_functions.py b/pypet2bids/pypet2bids/helper_functions.py index 2a28ec3..a53e322 100644 --- a/pypet2bids/pypet2bids/helper_functions.py +++ b/pypet2bids/pypet2bids/helper_functions.py @@ -1149,3 +1149,37 @@ def first_middle_last_frames_to_text( delimiter="\t", fmt="%s", ) + +def reorder_isotope(isotope: str) -> str: + """ + Reorders the isotope string to be in the format of "isotope""element name" + :param isotope: isotope string + :type isotope: str + :return: reordered isotope string + :rtype: str + """ + # remove all non-alphanumeric characters from isotope + isotope = re.findall(r"[a-zA-Z0-9]+", isotope) + # combine all elements in isotope into one string + isotope = "".join(isotope) + # collect the isotope number from the isotope string + isotope_num = re.findall(r"\d+", isotope) + # collect the element name from the isotope string + element_name = re.findall(r"[a-zA-Z]+", isotope) + + # capitalize the first letter of the element name if the element name's length is <= 2 + if 1 < len(element_name[0]) <= 2: + e = element_name[0][0].capitalize() + if len(element_name[0]) == 2: + e += element_name[0][1].lower() + elif len(element_name[0]) == 1: + e = element_name[0].capitalize() + + # special case for 52mMn + if "".join(element_name).lower() == "mmn" or "".join(element_name).lower() == "mnm": + e = "mMn" + + # reorder to put the number before the element name + isotope = f"{isotope_num[0]}{e}" + + return isotope diff --git a/pypet2bids/tests/test_helper_functions.py b/pypet2bids/tests/test_helper_functions.py index 52ba136..5a2d39a 100644 --- a/pypet2bids/tests/test_helper_functions.py +++ b/pypet2bids/tests/test_helper_functions.py @@ -343,5 +343,20 @@ def test_collect_pet_spreadsheets(): assert len(pet_spreadsheets) == 3 +def test_reorder_isotope(): + # tests whether the isotope is reordered correctly with the numerical part appearing before the string part + # and if any non-alphanumeric characters are present + isotopes = { + "11C": ["C11", "^11^C", "C-11", "11-C", "11C", "c11", "c-11", "11c"], + "18F": ["F18", "^18^F", "F-18", "18-F", "18F"], + "68Ga": ["Ga68", "^68^Ga", "Ga-68", "68-Ga", "68Ga"], + "52mMn": ["Mn52m", "Mn-52m", "52m-Mn", "52mMn"] + } + + for isotope, isotope_variants in isotopes.items(): + for isotope_variant in isotope_variants: + assert helper_functions.reorder_isotope(isotope_variant) == isotope + + if __name__ == "__main__": unittest.main()