Пример #1
0
        /// <summary>
        /// Triggers sending of an association.
        /// </summary>
        /// <param name="dicomMessage">The DICOM message to send.</param>
        /// <param name="presentationContexts">The presentation contexts to use for setting up the DICOM association.</param>
        public void TriggerSendAssociation(DicomMessage dicomMessage, params PresentationContext[] presentationContexts)
        {
            DicomMessageCollection dicomMessageCollection = new DicomMessageCollection();
            dicomMessageCollection.Add(dicomMessage);

            SendAssociationTrigger sendAssociationTrigger = new SendAssociationTrigger(dicomMessageCollection, presentationContexts);

            Trigger(sendAssociationTrigger);
        }
Пример #2
0
        /// <summary>
        /// Trigger a send association and wait until it has been completed.
        /// </summary>
        /// <param name="dicomMessage">The DICOM message to send.</param>
        /// <param name="presentationContexts">The presentation contexts to propose.</param>
        /// <returns>
        /// True indicates the other side has accepted the association, false indicates the other side
        /// has rejected the association.
        /// </returns>
        public bool TriggerSendAssociationAndWait(DicomMessage dicomMessage, params PresentationContext[] presentationContexts)
        {
            DicomMessageCollection dicomMessageCollection = new DicomMessageCollection();
            dicomMessageCollection.Add(dicomMessage);

            SendAssociationTrigger sendAssociationTrigger = new SendAssociationTrigger(dicomMessageCollection, presentationContexts);

            Trigger(sendAssociationTrigger);

            WaitForLastTriggerCallProcessed();

            return(sendAssociationTrigger.returnValue);
        }
Пример #3
0
        /// <summary>
        /// Return the DicomMessages from this collection that have the specified DimseCommand.
        /// </summary>
        /// <param name="dimseCommand">the DimseCommand.</param>
        /// <returns>The DicomMessages with the specified DimseCommand.</returns>
        private DicomMessageCollection DicomMessagesForDimseCommand(DvtkData.Dimse.DimseCommand dimseCommand)
        {
            DicomMessageCollection dicomMessages = new DicomMessageCollection();

            foreach (DicomMessage dicomMessage in this)
            {
                if (dicomMessage.CommandSet.DimseCommand == dimseCommand)
                {
                    dicomMessages.Add(dicomMessage);
                }
            }

            return(dicomMessages);
        }
Пример #4
0
        /// <summary>
        /// Return the DicomMessages from this collection that have the specified DimseCommand.
        /// </summary>
        /// <param name="dimseCommand">the DimseCommand.</param>
        /// <returns>The DicomMessages with the specified DimseCommand.</returns>
        private DicomMessageCollection DicomMessagesForDimseCommand(DvtkData.Dimse.DimseCommand dimseCommand)
        {
            DicomMessageCollection dicomMessages = new DicomMessageCollection();

            foreach(DicomMessage dicomMessage in this)
            {
                if (dicomMessage.CommandSet.DimseCommand == dimseCommand)
                {
                    dicomMessages.Add(dicomMessage);
                }
            }

            return(dicomMessages);
        }
