LAUREL BRIDGE

LaurelBridge.DCF.Examples.MWLSCU Namespace

DICOM Connectivity Framework V3.4
The MWLSCU example demonstrates how to use DCF to implement a modality worklist service class user.
Classes

  ClassDescription
Public classProgram
Basic worklist service class user example which should be run with MWLSCP.
Public classProgramMWLQueryListener
This class wraps the worklist SCU and handles receiving worklist query responses. Various properties on the scu object allow setting timeouts for various conditions.
Examples

MWLSCU Sample Code
public class Program
{
    /// <summary>
    /// The main entry point for MWLSCU.
    /// </summary>
    [STAThread]
    public static void Main()
    {
        MWLQueryListener listener = new MWLQueryListener();
        listener.ExecuteQuery(BuildQuery());

        if (System.Diagnostics.Debugger.IsAttached)
        {
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey();
        }
    }

    private static QRIdentifier BuildQuery()
    {
        QRIdentifier query = new QRIdentifier();
        //Fields to query on.
        query.PatientsName = "*STEPHEN";

        //Fields to return.
        query.PatientId = "";
        query.PatientsSex = "";
        query.Modality = "";
        query.StudyDate = "";

        return query;
    }

    /// <summary>
    /// This class wraps the worklist SCU and handles receiving worklist query responses.
    /// Various properties on the scu object allow setting timeouts for various conditions.
    /// </summary>
    public class MWLQueryListener : IQueryListener
    {
        private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

        private readonly Dicom.Worklist.MWLSCU _scu;

        /// <summary>
        /// Constructor creates the MWLSCU, and configures timeouts.
        /// </summary>
        public MWLQueryListener()
        {
            AssociationInfo ainfo = new AssociationInfo();
            ainfo.CallingTitle = "SCU";
            ainfo.CalledTitle = "SCP";
            ainfo.CalledPresentationAddress = "localhost:104";

            // Add the requested presentation context
            RequestedPresentationContext ctx = new RequestedPresentationContext(
                1,
                Uids.ModalityWorklistInformationModelFIND,
                Uids.ELE, Uids.ILE);

            ainfo.AddRequestedPresentationContext(ctx);

            // Make the SCU here
            _scu = new Dicom.Worklist.MWLSCU(ainfo, new DicomSessionSettings() { IsDebugEnabled = true, DebugFlags = DF.User8 });

            _scu.MaxReturnedResults = 100;
            //scu_.QueryTimeoutSeconds = configuration_.QueryTimeoutSeconds;
            _scu.QueryTimeoutSeconds = -1; // We only use the progress timer, not the absolute timer
            _scu.SendDimseTimeoutSeconds = 30;
            _scu.ReceiveDimseTimeoutSeconds = 30;
            _scu.ProgressTimeoutSeconds = 30;
        }

        /// <summary>
        /// Execute a c-find request using the dataset in the QRIdentifier.
        /// </summary>
        /// <param name="query">the query dataset</param>
        public void ExecuteQuery(QRIdentifier query)
        {
            try
            {
                Logger.DebugFormat(DF.User8, "Query Data set is: {0}{1}", Environment.NewLine, query.DataSet);

                _scu.RequestAssociation();
                _scu.CFind(query.DataSet, this, true);
                _scu.ReleaseAssociation();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error executing query: {0}{1}{1}Please verify the Query SCP is up and running.", ex, Environment.NewLine);
            }
        }

        #region QueryListener Members
        /// <summary>
        /// This method is called at the completion of the query.
        /// </summary>
        /// <param name="status">The DIMSE status of the final response.</param>
        public void QueryComplete(int status)
        {
            Logger.InfoFormat("Received queryComplete event status = {0}", status);

            switch (status)
            {
                default:
                    {
                        Console.WriteLine("Operation status({0})", status);
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_SUCCESS:
                    {
                        Console.WriteLine("Operation finished with no errors.");
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_CANCELED:
                    {
                        Console.WriteLine("Operation was Canceled successfully");
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_WARNING:
                    {
                        Console.WriteLine("Warning: some or all subops failed for C-MOVE");
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_ERROR:
                    {
                        Console.WriteLine("Failure.");
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_INTERNAL_ERROR:
                    {
                        Console.WriteLine("Internal Error. Association may still be connected. Aborting");
                        if (_scu.Connected) { _scu.AbortAssociation(); }
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_TIMEOUT:
                    {
                        Console.WriteLine("Operation timed out");
                        if (_scu.Connected) { _scu.AbortAssociation(); }
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_SUCCESS_MAX_RETURNED_RESULTS_REACHED:
                    {
                        Console.WriteLine("Success, Max Returned Results Reached");
                        if (_scu.Connected) { _scu.AbortAssociation(); }
                        break;
                    }
                case QueryListenerStatus.QUERY_LISTENER_DIMSE_RECEIVE_TIMEOUT:
                    {
                        Console.WriteLine("Operation DIMSE receive timed out");
                        if (_scu.Connected) { _scu.AbortAssociation(); }
                        break;
                    }
            }
        }

        /// <summary>
        /// This method is called for all incoming DIMSE response messages.
        /// </summary>
        /// <param name="rsp">The DIMSE response messages.</param>
        public void QueryEvent(DimseMessage rsp)
        {
            // This method is called for both pending and final responses, so filter out 
            // the final response (it doesn't have a data dataset, only a command dataset).
            if (rsp.DataSetType != 0x101)
                Console.WriteLine("Received response:{0}{1}", Environment.NewLine, rsp.Data);
        }
        #endregion
    }
}