LAUREL BRIDGE

LaurelBridge.DCFExamples.MPPSSCU Namespace

DICOM Connectivity Framework V3.4
The MPPSSCU example demonstrates how to use DCF to implement a modality performed procedure step service class user.
Classes

  ClassDescription
Public classProgram
Basic modality performed procedure step service class user example which should be run with MPPSSCP.
Public classProgramModalityPerformedProcedureStepSCU
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
}