Пример #1
0
        /// <summary>
        /// Query the Information Model using the given query message.
        /// </summary>
        /// <param name="queryMessage">Message used to query the Information Model.</param>
        /// <returns>DicomMessageCollection - containing the query responses. The final query response (without a dataset) is also included.</returns>
        public DicomMessageCollection QueryInformationModel(DicomMessage queryMessage)
        {
            DicomMessageCollection responseMessages = new DicomMessageCollection();

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

            DataSet queryDataset = queryMessage.DataSet;

            Dvtk.Dicom.InformationEntity.DataSetCollection queryResponses = _root.QueryInformationModel(queryDataset.DvtkDataDataSet);

            DvtkData.Dimse.DicomMessage dvtkDicomMessage = null;
            DvtkData.Dimse.CommandSet   dvtkCommand      = null;
            DicomMessage responseMessage = null;

            if (queryResponses != null)
            {
                foreach (DvtkData.Dimse.DataSet dvtkDataset in queryResponses)
                {
                    dvtkDicomMessage = new DvtkData.Dimse.DicomMessage();
                    dvtkCommand      = new DvtkData.Dimse.CommandSet(DvtkData.Dimse.DimseCommand.CFINDRSP);
                    dvtkCommand.AddAttribute(0x0000, 0x0002, DvtkData.Dimse.VR.UI, sopClassUid);
                    dvtkCommand.AddAttribute(0x0000, 0x0900, DvtkData.Dimse.VR.US, 0xFF00);

                    dvtkDicomMessage.Apply(dvtkCommand, dvtkDataset, queryMessage.EncodedPresentationContextID);
                    responseMessage = new DicomMessage(dvtkDicomMessage);
                    responseMessages.Add(responseMessage);
                }
            }

            dvtkDicomMessage = new DvtkData.Dimse.DicomMessage();
            dvtkCommand      = new DvtkData.Dimse.CommandSet(DvtkData.Dimse.DimseCommand.CFINDRSP);
            dvtkCommand.AddAttribute(0x0000, 0x0002, DvtkData.Dimse.VR.UI, sopClassUid);
            dvtkCommand.AddAttribute(0x0000, 0x0900, DvtkData.Dimse.VR.US, 0x0000);

            dvtkDicomMessage.Apply(dvtkCommand, queryMessage.EncodedPresentationContextID);
            responseMessage = new DicomMessage(dvtkDicomMessage);
            responseMessages.Add(responseMessage);

            return(responseMessages);
        }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        /// Adds a single attribute with the tag sequence, VR and values specified.
        /// </summary>
        /// <remarks>
        /// If an attribute already exists with this tag, it is removed first before it is again
        /// added.
        /// <br></br><br></br>
        /// If sequence items (each with a sequence item index) are specified in the tag sequence,
        /// empty sequence items will be added automatically to avoid gaps in the sequence items of sequence
        /// attributes.
        /// </remarks>
        /// <param name="tagSequence">The tag sequence of the attribute.</param>
        /// <param name="vR">The VR of the attribute.</param>
        /// <param name="values">The values, which will be copied from another attribute, for this attribute.</param>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="dvtkDataTag"/> is not valid for setting an attribute.<br></br>
        /// -or-<br></br>
        /// <paramref name="dvtkDataTag"/> is not valid for setting a CommandSet attribute.<br></br>
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="values"/> is a null reference.
        /// </exception>
        public override void Set(String tagSequence, VR vR, Values values)
        {
            TagSequence internalTagSequence = new TagSequence(tagSequence);

            //
            // Sanity checks.
            //

            if (!internalTagSequence.IsSingleAttributeMatching)
            {
                throw new ArgumentException(internalTagSequence.ToString() + " not valid for setting an attribute.");
            }

            // Check if the tag supplied is valid for a CommandSet.
            if (!internalTagSequence.IsValidForCommandSet)
            {
                throw new ArgumentException(internalTagSequence.ToString() + " not valid for setting a CommandSet attribute.", "dvtkDataTag");
            }

            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            //
            // Perform the actual operation in the base class.
            //

            Set(internalTagSequence, vR, values);
        }
Пример #4
0
        /// <summary>
        /// Adds a single attribute with the tag, VR and values specified.
        /// </summary>
        /// <remarks>
        /// If an attribute already exists with this tag, it is removed first before it is again
        /// added.
        /// </remarks>
        /// <param name="dvtkDataTag">The tag of the attribute.</param>
        /// <param name="vR">The VR of the attribute.</param>
        /// <param name="values">The values, which will be copied from another attribute, for this attribute.</param>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="dvtkDataTag"/> is not valid for setting a CommandSet attribute.<br></br>
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="values"/> is a null reference.
        /// </exception>
        public override void Set(DvtkData.Dimse.Tag dvtkDataTag, VR vR, Values values)
        {
            TagSequence internalTagSequence = new TagSequence();

            internalTagSequence.Add(new Tag(dvtkDataTag.GroupNumber, dvtkDataTag.ElementNumber));

            //
            // Sanity checks.
            //

            // Check if the tag supplied is valid for a CommandSet.
            if (!internalTagSequence.IsValidForCommandSet)
            {
                throw new ArgumentException(internalTagSequence.ToString() + " is not valid for setting a CommandSet attribute.", "dvtkDataTag");
            }

            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            //
            // Perform the actual operation in the base class.
            //

            Set(internalTagSequence, vR, values);
        }
Пример #5
0
        public override bool HandleCMoveRequest(DicomMessage retrieveMessage)
        {
            // try to get the SOP Class Uid so that we know which Information Model to use.
            DvtkHighLevelInterface.Dicom.Other.Values values = retrieveMessage.CommandSet["0x00000002"].Values;
            System.String sopClassUid = values[0];
            DvtkData.Dul.AbstractSyntax abstractSyntax = new DvtkData.Dul.AbstractSyntax(sopClassUid);

            // try to get the Move Destination AE.
            values = retrieveMessage.CommandSet["0x00000600"].Values;
            string vr = retrieveMessage.CommandSet["0x00000600"].VR.ToString();

            System.String moveDestinationAE = values[0];
            string        hexString         = moveDestinationAE;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (DicomThread.Options.LoadedDefinitionFileNames.Length < 10)
            {
                WriteWarning("Some of the definition files is not loaded properly.");
            }
            if (vr == "UN")
            {
                for (int i = 0; i <= hexString.Length - 2; i += 2)
                {
                    sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber))));
                }
            }
            else if (vr == "AE")
            {
                sb.Append(moveDestinationAE);
            }
            if (moveDestinationAE == null || moveDestinationAE == "")
            {
                DicomMessage responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CMOVERSP);
                responseMessage.Set("0x00000900", VR.US, 0xA801);
                responseMessage.Set("0x00000902", VR.LO, "Unknown Move Destination");
                this.Send(responseMessage);
                return(true);
            }
            MoveAEdetailsIndex = FindMoveAEDetails(sb.ToString());
            if (IsHaveMoveDestinations && MoveAEdetailsIndex == -1)
            {
                DicomMessage responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CMOVERSP);
                responseMessage.Set("0x00000900", VR.US, 0xA801);
                responseMessage.Set("0x00000902", VR.LO, "Move Destination not registered in SCP");
                this.Send(responseMessage);
                WriteWarning("Move destination is not registered in SCP");
                return(true);
            }
            DvtkData.Collections.StringCollection retrieveList = null;

            // check if we should use the Patient Root Information Model
            if ((abstractSyntax.UID == DvtkData.Dul.AbstractSyntax.Patient_Root_Query_Retrieve_Information_Model_MOVE.UID) &&
                (PatientRootInformationModel != null))
            {
                // check if the information model should be refreshed before retrieving
                if (RefreshInformationModelBeforeUse == true)
                {
                    PatientRootInformationModel.RefreshInformationModel();
                }

                // perform retrieve
                retrieveList = PatientRootInformationModel.RetrieveInformationModel(retrieveMessage);
            }
            // check if we should use the Study Root Information Model
            else if ((abstractSyntax.UID == DvtkData.Dul.AbstractSyntax.Study_Root_Query_Retrieve_Information_Model_MOVE.UID) &&
                     (StudyRootInformationModel != null))
            {
                // check if the information model should be refreshed before retrieving
                if (RefreshInformationModelBeforeUse == true)
                {
                    StudyRootInformationModel.RefreshInformationModel();
                }

                // perform retrieve
                retrieveList = StudyRootInformationModel.RetrieveInformationModel(retrieveMessage);
            }
            // check if we should use the Patient Study Only Information Model
            else if ((abstractSyntax.UID == DvtkData.Dul.AbstractSyntax.Patient_Study_Only_Query_Retrieve_Information_Model_MOVE.UID) &&
                     (PatientStudyOnlyInformationModel != null))
            {
                // check if the information model should be refreshed before retrieving
                if (RefreshInformationModelBeforeUse == true)
                {
                    PatientStudyOnlyInformationModel.RefreshInformationModel();
                }

                // perform retrieve
                retrieveList = PatientStudyOnlyInformationModel.RetrieveInformationModel(retrieveMessage);
            }

            // process the retrieve list
            return(ProcessRetrieveList(moveDestinationAE, retrieveList));
        }
