-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is Print Management Service Examples working? #777
Comments
After minor adjusment of example (because of not getting affected sop instance, and also somehow generated uid could be rejected) it started to work, kinda, although I have encountered with another issue import sys
from pydicom import dcmread
from pydicom.dataset import Dataset
from pydicom.uid import generate_uid
from pynetdicom import AE, evt, debug_logger
from pynetdicom.sop_class import (
BasicGrayscalePrintManagementMeta,
BasicFilmSession,
BasicFilmBox,
BasicGrayscaleImageBox,
Printer,
PrinterInstance
)
debug_logger()
# The SOP Instance containing the grayscale image data to be printed
DATASET = dcmread('path/to/file.dcm')
def build_session():
"""Return an N-CREATE *Attribute List* for creating a Basic Film Session
Returns
-------
pydicom.dataset.Dataset
An N-CREATE *Attribute List* dataset that can be used to create a
*Basic Film Session SOP Class* instance.
"""
attr_list = Dataset()
attr_list.NumberOfCopies = '1' # IS
attr_list.PrintPriority = 'LOW' # CS
attr_list.MediumType = 'PAPER' # CS
attr_list.FilmDestination = 'SOMEWHERE' # CS
attr_list.FilmSessionLabel = 'TEST JOB' # LO
attr_list.MemoryAllocation = '' # IS
attr_list.OwnerID = 'PYNETDICOM' # SH
return attr_list
def build_film_box(session):
"""Return an N-CREATE *Attribute List* for creating a Basic Film Box.
In this example we just have a single Image Box.
Parameters
----------
session : pydicom.dataset.Dataset
The *Basic Film Session SOP Class* instance returned by SCP in
response to the N-CREATE request that created it.
Returns
-------
pydicom.dataset.Dataset
An N-CREATE *Attribute List* dataset that can be used to create a
*Basic Film Box SOP Class* instance.
"""
# The "film" consists of a single Image Box
attr_list = Dataset()
attr_list.ImageDisplayFormat = 'STANDARD\1,1'
attr_list.FilmOrientation = 'PORTRAIT'
attr_list.FilmSizeID = 'A4'
# Can only contain a single item, is a reference to the *Film Session*
attr_list.ReferencedFilmSessionSequence = [Dataset()]
item = attr_list.ReferencedFilmSessionSequence[0]
item.ReferencedSOPClassUID = session.SOPClassUID
item.ReferencedSOPInstanceUID = session.SOPInstanceUID
return attr_list
def build_image_box(im):
"""Return an N-SET *Attribute List* for updating a Basic Grayscale Image Box
Parameters
----------
im : pydicom.dataset.Dataset
The SOP Instance containing the pixel data that is to be printed.
Returns
-------
pydicom.dataset.Dataset
An N-SET *Attribute List* dataset that can be used to update the
*Basic Grayscale Image Box SOP Class* instance.
"""
attr_list = Dataset()
attr_list.ImageBoxPosition = 1 # US
# Zero or one item only
attr_list.ReferencedImageBoxSequence = [Dataset()]
item = attr_list.ReferencedImageBoxSequence[0]
item.SamplesPerPixel = im.SamplesPerPixel
item.PhotometricInterpretation = im.PhotometricInterpretation
item.Rows = im.Rows
item.Columns = im.Columns
item.BitsAllocated = im.BitsAllocated
item.BitsStored = im.BitsStored
item.HighBit = im.HighBit
item.PixelRepresentation = im.PixelRepresentation
item.PixelData = im.PixelData
return attr_list
def handle_n_er(event):
"""Ignore the N-EVENT-REPORT notification"""
return 0x0000
handlers = [(evt.EVT_N_EVENT_REPORT, handle_n_er)]
ae = AE()
ae.add_requested_context(BasicGrayscalePrintManagementMeta)
assoc = ae.associate("127.0.0.1", 11112, evt_handlers=handlers)
if assoc.is_established:
# Step 1: Check the status of the printer
# (2110,0010) Printer Status
# (2110,0020) Printer Status Info
# Because the association was negotiated using a presentation context
# with a Meta SOP Class we need to use the `meta_uid` keyword
# parameter to ensure we use the correct context
status, attr_list = assoc.send_n_get(
[0x21100010, 0x21100020], # Attribute Identifier List
Printer, # Affected SOP Class UID
PrinterInstance, # Well-known Printer SOP Instance
meta_uid=BasicGrayscalePrintManagementMeta
)
if status and status.Status == 0x0000:
if getattr(attr_list, 'PrinterStatus', None) != "NORMAL":
print("Printer status is not 'NORMAL'")
assoc.release()
sys.exit()
else:
print("Failed to get the printer status")
assoc.release()
sys.exit()
else:
print("Failed to get the printer status")
assoc.release()
sys.exit()
print('Printer ready')
affected_sop_instance_uid = generate_uid(prefix=None) # Affected SOP Instance UID
# Step 2: Create *Film Session* instance
status, film_session = assoc.send_n_create(
build_session(), # Attribute List
BasicFilmSession, # Affected SOP Class UID
affected_sop_instance_uid, # Affected SOP Instance UID
meta_uid=BasicGrayscalePrintManagementMeta
)
film_session.SOPInstanceUID = affected_sop_instance_uid
film_session.SOPClassUID = BasicFilmSession
if not status or status.Status != 0x0000:
print('Creation of Film Session failed, releasing association')
assoc.release()
sys.exit()
print('Film Session created')
affected_sop_instance_uid_2 = generate_uid(prefix=None)
# Step 3: Create *Film Box* and *Image Box(es)*
status, film_box = assoc.send_n_create(
build_film_box(film_session),
BasicFilmBox,
affected_sop_instance_uid_2,
meta_uid=BasicGrayscalePrintManagementMeta
)
if not status or status.Status != 0x0000:
print('Creation of the Film Box failed, releasing association')
assoc.release()
sys.exit()
print('Film Box created')
film_box.SOPInstanceUID = affected_sop_instance_uid_2
film_box.SOPClassUID = BasicFilmBox
# Step 4: Update the *Image Box* with the image data
# In this example we only have one *Image Box* per *Film Box*
# Get the Image Box's SOP Class and SOP Instance UIDs
item = film_box.ReferencedImageBoxSequence[0]
status, image_box = assoc.send_n_set(
build_image_box(DATASET),
item.ReferencedSOPClassUID,
item.ReferencedSOPInstanceUID,
meta_uid=BasicGrayscalePrintManagementMeta
)
if not status or status.Status != 0x0000:
print('Updating the Image Box failed, releasing association')
assoc.release()
sys.exit()
print('Updated the Image Box with the image data')
# Step 5: Print the *Film Box*
status, action_reply = assoc.send_n_action(
None, # No *Action Information* needed
1, # Print the Film Box
film_box.SOPClassUID,
film_box.SOPInstanceUID,
meta_uid=BasicGrayscalePrintManagementMeta
)
if not status or status.Status != 0x0000:
print('Printing the Film Box failed, releasing association')
assoc.release()
sys.exit()
# The actual printing may occur after association release/abort
print('Print command sent successfully')
# Optional - Delete the Film Box
status = assoc.send_n_delete(
film_box.SOPClassUID,
film_box.SOPInstanceUID
)
# Release the association
assoc.release() Maybe update example? |
Thanks, I don't actually have anything to test the DIMSE-N services against, so I'll update the example using your code |
Even I tried with DryStar 5302 with the same script, the Image box creation failed. I added the attributes according to the Drystar conformance statement. But still my image box is not creating. It returns None. Updating the Image Box failed. Status: 290. How to fix it. I am using pynetdicom=2.0.2, pydicom= 2.4.3 and python = ">=3.9,<3.13"
|
https://pydicom.github.io/pynetdicom/stable/examples/print.html
I tried to follow this example, but encountered different obstacles.
First 1st step (checking status) originally had no successfull outcome. It would always get fail. But its easily fixable. Okay...
Secondly, 2nd step (getting film session) somehow gets empty dataset (film session) so when I try generate film box it crashes because it can't get ReferencedSOPClassUID and ReferencedSOPInstanceUID (and fails to get film box).
Am I doing something wrong?
Tried on real printer DryStar 5302 and on virtual printer (Print SCP) from CharruaSoft (their Print Server). Pynetdicom version 2.0.2 and pydicom is 2.3.0 with Windows 10 (Superior OS)
The text was updated successfully, but these errors were encountered: