Results and errors
What the frozen Session methods return, and the two exceptions a caller
is expected to catch. The names and fields on this page are frozen at
1.0 (API stability) unless the stability
page lists them as tier 2.
| Method | Returns |
|---|---|
ingest() |
IngestSummary |
audit(), scan_pixel_content() |
PhiReport of PhiFinding |
lock_identities(), lock_identities_batch() |
LockingResult, a list of Instance |
recover_patient_identity() |
Dict[str, Dict[str, Any]]: SOP Instance UID to the values its token holds |
export(format="dicom") |
ExportSummary |
export(format="wfdb") |
List[str], the paths written |
discover_redaction_zones() |
DiscoveryResult |
get_cohort_report() |
pandas.DataFrame |
phi_status_summary() |
Dict[str, Counter] of PhiStatus |
redact(), reconcile_private_tags(), auto_remediate_config() |
int |
Import the two exceptions from the package:
from isocenter import RedactionError, ExportError. Both subclass
RuntimeError.
Summaries
IngestSummary
dataclass
What ingest() did with each file it found.
A file takes exactly one of four routes. A declined file is not recorded as imported, so offering it again declines it again.
Attributes:
| Name | Type | Description |
|---|---|---|
ingested |
int
|
Files read into the graph. |
failures |
List[Tuple[str, str]]
|
|
declined |
int
|
Files refused because the session already holds
their SOP Instance UID (as another instance's UID, or as a
redacted instance's UID before redaction). Each has a
|
skipped |
int
|
Files already in the store, not read again. |
failed |
int
|
|
failed
property
How many files were rejected.
ExportSummary
dataclass
What export(format="dicom") wrote, and what it did not.
Attributes:
| Name | Type | Description |
|---|---|---|
written_uids |
List[str]
|
The SOP Instance UID of each instance
that reached disk, and nothing else. An instance with no UID
is not written and is in |
failures |
List[Tuple[str, str]]
|
|
written |
int
|
Files that reached disk, counted over distinct UIDs: two instances sharing a UID write one file. |
failed |
int
|
|
failed
property
How many instances did not.
written
property
How many files reached disk.
Counted over the de-duplicated UIDs: two instances sharing a UID write one file, the second overwriting the first.
Returns:
| Type | Description |
|---|---|
int
|
The number of distinct written UIDs. |
Findings
PhiReport(findings, failures=None)
A container for PHI findings that supports analysis and export.
Iterates, indexes and measures like the list of findings it wraps
(len(report), report[0], for finding in report), and adds
DataFrame export.
Attributes:
| Name | Type | Description |
|---|---|---|
findings |
List[PhiFinding]
|
The findings, one per report line. |
failures |
List[Tuple[str, str]]
|
|
to_dataframe()
Convert the findings to a pandas DataFrame, one row each.
Returns:
| Type | Description |
|---|---|
pd.DataFrame
|
A dataframe containing flattened finding details. |
Raises:
| Type | Description |
|---|---|
ImportError
|
If pandas is not installed. |
PhiFinding
dataclass
A potential PHI breach discovered during a scan: one report line.
Attributes:
| Name | Type | Description |
|---|---|---|
entity_uid |
str
|
Unique identifier of the entity (PatientID, SOPInstanceUID). |
entity_type |
str
|
|
field_name |
str
|
The specific field or tag description. |
value |
Any
|
The PHI value found. |
reason |
str
|
Why this was flagged (e.g. "Safe Harbor Rules"). |
tag |
Optional[str]
|
The DICOM tag (e.g., "0010,0010"). |
patient_id |
Optional[str]
|
Linkage for context. |
entity |
Any
|
The live object in |
remediation_proposal |
Optional[PhiRemediation]
|
The suggested fix,
which |
metadata |
Dict[str, Any]
|
Context carried with the finding. |
entity_path |
Tuple
|
Route from the Instance to the item this was
raised against, as |
PhiRemediation
dataclass
Proposed action to fix a PHI finding.
Attributes:
| Name | Type | Description |
|---|---|---|
action_type |
str
|
|
target_attr |
str
|
The attribute or tag to modify. |
new_value |
Any
|
The proposed new value (if known). |
original_value |
Any
|
The original value for audit/reversion. |
metadata |
Dict[str, Any]
|
Context metadata (e.g. patient linkage for date shifting). |
Identity locks
LockingResult
Bases: list
What lock_identities() returns: a list of the Instance objects
that received an identity token, whose repr is one line
(<LockingResult: N instances secured>) rather than every instance.
Exceptions
RedactionError(failures, attempted)
Bases: RuntimeError
Redaction did not remove what it was asked to remove.
Raised after the whole pass, not at the first failure: the instances that could be redacted are redacted, and the failures are already in the audit log, so a caller that catches this still gets a compliance report that grades REVIEW_REQUIRED.
A RuntimeError subclass, so except RuntimeError catches it; its
own class tells it from the export path's bare RuntimeErrors, which
mean nothing was written, where this means something unsafe is still
in the graph.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
failures
|
list
|
|
required |
attempted
|
int
|
How many instances the pass targeted, kept as
|
required |
ExportError(failures, attempted, folder=None)
Bases: RuntimeError
The export delivered nothing.
Raised by session.export() when zero of N planned instances
reached disk and at least one failed, in both formats: the DICOM path,
and WfdbExporter.export, where N is the waveform records attempted.
The message says "instances" in both: a WFDB record is written from
one waveform instance, and its failure is named by that instance's
UID, as the DICOM one is. Not raised on a partial export.
Raised last, after every record the run produces, so a caller who
catches this still holds a correct graph, a complete audit trail and
a compliance report grading REVIEW_REQUIRED. The DICOM path raises
after the collision report, the recoverable-identity disclosure, the
delivery counters, the EXPORT audit row and Done.. The WFDB path
has none of the first three; it raises after each record's ERROR or
DATA_LOSS row and its own EXPORT row.
A RuntimeError subclass, so except RuntimeError catches it.
write_tree raises a bare RuntimeError instead, for "this
serializer could not write".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
failures
|
list
|
|
required |
attempted
|
int
|
How many instances were planned; kept as
|
required |
folder
|
str
|
The output folder, named in the message. |
None
|
Building a graph by hand
isocenter.Builder is the frozen name of the class below; only
start_patient() is frozen, and the chain it starts is tier 2.
Builder
Build a Patient graph by hand, with no files behind it.
Import it as from isocenter import Builder:
patient = (Builder.start_patient("P123", "Doe^John")
.add_study("1.2.3", "20240101")
.add_series("1.2.3.1", "CT", 1)
.end_series().end_study().build())
start_patient(patient_id, name)
staticmethod
Begin building a Patient.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
patient_id
|
str
|
The Patient ID. There is no |
required |
name
|
str
|
The Patient's Name. |
required |
Returns:
| Type | Description |
|---|---|
PatientBuilder
|
A builder for the new patient. |