Пример #5
0
 /// <summary>
 /// Sends a Dicom Messages while taking care of setting up and releasing an
 /// association for it.
 /// </summary>
 /// <remarks>
 /// 1. An A-ASSOCIATE-RQ is sent.<br></br>
 /// 2. An A-ASSOCIATE-AC or A-ASSOCIATE-RJ is received.<br></br>
 /// Only when an A-ASSOCIATE-AC is received, steps 3, 4 and 5 are executed.<br></br>
 /// 3. For each Dicom Message to send, it is sent and responses are received until the status is not pending anymore.<br></br>
 /// 4. An A-RELEASE-RQ is sent.<br></br>
 /// 5. An A-RELEASE-RP is received.<br></br>
 /// </remarks>
 /// <param name="dicomMessages">The Dicom Messages to send.</param>
 /// <param name="presentationContexts">The presentation contexts to propose in the A-ASSOCIATE-RQ.</param>
 /// <returns>
 /// True indicates the other side has accepted the association, false indicates the other side
 /// has rejected the association.
 /// </returns>
 /// <exception cref="System.Exception">
 ///	Sending or receiving of one of the Dul or Dicom messages fails or the flow of messages differs
 /// from the flow described.
 /// </exception> 
 protected bool SendAssociation(DicomMessageCollection dicomMessages, params PresentationContext[] presentationContexts)
 {
     return(this.dicomThread.SendAssociation(dicomMessages, presentationContexts));
 }
        public void DataSetCollectionEvaluate_2_2()
        {
            //
            // SetUp the test data for this test case.
            //

            DicomMessageCollection dicomMessageCollection1 = new DicomMessageCollection();
            DicomMessageCollection dicomMessageCollection2 = new DicomMessageCollection();

            DicomMessage dicomMessage1 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage1.DataSet.Set("0x00200020", VR.UI, "1.1.1.1");
            dicomMessageCollection1.Add(dicomMessage1);

            DicomMessage dicomMessage2 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage2.DataSet.Set("0x00300030", VR.UI, "1.1.1.1");
            dicomMessage2.DataSet.Set("0x00400040", VR.LT, "dicomMessage2");
            dicomMessageCollection2.Add(dicomMessage2);

            DicomMessage dicomMessage3 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage3.DataSet.Set("0x00300030", VR.UI, "2.2.2.2");
            dicomMessage3.DataSet.Set("0x00400040", VR.LT, "dicomMessage3");
            dicomMessageCollection2.Add(dicomMessage3);

            DicomMessage dicomMessage4 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage4.DataSet.Set("0x00300030", VR.UI, "3.3.3.3");
            dicomMessage4.DataSet.Set("0x00400040", VR.LT, "dicomMessage4");
            dicomMessageCollection2.Add(dicomMessage4);

            //
            // Perform the actual test.
            //

            GenericCollection<GenericPair<DataSet, DataSet>> collection = BooleanExpressionTwoDataSets.MapsAttributes("0x00200020", "0x00300030").Evaluate(dicomMessageCollection1.DataSets, dicomMessageCollection2.DataSets);

            Assert.That(collection[0].Element2["0x00400040"].Values[0], Is.EqualTo("dicomMessage2"));
        }
        public void DataSetCollectionEvaluate_1_1()
        {
            //
            // SetUp the test data for this test case.
            //

            DicomMessageCollection dicomMessageCollection = new DicomMessageCollection();

            DicomMessage dicomMessage1 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage1.DataSet.Set("0x00200020", VR.LT, "Long text value");
            dicomMessageCollection.Add(dicomMessage1);

            DicomMessage dicomMessage2 = new DicomMessage(DimseCommand.CSTORERQ);
            dicomMessage2.DataSet.Set("0x00300030", VR.LT, "Long text value");
            dicomMessageCollection.Add(dicomMessage2);

            //
            // Perform the actual test.
            //

            DataSetCollection dataSetCollection = BooleanExpressionDataSet.ContainsAttribute("0x00200020").Evaluate(dicomMessageCollection.DataSets);

            Assert.That(dataSetCollection.Count, Is.EqualTo(1));
        }
