Repository: pydicom/pydicom

Issue:
Comparing two codes where one is erroneously set as a SRT will throw KeyError
**Describe the bug**
The comparision of two codes does mapping from `SRT` codes to `SCT`. If comparision is done on a code that has `SRT` as the scheme designator but is not in the dictionary of `SRT` to `SCT` mappings, the comparision will throw a `KeyError`.

**Expected behavior**
If the mapping from `SRT` to `SCT` is not possible I would excpect the comparision to return `False` if the codes are not equal.

**Steps To Reproduce**
```python
wrong_srt_code = Code("111729", "SRT", "Specimen storage") # Is actually a DCM code
sct_code = Code("127790008", "SCT", "Staining")

wrong_srt_code == sct_code
```
Throws:
```
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[9], [line 4](vscode-notebook-cell:?execution_count=9&line=4)
      [1](vscode-notebook-cell:?execution_count=9&line=1) wrong_srt_code = Code("111729", "SRT", "Specimen storage") # Is actually a DCM code
      [2](vscode-notebook-cell:?execution_count=9&line=2) sct_code = Code("127790008", "SCT", "Staining")
----> [4](vscode-notebook-cell:?execution_count=9&line=4) wrong_srt_code == sct_code

File [c:\work\notebooks\.venv311\Lib\site-packages\pydicom\sr\coding.py:26](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:26), in Code.__eq__(self, other)
     [23](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:23) def __eq__(self, other: Any) -> Any:
     [24](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:24)     if self.scheme_designator == "SRT":
     [25](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:25)         self_mapped = Code(
---> [26](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:26)             value=snomed_mapping["SRT"][self.value],
     [27](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:27)             meaning="",
     [28](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:28)             scheme_designator="SCT",
     [29](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:29)             scheme_version=self.scheme_version,
     [30](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:30)         )
     [31](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:31)     else:
     [32](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:32)         self_mapped = Code(
     [33](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:33)             value=self.value,
     [34](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:34)             meaning="",
     [35](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:35)             scheme_designator=self.scheme_designator,
     [36](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:36)             scheme_version=self.scheme_version,
     [37](file:///C:/work/notebooks/.venv311/Lib/site-packages/pydicom/sr/coding.py:37)         )

KeyError: '111729'
```
**Your environment**
Please use the `pydicom.env_info` module (available in **pydicom 2 or later**)
to gather information about your environment and paste it into the issue:

```bash
module       | version
------       | -------
platform     | Windows-10-10.0.22631-SP0
Python       | 3.11.6 (tags/v3.11.6:8b6ee5b, Oct  2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)]
pydicom      | 3.0.0.dev0
gdcm         | 3.0.22
jpeg_ls      | **cannot determine version**
numpy        | 1.26.2
PIL          | 10.1.0
pylibjpeg    | 1.4.0
openjpeg     | 1.3.2
libjpeg      | _module not found_
```







Discussion:
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/pydicom/pydicom/pull/1995?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`34fbbd6`)](https://app.codecov.io/gh/pydicom/pydicom/commit/34fbbd607388008ce98a394fd03c796aa49396b1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) 97.86% compared to head [(`d31e9cf`)](https://app.codecov.io/gh/pydicom/pydicom/pull/1995?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) 97.97%.
> Report is 17 commits behind head on main.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1995      +/-   ##
==========================================
+ Coverage   97.86%   97.97%   +0.11%     
==========================================
  Files          63       63              
  Lines       10767    10968     +201     
==========================================
+ Hits        10537    10746     +209     
+ Misses        230      222       -8     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/pydicom/pydicom/pull/1995?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom).

scaramallion: Can you add a note to the release notes, please?

Patch:
diff --git a/doc/release_notes/v3.0.0.rst b/doc/release_notes/v3.0.0.rst
index d0d507764..77f631453 100644
--- a/doc/release_notes/v3.0.0.rst
+++ b/doc/release_notes/v3.0.0.rst
@@ -178,6 +178,9 @@ Fixes
   explicit and implicit VR when only the *Transfer Syntax UID* was changed (:issue:`1943`)
 * Fixed the ``jpeg_ls``, ``pillow`` and ``rle`` pixel data handlers not working
   correctly when a frame is spread across multiple fragments (:issue:`1774`)
+* Fixed a ``KeyError`` when comparing codes with one of the codes having
+  ``scheme_designator`` set to ``SRT`` but not being included in the ``SRT``
+  to ``SCT`` code mapping (:issue:`1994`)
 
 
 Deprecations
diff --git a/src/pydicom/sr/coding.py b/src/pydicom/sr/coding.py
index 2b9e37bd2..151ebe402 100644
--- a/src/pydicom/sr/coding.py
+++ b/src/pydicom/sr/coding.py
@@ -22,7 +22,7 @@ class Code(NamedTuple):
         return hash(self.scheme_designator + self.value)
 
     def __eq__(self, other: Any) -> Any:
-        if self.scheme_designator == "SRT":
+        if self.scheme_designator == "SRT" and self.value in snomed_mapping["SRT"]:
             self_mapped = Code(
                 value=snomed_mapping["SRT"][self.value],
                 meaning="",
@@ -37,7 +37,7 @@ class Code(NamedTuple):
                 scheme_version=self.scheme_version,
             )
 
-        if other.scheme_designator == "SRT":
+        if other.scheme_designator == "SRT" and other.value in snomed_mapping["SRT"]:
             other_mapped = Code(
                 value=snomed_mapping["SRT"][other.value],
                 meaning="",


Test patch:
diff --git a/tests/test_codes.py b/tests/test_codes.py
index cb842037e..71844ab1c 100644
--- a/tests/test_codes.py
+++ b/tests/test_codes.py
@@ -91,6 +91,12 @@ class TestCode:
         assert c1 == c2
         assert c2 == c1
 
+    def test_equal_not_in_snomed_mapping(self):
+        c1 = Code(self._value, self._scheme_designator, self._meaning)
+        c2 = Code("bla bal bla", "SRT", self._meaning)
+        assert c1 != c2
+        assert c2 != c1
+
 
 class TestCodesDict:
     def test_dcm_1(self):