The MPPSSCU example demonstrates how to use DCF to implement a modality performed procedure step service class user.
Classes
Class | Description | |
---|---|---|
Program |
Basic modality performed procedure step service class user example which should be run with MPPSSCP.
| |
ProgramModalityPerformedProcedureStepSCU |
A class that implements the MPPS service class user create and update messages.
|
Remarks
Supported OS Platforms:
- Windows - .Net Framework 4.7.2 64-bit and 32-bit
- Windows - .Net Core 2.1 64-bit and 32-bit
- Linux - .Net Core 2.1 64-bit
Examples
MPPSSCU Sample Code
public class Program { /// <summary> /// The main entry point for MPPSSCU. /// </summary> [STAThread] public static void Main() { ModalityPerformedProcedureStepSCU mppsSCU = new ModalityPerformedProcedureStepSCU(10104); mppsSCU.SendNCreate(MppsForNCreate()); mppsSCU.SendNSet(MppsForNSet()); if (System.Diagnostics.Debugger.IsAttached) { Console.Write("Press any key to continue . . . "); Console.ReadKey(); } } /// <summary> /// A class that implements the MPPS service class user create and update messages. /// </summary> public class ModalityPerformedProcedureStepSCU { private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); private readonly DCF.Dicom.ProcedureStep.MPPSSCU _scu; private int _timeoutSecs = 10; /// <summary> /// Construct a modality performed procedure step Service Class User, using the /// given port on localhost for communication with the MPPSSCP. /// </summary> /// <param name="port">The port on localhost to use for the association.</param> public ModalityPerformedProcedureStepSCU(int port) { AssociationInfo ainfo = new AssociationInfo(); RequestedPresentationContext mppsCtx = new RequestedPresentationContext(1, Uids.ModalityPerformedProcedureStepSOPClass, Uids.TransferSyntax.ImplicitVRLittleEndian, Uids.TransferSyntax.ExplicitVRLittleEndian); ainfo.CalledTitle = "SCP"; ainfo.CallingTitle = "SCU"; ainfo.CalledPresentationAddress = String.Format("{0}:{1}", "localhost", port); ainfo.AddRequestedPresentationContext(mppsCtx); _scu = new DCF.Dicom.ProcedureStep.MPPSSCU(ainfo); } /// <summary> /// Send the N-Create dimse message for the given modality performed procedure step. /// </summary> /// <param name="mpps">The MPPS IOD to send</param> public void SendNCreate(ModalityPerformedProcedureStep mpps) { try { _scu.RequestAssociation(); Logger.InfoFormat("Outgoing NCreate dataset:{0}{1}", Environment.NewLine, mpps); DimseMessage rsp = _scu.NCreate(mpps, _timeoutSecs); Logger.InfoFormat("Incoming NCreate rsp:{0}{1}", Environment.NewLine, rsp); } catch (Exception e) { Logger.Error(e, "Error sending NCreate message to SCP"); Environment.ExitCode = 1; } finally { if (_scu != null && _scu.Connected) { _scu.ReleaseAssociation(); } } } /// <summary> /// Send the N-Set dimse message for the given modality performed procedure step. /// </summary> /// <param name="mpps">The MPPS IOD to send</param> public void SendNSet(ModalityPerformedProcedureStep mpps) { try { _scu.RequestAssociation(); Logger.InfoFormat("Outgoing NSet dataset:{0}{1}", Environment.NewLine, mpps); DimseMessage rsp = _scu.NSet(mpps, _timeoutSecs); Logger.InfoFormat("Incoming NSet rsp:{0}{1}", Environment.NewLine, rsp); } catch (Exception e) { Logger.Error(e, "Error sending NSet message to SCP"); Environment.ExitCode = 1; } finally { if (_scu != null && _scu.Connected) { _scu.ReleaseAssociation(); } } } } #region Helpers /// <summary> /// A method to create a dataset for the SCU test. Typically, the MPPS information would be extracted from /// a modality work list (MWL) query by the modality performing the MPPS create. /// </summary> /// <returns>An MPPS dataset suitable for N-Create.</returns> private static ModalityPerformedProcedureStep MppsForNCreate() { DicomDataSet ds = new DicomDataSet(); // These will be removed from the N-Create's dataset; they will be set in the affected sop class/instance // uid's in the N-Create DIMSE message. ds.Insert(Tags.SOPClassUID, "1.2.840.10008.3.1.2.3.3"); ds.Insert(Tags.SOPInstanceUID, "1.2.3.4.1.100"); ds.Insert(Tags.AccessionNumber, "111"); ds.Insert(Tags.ReferringPhysicianName, "Dr. Nick"); DicomDataSet refStudyDs = new DicomDataSet(); refStudyDs.Insert(Tags.ReferencedSOPClassUID, "1.2.3.4.5"); refStudyDs.Insert(Tags.ReferencedSOPInstanceUID, "1.2.3.4.100"); ds.Insert(new DicomSQElement(Tags.ReferencedStudySequence, refStudyDs)); DicomDataSet refSeriesDs = new DicomDataSet(); refSeriesDs.Insert(Tags.ReferencedSOPClassUID, "1.2.3.4.6"); refSeriesDs.Insert(Tags.ReferencedSOPInstanceUID, "1.2.3.4.101"); ds.Insert(new DicomSQElement(Tags.ReferencedPatientSequence, refSeriesDs)); ds.Insert(Tags.PatientName, "White^Charles"); ds.Insert(Tags.PatientID, "583020"); ds.Insert(Tags.PatientBirthDate, "19980704"); ds.Insert(Tags.PatientSex, "M"); ds.Insert(Tags.OtherPatientIDsRetired, "556644"); ds.Insert(Tags.PatientSize, "Large"); ds.Insert(Tags.PatientWeight, "255"); ds.Insert(Tags.AdditionalPatientHistory, "Has a crayon stuck up his nose"); ds.Insert(Tags.PregnancyStatus, "0"); ds.Insert(Tags.LastMenstrualDate, ""); ds.Insert(Tags.PatientComments, "Likes Duff Beer"); ds.Insert(Tags.StudyInstanceUID, "44445555"); ds.Insert(Tags.StudyDescription, "X-Ray to see if brain is present"); ds.Insert(Tags.StudyID, "33442211"); ds.Insert(Tags.RequestingPhysician, "Dr. Somebody"); ds.Insert(Tags.RequestedProcedureDescription, "Skull XRAY"); DicomDataSet reqProcCodeSeqDs = new DicomDataSet(); reqProcCodeSeqDs.Insert(Tags.CodeValue, ""); reqProcCodeSeqDs.Insert(Tags.CodingSchemeDesignator, ""); reqProcCodeSeqDs.Insert(Tags.CodeMeaning, ""); ds.Insert(new DicomSQElement(Tags.RequestedProcedureCodeSequence, reqProcCodeSeqDs)); ds.Insert(Tags.AdmissionID, "665544"); ds.Insert(Tags.CurrentPatientLocation, "On Couch watching TV"); ds.Insert(Tags.PatientState, "Asleep and Drooling"); ds.Insert(Tags.Modality, "MR"); DicomDataSet schdProcStepSeqDs = new DicomDataSet(); schdProcStepSeqDs.Insert(Tags.ScheduledStationAETitle, "0DROC_NUMBER_1"); schdProcStepSeqDs.Insert(Tags.ScheduledProcedureStepStartDate, "20020625"); schdProcStepSeqDs.Insert(Tags.ScheduledProcedureStepStartTime, "100000"); schdProcStepSeqDs.Insert(Tags.ScheduledPerformingPhysicianName, "Dr. Somebody Else"); schdProcStepSeqDs.Insert(Tags.ScheduledProcedureStepDescription, ""); DicomDataSet schdActionItemCodeSeqDs = new DicomDataSet(); schdActionItemCodeSeqDs.Insert(Tags.CodeValue, "X1_A1"); schdActionItemCodeSeqDs.Insert(Tags.CodingSchemeDesignator, ""); schdActionItemCodeSeqDs.Insert(Tags.CodingSchemeVersion, "12345"); schdActionItemCodeSeqDs.Insert(Tags.CodeMeaning, ""); schdProcStepSeqDs.Insert(new DicomSQElement(Tags.ScheduledProtocolCodeSequence, schdActionItemCodeSeqDs)); schdProcStepSeqDs.Insert(Tags.ScheduledProcedureStepID, ""); schdProcStepSeqDs.Insert(Tags.ScheduledStationName, "DROC_STATION_1"); schdProcStepSeqDs.Insert(Tags.ScheduledProcedureStepLocation, "Radiology Suite A"); schdProcStepSeqDs.Insert(Tags.CommentsOnTheScheduledProcedureStep, ""); ds.Insert(new DicomSQElement(Tags.ScheduledProcedureStepSequence, schdProcStepSeqDs)); ds.Insert(Tags.RequestedProcedureID, "13579"); ds.Insert(Tags.ConfidentialityConstraintOnPatientDataDescription, "NONE"); ds.Insert(Tags.PerformedProcedureStepStatus, "IN PROGRESS"); DicomDataSet perfProtCodeSeqDs = new DicomDataSet(); perfProtCodeSeqDs.Insert(Tags.CodeValue, "X1_A1"); perfProtCodeSeqDs.Insert(Tags.CodingSchemeDesignator, "DSS_MESA"); perfProtCodeSeqDs.Insert(Tags.CodingSchemeVersion, "SP Action Item X1_A1"); perfProtCodeSeqDs.Insert(Tags.CodeMeaning, "SP Action Item X1_A1"); ds.Insert(new DicomSQElement(Tags.PerformedProtocolCodeSequence, perfProtCodeSeqDs)); ModalityPerformedProcedureStep mpps = new ModalityPerformedProcedureStep(ds); return mpps; } /// <summary> /// A method to create a dataset for the SCU test. Typically, the MPPS information would be extracted from /// a modality work list (MWL) query by the modality performing the MPPS update. /// </summary> /// <returns>An MPPS dataset suitable for N-Set.</returns> private static ModalityPerformedProcedureStep MppsForNSet() { DicomDataSet ds = new DicomDataSet(); // These will be removed from the N-Set's dataset; they will be set in the affected sop class/instance // uid's in the N-NSet DIMSE message. ds.Insert(Tags.SOPClassUID, "1.2.840.10008.3.1.2.3.3"); ds.Insert(Tags.SOPInstanceUID, "1.2.3.4.1.100"); ds.Insert(Tags.PerformedProcedureStepStatus, "COMPLETED"); DicomDataSet perfProtCodeSeqDs = new DicomDataSet(); perfProtCodeSeqDs.Insert(Tags.CodeValue, "X1_A1"); perfProtCodeSeqDs.Insert(Tags.CodingSchemeDesignator, "DSS_MESA"); perfProtCodeSeqDs.Insert(Tags.CodingSchemeVersion, "SP Action Item X1_A1"); perfProtCodeSeqDs.Insert(Tags.CodeMeaning, "SP Action Item X1_A1"); ds.Insert(new DicomSQElement(Tags.PerformedProtocolCodeSequence, perfProtCodeSeqDs)); ModalityPerformedProcedureStep mpps = new ModalityPerformedProcedureStep(ds); return mpps; } #endregion }