Skip to content

Commit c22be4b

Browse files
authored
Adjust default StoragePresentationContexts (#980)
1 parent 503a75f commit c22be4b

File tree

10 files changed

+161
-166
lines changed

10 files changed

+161
-166
lines changed

Diff for: docs/changelog/v3.0.0.rst

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. _v3.0.0:
2+
3+
3.0.0
4+
=====
5+
6+
The major breaking changes with the version 3.0 release are:
7+
8+
* Support for pydicom v3
9+
* Changed ``StoragePresentationContexts`` to match DCMTK implementation
10+
* Some presentation contexts were replaced

Diff for: docs/examples/storage.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ single CT dataset.
5757
Of course it's rarely the case that someone wants to store just CT images,
5858
so you can also use the inbuilt
5959
:attr:`~pynetdicom.presentation.StoragePresentationContexts` which contains
60-
presentation contexts for the first 128 storage SOP Classes when setting
60+
presentation contexts for the first 120 storage SOP Classes when setting
6161
the requested contexts, or just add as many contexts as you need.
6262

6363
.. code-block:: python

Diff for: docs/user/ae.rst

+7-6
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ Adding presentation contexts all at once:
8888
>>> ae.requested_contexts = StoragePresentationContexts
8989

9090
Here :attr:`~pynetdicom.presentation.StoragePresentationContexts` is a
91-
prebuilt list of presentation contexts containing (almost) all the Storage
92-
Service Class' :dcm:`supported SOP Classes <part04/sect_B.5.html>`,
91+
prebuilt list of presentation contexts containing 120 of the most commonly used Storage
92+
Service Classes' :dcm:`supported SOP Classes <part04/sect_B.5.html>`,
9393
and there's a :ref:`similar list<api_presentation_prebuilt>` for all
9494
the supported service classes.
9595
Alternatively you can build your own list of presentation contexts, either
@@ -115,12 +115,13 @@ Combining the all-at-once and one-by-one approaches:
115115
>>> from pynetdicom import AE, StoragePresentationContexts
116116
>>> from pynetdicom.sop_class import Verification
117117
>>> ae = AE()
118-
>>> ae.requested_contexts = StoragePresentationContexts[:127]
118+
>>> ae.requested_contexts = StoragePresentationContexts
119119
>>> ae.add_requested_context(Verification)
120120

121121
As the association *Requestor* you're limited to a total of 128 requested
122122
presentation contexts, so attempting to add more than 128 contexts will raise
123-
a :class:`ValueError` exception.
123+
a :class:`ValueError` exception. :attr:`~pynetdicom.presentation.StoragePresentationContexts` consists of 120 of most commonly used Storage
124+
Service Classes, therefore you are able to add 8 additional presentation contexts without rasing a :class:`ValueError` exception.
124125

125126
When you add presentation contexts as shown above, the following transfer
126127
syntaxes are used by default for each context:
@@ -285,8 +286,8 @@ Adding presentation contexts all at once:
285286
>>> ae.supported_contexts = StoragePresentationContexts
286287

287288
Here :attr:`~pynetdicom.presentation.StoragePresentationContexts` is a prebuilt
288-
:class:`list` of presentation contexts containing (almost) all the Storage
289-
Service Class' :dcm:`supported SOP Classes<part04/sect_B.5.html>`,
289+
:class:`list` of presentation contexts containing 120 of the most commonly used Storage
290+
Service Classes' :dcm:`supported SOP Classes<part04/sect_B.5.html>`,
290291
and there's a :ref:`similar list<api_presentation_prebuilt>` for
291292
all the supported service classes. Alternatively you can build your own list
292293
of presentation contexts, either through creating new

Diff for: docs/user/association.rst

+5-4
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,16 @@ also acting as a Storage SCP), plus a *User Identity Negotiation* item:
9595
9696
ae = AE()
9797
# Contexts supported as a Storage SCP - requires Role Selection
98-
# Note that we are limited to a maximum of 128 contexts so we
99-
# only include 127 to make room for the QR Get context
100-
ae.requested_contexts = StoragePresentationContexts[:127]
98+
# Note that we are limited to a maximum of 128 contexts.
99+
# StoragePresentationContexts includes 120, it is therefore
100+
# possible to add 8 additional presentation contexts if needed.
101+
ae.requested_contexts = StoragePresentationContexts
101102
# Contexts proposed as a QR SCU
102103
ae.add_requested_context = PatientRootQueryRetrieveInformationModelGet
103104
104105
# Add role selection items for the contexts we will be supporting as an SCP
105106
negotiation_items = []
106-
for context in StoragePresentationContexts[:127]:
107+
for context in StoragePresentationContexts:
107108
role = build_role(context.abstract_syntax, scp_role=True)
108109
negotiation_items.append(role)
109110

Diff for: pynetdicom/apps/getscu/getscu.py

+1-14
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
PatientRootQueryRetrieveInformationModelGet,
2121
StudyRootQueryRetrieveInformationModelGet,
2222
PatientStudyOnlyQueryRetrieveInformationModelGet,
23-
EncapsulatedSTLStorage,
24-
EncapsulatedOBJStorage,
25-
EncapsulatedMTLStorage,
2623
)
2724

2825

@@ -248,16 +245,6 @@ def main(args=None):
248245
APP_LOGGER.exception(exc)
249246
sys.exit(1)
250247

251-
# Exclude these SOP Classes
252-
_exclusion = [
253-
EncapsulatedSTLStorage,
254-
EncapsulatedOBJStorage,
255-
EncapsulatedMTLStorage,
256-
]
257-
store_contexts = [
258-
cx for cx in StoragePresentationContexts if cx.abstract_syntax not in _exclusion
259-
]
260-
261248
# Create application entity
262249
# Binding to port 0 lets the OS pick an available port
263250
ae = AE(ae_title=args.calling_aet)
@@ -270,7 +257,7 @@ def main(args=None):
270257
ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
271258
ae.add_requested_context(StudyRootQueryRetrieveInformationModelGet)
272259
ae.add_requested_context(PatientStudyOnlyQueryRetrieveInformationModelGet)
273-
for cx in store_contexts:
260+
for cx in StoragePresentationContexts:
274261
ae.add_requested_context(cx.abstract_syntax)
275262
# Add SCP/SCU Role Selection Negotiation to the extended negotiation
276263
# We want to act as a Storage SCP

Diff for: pynetdicom/apps/tests/test_getscu.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,14 @@ def handle_release(event):
111111
assert "GETSCU" == requestor.ae_title
112112
assert 16382 == requestor.maximum_length
113113
assert "ANY-SCP" == requestor.primitive.called_ae_title
114-
assert 125 == len(requestor.extended_negotiation)
114+
assert 120 == len(requestor.extended_negotiation)
115115
assert (1, 1) == requestor.asynchronous_operations
116116
assert {} == requestor.sop_class_common_extended
117117
assert {} == requestor.sop_class_extended
118118
assert requestor.role_selection != {}
119119
assert requestor.user_identity == None
120120
cxs = requestor.primitive.presentation_context_definition_list
121-
assert len(cxs) == 128
121+
assert len(cxs) == 123
122122
cxs = {cx.abstract_syntax: cx for cx in cxs}
123123
assert PatientRootQueryRetrieveInformationModelGet in cxs
124124
cx = cxs[PatientRootQueryRetrieveInformationModelGet]

Diff for: pynetdicom/apps/tests/test_storescu.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def handle_release(event):
104104
assert {} == requestor.sop_class_extended
105105
assert requestor.user_identity == None
106106
cxs = requestor.primitive.presentation_context_definition_list
107-
assert len(cxs) == 128
107+
assert len(cxs) == 120
108108
cxs = {cx.abstract_syntax: cx for cx in cxs}
109109
assert CTImageStorage in cxs
110110
assert cxs[CTImageStorage].transfer_syntax == [
@@ -422,7 +422,7 @@ def handle_release(event):
422422
assert events[1].event == evt.EVT_RELEASED
423423
requestor = events[1].assoc.requestor
424424
cxs = requestor.primitive.presentation_context_definition_list
425-
assert len(cxs) == 128
425+
assert len(cxs) == 120
426426
cxs = {cx.abstract_syntax: cx for cx in cxs}
427427
assert CTImageStorage in cxs
428428
assert cxs[CTImageStorage].transfer_syntax == [ExplicitVRLittleEndian]
@@ -459,7 +459,7 @@ def handle_release(event):
459459
requestor = events[1].assoc.requestor
460460
cxs = requestor.primitive.presentation_context_definition_list
461461
cxs = requestor.primitive.presentation_context_definition_list
462-
assert len(cxs) == 128
462+
assert len(cxs) == 120
463463
cxs = {cx.abstract_syntax: cx for cx in cxs}
464464
assert CTImageStorage in cxs
465465
assert cxs[CTImageStorage].transfer_syntax == [ExplicitVRBigEndian]
@@ -496,7 +496,7 @@ def handle_release(event):
496496
requestor = events[1].assoc.requestor
497497
cxs = requestor.primitive.presentation_context_definition_list
498498
cxs = requestor.primitive.presentation_context_definition_list
499-
assert len(cxs) == 128
499+
assert len(cxs) == 120
500500
cxs = {cx.abstract_syntax: cx for cx in cxs}
501501
assert CTImageStorage in cxs
502502
assert cxs[CTImageStorage].transfer_syntax == [ImplicitVRLittleEndian]

0 commit comments

Comments
 (0)