Пример #8
0
        /// <summary>
        /// Sends a Dicom Messages while taking care of setting up and releasing an
        /// association for it.
        /// </summary>
        /// <remarks>
        /// 1. An A-ASSOCIATE-RQ is sent.<br></br>
        /// 2. An A-ASSOCIATE-AC or A-ASSOCIATE-RJ is received.<br></br>
        /// Only when an A-ASSOCIATE-AC is received, steps 3, 4 and 5 are executed.<br></br>
        /// 3. For each Dicom Message to send, it is sent and responses are received until the status is not pending anymore.<br></br>
        /// 4. An A-RELEASE-RQ is sent.<br></br>
        /// 5. An A-RELEASE-RP is received.<br></br>
        /// </remarks>
        /// <param name="dicomMessages">The Dicom Messages to send.</param>
        /// <param name="presentationContexts">The presentation contexts to propose in the A-ASSOCIATE-RQ.</param>
        /// <returns>
        /// True indicates the other side has accepted the association, false indicates the other side
        /// has rejected the association.
        /// </returns>
        /// <exception cref="System.Exception">
        ///	Sending or receiving of one of the Dul or Dicom messages fails or the flow of messages differs
        /// from the flow described.
        /// </exception> 
        protected internal bool SendAssociation(DicomMessageCollection dicomMessages, params PresentationContext[] presentationContexts)
        {
            bool isAssociationAccepted = true;

            // Send the associate request.
            SendAssociateRq(presentationContexts);

            // Receive the associate repsonse (may be an accept or reject).
            DulMessage associateRp = ReceiveAssociateRp();
            try
            {
                // If an associate accept was received, send the collection of DicomMessages, receive a response and
                // release the association.
                if (associateRp is AssociateAc)
                {
                    // send each message
                    foreach (DicomMessage dicomMessage in dicomMessages)
                    {
                        Send(dicomMessage);

                        // handle all responses
                        bool pendingResponses = true;
                        while (pendingResponses == true)
                        {
                            DicomMessage dicomResponse = ReceiveDicomMessage();
                            Values values = dicomResponse.CommandSet["0x00000900"].Values;
                            System.String statusString = values[0];
                            uint status = uint.Parse(statusString);
                            if ((status != 0xFF00) && (status != 0xFF01))
                            {
                                pendingResponses = false;
                            }
                        }
                    }

                    SendReleaseRq();

                    ReceiveReleaseRp();
                }
                else
                {
                    isAssociationAccepted = false;
                }
            }
            catch (Exception e)
            {
                SendReleaseRq();
                ReceiveReleaseRp();
                throw e;
            }
            return (isAssociationAccepted);
        }
Пример #9
0
        /// <summary>
        /// Sends a single Dicom Message while taking care of setting up and releasing an
        /// association for it.
        /// </summary>
        /// <remarks>
        /// 1. An A-ASSOCIATE-RQ is sent.<br></br>
        /// 2. An A-ASSOCIATE-AC or A-ASSOCIATE-RJ is received.<br></br>
        /// Only when an A-ASSOCIATE-AC is received, steps 3, 4 and 5 are executed.<br></br>
        /// 3. The Dicom Message is send and responses are received until the status is not pending anymore.<br></br>
        /// 4. An A-RELEASE-RQ is sent.<br></br>
        /// 5. An A-RELEASE-RP is received.<br></br>
        /// </remarks>
        /// <param name="dicomMessage">The Dicom Message to send.</param>
        /// <param name="presentationContexts">The presentation contexts to propose in the A-ASSOCIATE-RQ.</param>
        /// <returns>
        /// True indicates the other side has accepted the association, false indicates the other side
        /// has rejected the association.
        /// </returns>
        /// <exception cref="System.Exception">
        ///	Sending or receiving of one of the Dul or Dicom messages fails or the flow of messages differs
        /// from the flow described.
        /// </exception> 
        protected internal bool SendAssociation(DicomMessage dicomMessage, params PresentationContext[] presentationContexts)
        {
            DicomMessageCollection dicomMessages = new DicomMessageCollection();

            dicomMessages.Add(dicomMessage);

            return (SendAssociation(dicomMessages, presentationContexts));
        }
Пример #10
0
 public SendAssociationTrigger(DicomMessageCollection dicomMessageCollection, PresentationContext[] presentationContexts)
 {
     this.dicomMessageCollection = dicomMessageCollection;
     this.presentationContexts = presentationContexts;
     this.returnValue = true;
 }