Пример #6
0
        /// <summary>
        /// Compares this instance with another Values instance.
        /// </summary>
        /// <remarks>
        /// Two Values instances are considered equal when:<br></br>
        /// - Both contain the same number of values.<br></br>
        /// - The String representations of the individual values are the same.<br></br><br></br>
        /// 
        /// When spaces are non-significant according to part 5, 
        /// they are left out, when comparing, like specified below.<br></br><br></br>
        /// 
        /// When the attribute, a Values instance belongs to, has VR AE, CS, DS, IS, LO or SH,
        /// all leading and trailing spaces are removed before comparing.<br></br><br></br>
        /// 
        /// When the attribute, a Values instance belongs to, has VR LT, PN, ST, TM or UT,
        /// all trailing spaces are removed before comparing.<br></br><br></br>
        /// 
        /// When the attribute, a Values instance belongs to, has VR DA or DT,
        /// all trailing spaces are removed before comparing although
        /// nothing is mentioned in part 5 about non-significant spaces. This is
        /// because trailing spaces may be present in queries with range matching.<br></br><br></br>
        /// </remarks>
        /// <param name="values">The Values instance to compare with.</param>
        /// <returns>Boolean indicating if they are equal.</returns>
        public bool Equals(Values values)
        {
            bool equals = true;

            ValidAttribute validAttribute1 = Attribute as ValidAttribute;
            ValidAttribute validAttribute2 = values.Attribute as ValidAttribute;

            if ((validAttribute1 != null) &&
                (validAttribute2 != null) &&
                ((attribute.VR == VR.OB) || (attribute.VR == VR.OF) || (attribute.VR == VR.OW)) &&
                ((values.Attribute.VR == VR.OB) || (values.Attribute.VR == VR.OF) || (values.Attribute.VR == VR.OW)))
            {
                equals = Dvtk.DvtkDataHelper.ComparePixelAttributes(validAttribute1.DvtkDataAttribute, validAttribute2.DvtkDataAttribute);
            }
            else
            {
                if (Count != values.Count)
                {
                    equals = false;
                }
                else
                {
                    for (int index = 0; index < Count; index++)
                    {
                        if (this[index] != values[index])
                        {
                            equals = false;
                            break;
                        }
                    }
                }
            }

            return (equals);
        }
Пример #7
0
 /// <summary>
 /// Adds values to the end of this instance.
 /// </summary>
 /// <param name="values">Values to add.</param>
 /// 
 public void Add(Values values)
 {
     Insert(this.Count, values);
 }
Пример #8
0
        /// <summary>
        /// Inserts another Values instance in this instance at a specified position.
        /// </summary>
        /// <param name="zeroBasedIndex">The zero based index to insert.</param>
        /// <param name="values">The Values instance to insert.</param>
        public void Insert(int zeroBasedIndex, Values values)
        {
            if ((attribute.VR == VR.OB) || (attribute.VR == VR.OF) || (attribute.VR == VR.OW))
            {
                ValidAttribute thisAttribute = this.attribute as ValidAttribute;
                ValidAttribute attributeToCopyFrom = values.Attribute as ValidAttribute;

                if ((thisAttribute != null) && (attributeToCopyFrom != null))
                {
                    // It is safe to use the same other...String object because it is never
                    // changed through the HLI.
                    thisAttribute.DvtkDataAttribute.DicomValue = attributeToCopyFrom.DvtkDataAttribute.DicomValue;
                    thisAttribute.DvtkDataAttribute.Length = attributeToCopyFrom.DvtkDataAttribute.Length;
                }
            }
            else
            {
                String[] valuesAsStringArray = new String[values.Count];

                for (int index = 0; index < values.Count; index++)
                {
                    valuesAsStringArray[index] = values[index];
                }

                Insert(zeroBasedIndex, valuesAsStringArray);
            }
        }
Пример #9
0
        /// <summary>
        /// Adds a single attribute with the tag sequence, VR and values specified.
        /// </summary>
        /// <remarks>
        /// If an attribute already exists with this tag, it is removed first before it is again
        /// added.
        /// <br></br>
        /// If sequence items (each with a sequence item index) are specified in the tag sequence,
        /// empty sequence items will be added automatically to avoid gaps in the sequence items of sequence
        /// attributes.
        /// </remarks>
        /// <param name="tagSequence">The tag sequence of the attribute.</param>
        /// <param name="vR">The VR of the attribute.</param>
        /// <param name="values">The values, which will be copied from another attribute, for this attribute.</param>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="dvtkDataTag"/> is not valid for setting an attribute.<br></br>
        /// -or-<br></br>
        /// <paramref name="dvtkDataTag"/> is not valid for setting a FileMetaInformation attribute.<br></br>
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="values"/> is a null reference.
        /// </exception>
        public override void Set(String tagSequence, VR vR, Values values)
        {
            TagSequence internalTagSequence = new TagSequence(tagSequence);

            //
            // Sanity checks.
            //

            if (!internalTagSequence.IsSingleAttributeMatching)
            {
                throw new ArgumentException(internalTagSequence.ToString() + " not valid for setting an attribute.");
            }

            // Check if the tag supplied is valid for a FileMetaInformation.
            if (!internalTagSequence.IsValidForFileMetaInformation)
            {
                throw new ArgumentException(internalTagSequence.ToString() + " not valid for setting a FileMetaInformation attribute.", "dvtkDataTag");
            }

            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            //
            // Perform the actual operation.
            //

            Set(internalTagSequence, vR, values);

            if ((internalTagSequence.ToString() == "0x00020010") && (values.Count == 1))
            {
                this.dvtkDataFileHead.TransferSyntax = new DvtkData.Dul.TransferSyntax(values[0]);
            }
        }