Repository: blairconrad/dicognito

Issue:
Anonymizing dataset with StationName but no Modality fails
Anonymizing a dataset with a supplied `StationName` attribute but no sibling `Modality` fails with this output:

```
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2040, in walk
    callback(self, data_element)  # self = this Dataset
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 120, in _anonymize_element
    if handler(dataset, data_element):
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 48, in __call__
    element_anonymizer(dataset, data_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 67, in anonymize_station_name
    data_element.value = dataset.Modality + "01"
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 778, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Dataset' object has no attribute 'Modality'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2046, in walk
    dataset.walk(callback)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2046, in walk
    dataset.walk(callback)
  File "c:\program files (x86)\python38-32\lib\contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 34, in tag_in_exception
    raise type(ex)(msg)
AttributeError: With tag (0008, 1010) got exception: 'Dataset' object has no attribute 'Modality'
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2040, in walk
    callback(self, data_element)  # self = this Dataset
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 120, in _anonymize_element
    if handler(dataset, data_element):
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 48, in __call__
    element_anonymizer(dataset, data_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 67, in anonymize_station_name
    data_element.value = dataset.Modality + "01"
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 778, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Dataset' object has no attribute 'Modality'

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\program files (x86)\python38-32\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Program Files (x86)\Python38-32\Scripts\dicognito.exe\__main__.py", line 7, in <module>
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\__main__.py", line 119, in main
    anonymizer.anonymize(dataset)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 114, in anonymize
    dataset.walk(self._anonymize_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2046, in walk
    dataset.walk(callback)
  File "c:\program files (x86)\python38-32\lib\contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 34, in tag_in_exception
    raise type(ex)(msg)
AttributeError: With tag (0018, 9506) got exception: With tag (0008, 1010) got exception: 'Dataset' object has no attribute 'Modality'
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2040, in walk
    callback(self, data_element)  # self = this Dataset
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 120, in _anonymize_element
    if handler(dataset, data_element):
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 48, in __call__
    element_anonymizer(dataset, data_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 67, in anonymize_station_name
    data_element.value = dataset.Modality + "01"
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 778, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Dataset' object has no attribute 'Modality'
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2040, in walk
    callback(self, data_element)  # self = this Dataset
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 120, in _anonymize_element
    if handler(dataset, data_element):
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 48, in __call__
    element_anonymizer(dataset, data_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 67, in anonymize_station_name
    data_element.value = dataset.Modality + "01"
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 778, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Dataset' object has no attribute 'Modality'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2046, in walk
    dataset.walk(callback)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2046, in walk
    dataset.walk(callback)
  File "c:\program files (x86)\python38-32\lib\contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 34, in tag_in_exception
    raise type(ex)(msg)
AttributeError: With tag (0008, 1010) got exception: 'Dataset' object has no attribute 'Modality'
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\tag.py", line 27, in tag_in_exception
    yield
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 2040, in walk
    callback(self, data_element)  # self = this Dataset
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\anonymizer.py", line 120, in _anonymize_element
    if handler(dataset, data_element):
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 48, in __call__
    element_anonymizer(dataset, data_element)
  File "c:\program files (x86)\python38-32\lib\site-packages\dicognito\equipmentanonymizer.py", line 67, in anonymize_station_name
    data_element.value = dataset.Modality + "01"
  File "c:\program files (x86)\python38-32\lib\site-packages\pydicom\dataset.py", line 778, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Dataset' object has no attribute 'Modality'
```

Discussion:

Patch:
diff --git a/src/dicognito/anonymizer.py b/src/dicognito/anonymizer.py
index b0f6a8b..80e991f 100644
--- a/src/dicognito/anonymizer.py
+++ b/src/dicognito/anonymizer.py
@@ -96,6 +96,7 @@ class Anonymizer:
                 "PlacerOrderNumberProcedure",
                 "RequestedProcedureID",
                 "ScheduledProcedureStepID",
+                "StationName",
                 "StudyID",
             ),
             address_anonymizer,
diff --git a/src/dicognito/equipmentanonymizer.py b/src/dicognito/equipmentanonymizer.py
index 35e41de..cb4bd46 100644
--- a/src/dicognito/equipmentanonymizer.py
+++ b/src/dicognito/equipmentanonymizer.py
@@ -17,7 +17,6 @@ class EquipmentAnonymizer:
             pydicom.datadict.tag_for_keyword("InstitutionName"): self.anonymize_institution_name,
             pydicom.datadict.tag_for_keyword("InstitutionAddress"): self.anonymize_institution_address,
             pydicom.datadict.tag_for_keyword("InstitutionalDepartmentName"): self.anonymize_department_name,
-            pydicom.datadict.tag_for_keyword("StationName"): self.anonymize_station_name,
         }
 
     def __call__(self, dataset, data_element):
@@ -33,8 +32,8 @@ class EquipmentAnonymizer:
         data_element : pydicom.dataset.DataElement
             The current element. Will be anonymized if it has a value
             and if its keyword is one of InstitutionName,
-            InstitutionAddress, InstitutionalDepartmentName, or
-            StationName. Additionally, if its keyword is InstitutionName,
+            InstitutionAddress, or InstitutionalDepartmentName.
+            Additionally, if its keyword is InstitutionName,
             then InstitutionAddress will also be anonymized.
 
         Returns
@@ -62,6 +61,3 @@ class EquipmentAnonymizer:
 
     def anonymize_department_name(self, dataset, data_element):
         data_element.value = "RADIOLOGY"
-
-    def anonymize_station_name(self, dataset, data_element):
-        data_element.value = dataset.Modality + "01"
diff --git a/src/dicognito/release_notes.md b/src/dicognito/release_notes.md
index 6a4a228..1a07c5f 100644
--- a/src/dicognito/release_notes.md
+++ b/src/dicognito/release_notes.md
@@ -9,8 +9,8 @@
 ### Fixed
 
 - Deflated files are corrupt when anonymized from the command line ([#80](https://github.com/blairconrad/dicognito/issues/80))
-
 - Date/time offset is not always the same for a given seed ([#86](https://github.com/blairconrad/dicognito/issues/86))
+- Anonymizing dataset with StationName but no Modality fails ([#97](https://github.com/blairconrad/dicognito/issues/97))
 
 
 ## 0.10.0


Test patch:
diff --git a/tests/test_anonymize_single_instance.py b/tests/test_anonymize_single_instance.py
index 5cffe58..912800c 100644
--- a/tests/test_anonymize_single_instance.py
+++ b/tests/test_anonymize_single_instance.py
@@ -313,6 +313,19 @@ def test_equipment_gets_anonymized():
         assert new_station_name != original_station_name
 
 
+def test_station_gets_anonymized_when_no_modality():
+    with load_test_instance() as dataset:
+        original_station_name = dataset.StationName
+        del dataset.Modality
+
+        anonymizer = Anonymizer()
+        anonymizer.anonymize(dataset)
+
+        new_station_name = dataset.StationName
+
+        assert new_station_name != original_station_name
+
+
 def test_requesting_service_gets_anonymized():
     with load_test_instance() as dataset:
         original = dataset.RequestingService