Пример #11
0
        private void SendDICOMDataInMultipleAssociation(string[] mediaFiles)
        {
            int index = 0;
            // Set the dicom messages to send
            DicomMessageCollection dicomMessageCollection = new DicomMessageCollection();
            PresentationContextCollection pcCollection = new PresentationContextCollection();

            //The Current Directory is being set to the Results Directory because
            // when DICOMDIRs(or DICOM Files)Media are exported, the Environment.CurrentDirectory
            //is set to the Directory in which the DCM objects are present and the export will fail
            // if the DICOMDIR is present on a Physical Media.
            Environment.CurrentDirectory = this.storageOptions.ResultsDirectory;

            foreach (string dcmFilename in mediaFiles)
            {
                HliScu storageScuSubThread = new HliScu();

                storageScuSubThread.Initialize(this.overviewThread);
                storageScuSubThread.Options.CopyFrom(this.storageOptions);

                storageScuSubThread.Options.Identifier = string.Format("StorageOperation_{0}",index);

                String resultsFileBaseName = string.Format("StorageOperation_{0}_", index) + System.DateTime.Now.ToString("yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);
                storageScuSubThread.Options.ResultsFileNameOnlyWithoutExtension = resultsFileBaseName;

                storageScuSubThread.Options.LogThreadStartingAndStoppingInParent = false;
                storageScuSubThread.Options.LogWaitingForCompletionChildThreads = false;
                storageScuSubThread.Options.AutoValidate = false;

                string msg = string.Format("Reading and exporting the DICOM object - {0}", dcmFilename);
                storageScuSubThread.WriteInformation(msg);

                try
                {
                    // Read the DCM File
                    DicomFile dcmFile = new DicomFile();
                    dcmFile.Read(dcmFilename, storageScuSubThread);

                    FileMetaInformation fMI = dcmFile.FileMetaInformation;

                    // Get the transfer syntax and SOP class UID
                    System.String transferSyntax = "1.2.840.10008.1.2.1";
                    if ((fMI != null) && fMI.Exists("0x00020010"))
                    {
                        // Get the Transfer syntax
                        HLI.Attribute tranferSyntaxAttr = fMI["0x00020010"];
                        transferSyntax = tranferSyntaxAttr.Values[0];
                    }

                    Values values = fMI["0x00020002"].Values;
                    System.String sopClassUid = values[0];

                    //Check for DICOMDIR
                    if (sopClassUid == "1.2.840.10008.1.3.10")
                    {
                        // Read the DICOMDIR dataset
                        dcmFile.DataSet.DvtkDataDataSet = Dvtk.DvtkDataHelper.ReadDataSetFromFile(dcmFilename);
                        ArrayList refFiles = ImportRefFilesFromDicomdir(dcmFilename, dcmFile.DataSet);

                        foreach (string refFilename in refFiles)
                        {
                            // Read the Reference File
                            DicomFile refFile = new DicomFile();
                            refFile.Read(refFilename, storageScuSubThread);

                            FileMetaInformation refFMI = refFile.FileMetaInformation;

                            // Get the transfer syntax and SOP class UID
                            System.String refTransferSyntax = "1.2.840.10008.1.2.1";
                            if ((refFMI != null) && refFMI.Exists("0x00020010"))
                            {
                                // Get the Transfer syntax
                                HLI.Attribute refTranferSyntaxAttr = refFMI["0x00020010"];
                                refTransferSyntax = refTranferSyntaxAttr.Values[0];
                            }

                            Values sopValues = refFile.DataSet["0x00080016"].Values;
                            System.String refSopClassUid = sopValues[0];

                            PresentationContext refPresentationContext = new PresentationContext(refSopClassUid, // Abstract Syntax Name
                                                                                        refTransferSyntax); // Transfer Syntax Name(s)
                            pcCollection.Add(refPresentationContext);

                            DicomMessage refStorageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ);
                            refStorageMessage.DataSet.CloneFrom(refFile.DataSet);
                            dicomMessageCollection.Add(refStorageMessage);

                            // set the presentation contexts for the association
                            PresentationContext[] presentationContexts = SetPresentationContexts(pcCollection);

                            storageScuSubThread.Start();

                            storageScuSubThread.TriggerSendAssociationAndWait(dicomMessageCollection, presentationContexts);
                        }
                    }
                    else
                    {
                        PresentationContext presentationContext = new PresentationContext(sopClassUid, // Abstract Syntax Name
                                                                                        transferSyntax); // Transfer Syntax Name(s)
                        PresentationContext[] presentationContexts = new PresentationContext[1];
                        presentationContexts[0] = presentationContext;

                        DicomMessage storageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ);
                        storageMessage.DataSet.CloneFrom(dcmFile.DataSet);

                        storageScuSubThread.Start();

                        storageScuSubThread.TriggerSendAssociationAndWait(storageMessage, presentationContexts);
                    }

                    if (storageScuSubThread.HasExceptionOccured)
                    {
                        storageScuSubThread.WriteError(string.Format("Store operation of {0} failed", dcmFilename));
                    }
                }
                catch (Exception e)
                {
                    storageScuSubThread.WriteError(e.Message + "\nSkipping the DCM File.");
                }

                index++;

                storageScuSubThread.Stop();
            }

            DicomMessageCollection cStoreResponses = threadManager.Messages.DicomProtocolMessages.DicomMessages.CStoreResponses;

            foreach (DicomMessage cStoreRsp in cStoreResponses)
            {
                Int32 statusVal = Int32.Parse(cStoreRsp.CommandSet.GetValues("0x00000900")[0]);
                String sopInstUid = cStoreRsp.CommandSet.GetValues("0x00001000")[0];
                if (statusVal == 0)
                {
                    string infoMsg = string.Format("Image with SOP Instance UID{0} stored successfully.", sopInstUid);
                    overviewThread.WriteInformation(infoMsg);
                }
                else
                {
                    string warnMsg = string.Format("Non-zero status returned. Image with SOP Instance UID{0} storage failed.", sopInstUid);
                    overviewThread.WriteWarning(warnMsg);
                }
            }

            HandleCStoreResponses(storageCommitItems, cStoreResponses);

            threadManager.Messages.DicomProtocolMessages.DicomMessages.CStoreResponses.Clear();
        }
Пример #12
0
 private void HandleCStoreResponses(ReferencedSopItemCollection storageCommitItems, DicomMessageCollection cStoreResponses)
 {
     foreach (DicomMessage cStoreRsp in cStoreResponses)
     {
         AddSopData(storageCommitItems, cStoreRsp);
     }
 }
Пример #13
0
        /// <summary>
        /// Trigger the Client.
        /// </summary>
        /// <param name="actorName">Destination Actor Name.</param>
        /// <param name="trigger">Trigger message.</param>
        /// <param name="awaitCompletion">Boolean indicating whether this a synchronous call or not.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool TriggerClient(ActorName actorName, BaseTrigger trigger, bool awaitCompletion)
        {
            DicomTrigger dicomTrigger = (DicomTrigger) trigger;

            _scu.SignalCompletion = awaitCompletion;

            // determine how the handle the trigger - in a single association or not
            if (dicomTrigger.HandleInSingleAssociation == true)
            {
                // set the dicom messages to send
                DicomMessageCollection dicomMessageCollection = new DicomMessageCollection();
                foreach (DicomTriggerItem dicomTriggerItem in dicomTrigger.TriggerItems)
                {
                    dicomMessageCollection.Add(dicomTriggerItem.Message);
                }

                // set the presentation contexts for the association
                PresentationContext[] presentationContexts = SetPresentationContexts(dicomTrigger);

                // send in single association
                _scu.TriggerSendAssociation(dicomMessageCollection, presentationContexts);

                // Check if this is a synchronous call or not
                // - timeout of 0 means "no timeout".
                if (awaitCompletion == true)
                {
                    _semaphore.Wait(0);
                }
            }
            else
            {
                // send the triggers in separate associations
                foreach (DicomTriggerItem dicomTriggerItem in dicomTrigger.TriggerItems)
                {
                    // check if the sop class uid and transfer syntax are being explicitly defined
                    if ((dicomTriggerItem.SopClassUid != System.String.Empty) &&
                        (dicomTriggerItem.TransferSyntaxes.Length != 0))
                    {
                        // use the given presentation context
                        PresentationContext[] presentationContexts = new PresentationContext[1];
                        presentationContexts[0] = new PresentationContext(dicomTriggerItem.SopClassUid,
                            MergeTransferSyntaxes(dicomTriggerItem.TransferSyntaxes));
                        _scu.TriggerSendAssociation(dicomTriggerItem.Message, presentationContexts);
                    }
                    else
                    {
                        // use the initial presentation context
                        _scu.TriggerSendAssociation(dicomTriggerItem.Message, _presentationContexts);
                    }

                    // Check if this is a synchronous call or not
                    // - timeout of 0 means "no timeout".
                    if (awaitCompletion == true)
                    {
                        _semaphore.Wait(0);
                    }
                }
            }

            // return a boolean indicating if the trigger was processed successfully or not
            return _scu.ProcessTriggerResult;
        }
Пример #14
0
        /// <summary>
        /// Overridden C-FIND-RQ message handler that makes use of the appropriate Information Model to handle the query.
        /// </summary>
        /// <param name="queryMessage">C-FIND-RQ Identifier (Dataset) containing query attributes.</param>
        /// <returns>Boolean - true if dicomMessage handled here.</returns>
        public override bool HandleCFindRequest(DicomMessage queryMessage)
        {
            // Query response messages
            DicomMessageCollection responseMessages = new DicomMessageCollection();

            DvtkHighLevelInterface.Dicom.Other.Values values = queryMessage.CommandSet["0x00000002"].Values;
            System.String sopClassUid = values[0];

            DicomMessage responseMessage = null;

            foreach (DataSet randomDataset in randomizedDatasets)
            {
                responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CFINDRSP);

                responseMessage.CommandSet.Set("0x00000002", DvtkData.Dimse.VR.UI, sopClassUid);
                responseMessage.CommandSet.Set("0x00000900", DvtkData.Dimse.VR.US, 0xFF00);
                responseMessage.DataSet.CloneFrom(randomDataset);

                responseMessages.Add(responseMessage);
            }

            responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CFINDRSP);

            responseMessage.CommandSet.Set("0x00000002", DvtkData.Dimse.VR.UI, sopClassUid);
            responseMessage.CommandSet.Set("0x00000900", DvtkData.Dimse.VR.US, 0x0000);

            responseMessages.Add(responseMessage);

            // handle responses
            foreach (DicomMessage rspMessage in responseMessages)
            {
                try
                {
                    int waitedTime = 0;

                    // Check for cancel message from SCU
                    if (WaitForPendingDataInNetworkInputBuffer(100, ref waitedTime))
                    {
                        DicomMessage cancelRq = ReceiveDicomMessage();

                        if (cancelRq.CommandSet.DimseCommand == DvtkData.Dimse.DimseCommand.CCANCELRQ)
                        {
                            // set up the C-FIND-RSP with cancel status
                            DicomMessage respMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CFINDRSP);
                            respMessage.Set("0x00000900", DvtkData.Dimse.VR.US, 0xFE00);

                            // send the response
                            this.Send(respMessage);
                            break;
                        }
                    }

                    this.Send(rspMessage);
                }
                catch(Exception)
                {
                    string theErrorText = "DICOM Connection Error: RIS Emulator is failed to send the C-FIND-RSP.";
                    WriteError(theErrorText);
                }
            }

            // message handled
            return true;
        }