/// <summary>
        /// Check if the given match dataset is found in the local dataset using the default Tag Type list. 
        /// A check is made to see if all the attributes in the given match dataset are present in the local
        /// dataset. In addition to the base match we need to try to match attributes from the
        /// Request Attributes Sequence (if present).
        /// </summary>
        /// <param name="matchDataset">Match dataset to check.</param>
        /// <returns>Boolean indicating if the match attributes are present in the local dataset.</returns>
        public override bool IsFoundIn(AttributeSet matchDataset)
        {
            bool isFoundIn = base.IsFoundIn(matchDataset);

            if (isFoundIn == false)
            {
                // check if the Request Attributes Sequence is available in the match dataset
                DvtkData.Dimse.Attribute requestAttributesSequence = matchDataset.GetAttribute(Tag.REQUEST_ATTRIBUTES_SEQUENCE);
                if (requestAttributesSequence != null)
                {
                    SequenceOfItems sequenceOfItems = (SequenceOfItems)requestAttributesSequence.DicomValue;
                    if (sequenceOfItems.Sequence.Count == 1)
                    {
                        // set up a temporary tag list to check the relevant tags in the Request Attributes Sequence
                        TagTypeList itemTagTypeList = new TagTypeList();
                        itemTagTypeList.Add(new TagType(Tag.REQUESTED_PROCEDURE_ID, TagTypeEnum.TagOptional));

                        DvtkData.Dimse.SequenceItem item = sequenceOfItems.Sequence[0];

                        // check if found in item
                        isFoundIn = base.IsFoundIn(itemTagTypeList, item);
                    }
                }
            }

            return isFoundIn;
        }
Beispiel #2
0
        /// <summary>
        /// Check if the given match dataset is found in the local dataset using the given Tag Type list. 
        /// A check is made to see if all the attributes in the given match dataset are present in the local
        /// dataset. if the given matchOnUniqueTagOnly parameter is true only the Unique Tags will be checked.
        /// </summary>
        /// <param name="tagTypeList">Match Tag Type list.</param>
        /// <param name="matchDataset">Match dataset to check.</param>
        /// <param name="matchOnUniqueTagOnly">Boolean indicating if only the Unique Tag should be checked.</param>
        /// <returns>Boolean indicating if the match attributes are present in the local dataset.</returns>
        private bool IsFoundIn(TagTypeList tagTypeList, AttributeSet matchDataset, bool matchOnUniqueTagOnly)
        {
            bool isFound = true;
            bool uniqueTagFound = false;

            if (tagTypeList != null)
            {
                foreach (TagType tagType in tagTypeList)
                {
                    // check if we should try to match on the unique TagType only
                    if (matchOnUniqueTagOnly)
                    {
                        if (tagType.Type != TagTypeEnum.TagUnique) continue;
                    }

                    DvtkData.Dimse.Attribute thisAttribute = _dataset.GetAttribute(tagType.Tag);
                    DvtkData.Dimse.Attribute matchAttribute = matchDataset.GetAttribute(tagType.Tag);

                    if ((thisAttribute != null) &&
                        (matchAttribute == null))
                    {
                        isFound = false;
                    }
                    else if ((thisAttribute == null) &&
                        (matchAttribute != null))
                    {
                        isFound = false;
                    }
                    else if ((thisAttribute != null) &&
                        (matchAttribute != null))
                    {
                        // set the unique tag used flag - if we get this far in the code when matching the
                        // unique tag only then we must have found it
                        if (matchOnUniqueTagOnly)
                        {
                            uniqueTagFound = true;
                        }

                        if (thisAttribute.ValueRepresentation != matchAttribute.ValueRepresentation)
                        {
                            isFound = false;
                        }
                        else
                        {
                            if ((thisAttribute.Length == 0) &&
                                (matchAttribute.Length ==0))
                            {
                                // found
                            }
                            else if (thisAttribute.Length == 0)
                            {
                                // not found
                                isFound = false;
                            }
                            else if (matchAttribute.Length == 0)
                            {
                                // not found
                                isFound = false;
                            }
                            else
                            {
                                switch(thisAttribute.ValueRepresentation)
                                {
                                    case VR.AE:
                                    {
                                        ApplicationEntity thisApplicationEntity = (ApplicationEntity)thisAttribute.DicomValue;
                                        ApplicationEntity matchApplicationEntity = (ApplicationEntity)matchAttribute.DicomValue;
                                        if (thisApplicationEntity.Values.Count != matchApplicationEntity.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisApplicationEntity.Values.Count; i++)
                                            {
                                                if (!WildCardMatchString(matchApplicationEntity.Values[i], thisApplicationEntity.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.AS:
                                    {
                                        AgeString thisAgeString = (AgeString)thisAttribute.DicomValue;
                                        AgeString matchAgeString = (AgeString)matchAttribute.DicomValue;
                                        if (thisAgeString.Values.Count != matchAgeString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisAgeString.Values.Count; i++)
                                            {
                                                if (!MatchString(matchAgeString.Values[i], thisAgeString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.AT:
                                    {
                                        AttributeTag thisAttributeTag = (AttributeTag)thisAttribute.DicomValue;
                                        AttributeTag matchAttributeTag = (AttributeTag)matchAttribute.DicomValue;
                                        if (thisAttributeTag.Values.Count != matchAttributeTag.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisAttributeTag.Values.Count; i++)
                                            {
                                                if (matchAttributeTag.Values[i] != thisAttributeTag.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.CS:
                                    {
                                        CodeString thisCodeString = (CodeString)thisAttribute.DicomValue;
                                        CodeString matchCodeString = (CodeString)matchAttribute.DicomValue;
                                        if (thisCodeString.Values.Count != matchCodeString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisCodeString.Values.Count; i++)
                                            {
                                                if (!WildCardMatchString(matchCodeString.Values[i], thisCodeString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.DA:
                                    {
                                        Date thisDate = (Date)thisAttribute.DicomValue;
                                        Date matchDate = (Date)matchAttribute.DicomValue;
                                        if (thisDate.Values.Count != matchDate.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisDate.Values.Count; i++)
                                            {
                                                System.String thisDateString = thisDate.Values[i].Trim();
                                                System.String matchDateString = matchDate.Values[i].Trim();
                                                switch (matchDateString.Length)
                                                {
                                                case 9:
                                                    // ToDate = -YYYYMMDD
                                                    // FromDate = YYYYMMDD-
                                                    if (matchDateString.StartsWith("-"))
                                                    {
                                                        System.String date = matchDateString.Substring(1,8);
                                                        int comparison = thisDateString.CompareTo(date);
                                                        if (comparison > 0)
                                                        {
                                                            isFound = false;
                                                        }
                                                    }
                                                    else if (matchDateString.EndsWith("-"))
                                                    {
                                                        System.String date = matchDateString.Substring(0,8);
                                                        int comparison = thisDateString.CompareTo(date);
                                                        if (comparison < 0)
                                                        {
                                                            isFound = false;
                                                        }
                                                    }
                                                    break;
                                                case 17:
                                                    // DateRange = YYYYMMDD-YYYYMMDD
                                                    System.String[] dates = matchDateString.Split('-');
                                                    int comparison1 = thisDateString.CompareTo(dates[0]);
                                                    int comparison2 = thisDateString.CompareTo(dates[1]);
                                                    if ((comparison1 < 0) ||
                                                        (comparison2 > 0))
                                                    {
                                                        isFound = false;
                                                    }
                                                    break;
                                                case 8:
                                                    // Date = YYYYMMDD
                                                default:
                                                    if (!MatchString(matchDateString, thisDateString))
                                                    {
                                                        isFound = false;
                                                    }
                                                    break;
                                                }

                                                if (isFound == false) break;
                                            }
                                        }
                                        break;
                                    }
                                    case VR.DS:
                                    {
                                        DecimalString thisDecimalString = (DecimalString)thisAttribute.DicomValue;
                                        DecimalString matchDecimalString = (DecimalString)matchAttribute.DicomValue;
                                        if (thisDecimalString.Values.Count != matchDecimalString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisDecimalString.Values.Count; i++)
                                            {
                                                if (!MatchString(matchDecimalString.Values[i], thisDecimalString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.DT:
                                    {
                                        DvtkData.Dimse.DateTime thisDateTime = (DvtkData.Dimse.DateTime)thisAttribute.DicomValue;
                                        DvtkData.Dimse.DateTime matchDateTime = (DvtkData.Dimse.DateTime)matchAttribute.DicomValue;
                                        if (thisDateTime.Values.Count != matchDateTime.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisDateTime.Values.Count; i++)
                                            {
                                                if (!MatchString(matchDateTime.Values[i], thisDateTime.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.FD:
                                    {
                                        FloatingPointDouble thisFloatingPointDouble = (FloatingPointDouble)thisAttribute.DicomValue;
                                        FloatingPointDouble matchFloatingPointDouble = (FloatingPointDouble)matchAttribute.DicomValue;
                                        if (thisFloatingPointDouble.Values.Count != matchFloatingPointDouble.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisFloatingPointDouble.Values.Count; i++)
                                            {
                                                if (matchFloatingPointDouble.Values[i] != thisFloatingPointDouble.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.FL:
                                    {
                                        FloatingPointSingle thisFloatingPointSingle = (FloatingPointSingle)thisAttribute.DicomValue;
                                        FloatingPointSingle matchFloatingPointSingle = (FloatingPointSingle)matchAttribute.DicomValue;
                                        if (thisFloatingPointSingle.Values.Count != matchFloatingPointSingle.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisFloatingPointSingle.Values.Count; i++)
                                            {
                                                if (matchFloatingPointSingle.Values[i] != thisFloatingPointSingle.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.IS:
                                    {
                                        IntegerString thisIntegerString = (IntegerString)thisAttribute.DicomValue;
                                        IntegerString matchIntegerString = (IntegerString)matchAttribute.DicomValue;
                                        if (thisIntegerString.Values.Count != matchIntegerString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisIntegerString.Values.Count; i++)
                                            {
                                                if (!MatchString(matchIntegerString.Values[i], thisIntegerString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.LO:
                                    {
                                        LongString thisLongString = (LongString)thisAttribute.DicomValue;
                                        LongString matchLongString = (LongString)matchAttribute.DicomValue;
                                        if (thisLongString.Values.Count != matchLongString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisLongString.Values.Count; i++)
                                            {
                                                if (!WildCardMatchString(matchLongString.Values[i], thisLongString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.LT:
                                    {
                                        break;
                                    }
                                    case VR.OB:
                                    {
                                        break;
                                    }
                                    case VR.OF:
                                    {
                                        break;
                                    }
                                    case VR.OW:
                                    {
                                        break;
                                    }
                                    case VR.PN:
                                    {
                                        PersonName thisPersonName = (PersonName)thisAttribute.DicomValue;
                                        PersonName matchPersonName = (PersonName)matchAttribute.DicomValue;
                                        if (thisPersonName.Values.Count != matchPersonName.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisPersonName.Values.Count; i++)
                                            {
                                                if (!WildCardMatchString(matchPersonName.Values[i], thisPersonName.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.SH:
                                    {
                                        ShortString thisShortString = (ShortString)thisAttribute.DicomValue;
                                        ShortString matchShortString = (ShortString)matchAttribute.DicomValue;
                                        if (thisShortString.Values.Count != matchShortString.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisShortString.Values.Count; i++)
                                            {
                                                if (!WildCardMatchString(matchShortString.Values[i], thisShortString.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.SL:
                                    {
                                        SignedLong thisSignedLong = (SignedLong)thisAttribute.DicomValue;
                                        SignedLong matchSignedLong = (SignedLong)matchAttribute.DicomValue;
                                        if (thisSignedLong.Values.Count != matchSignedLong.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisSignedLong.Values.Count; i++)
                                            {
                                                if (matchSignedLong.Values[i] != thisSignedLong.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.SQ:
                                    {
            //										SequenceOfItems sequenceOfItems = (SequenceOfItems)attribute.DicomValue;
            //										foreach (SequenceItem item in sequenceOfItems.Sequence)
            //										{
            //										}
                                        break;
                                    }
                                    case VR.SS:
                                    {
                                        SignedShort thisSignedShort = (SignedShort)thisAttribute.DicomValue;
                                        SignedShort matchSignedShort = (SignedShort)matchAttribute.DicomValue;
                                        if (thisSignedShort.Values.Count != matchSignedShort.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisSignedShort.Values.Count; i++)
                                            {
                                                if (matchSignedShort.Values[i] != thisSignedShort.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.ST:
                                    {
                                        break;
                                    }
                                    case VR.TM:
                                    {
                                        Time thisTime = (Time)thisAttribute.DicomValue;
                                        Time matchTime = (Time)matchAttribute.DicomValue;
                                        if (thisTime.Values.Count != matchTime.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisTime.Values.Count; i++)
                                            {
                                                System.String thisTimeString = thisTime.Values[i].Trim();
                                                System.String matchTimeString = matchTime.Values[i].Trim();
                                                switch (matchTimeString.Length)
                                                {
                                                    case 7:
                                                        // ToDate = -HHMMSS
                                                        // FromDate = HHMMSS-
                                                        if (matchTimeString.StartsWith("-"))
                                                        {
                                                            System.String time = matchTimeString.Substring(1,6);
                                                            int comparison = thisTimeString.CompareTo(time);
                                                            if (comparison > 0)
                                                            {
                                                                isFound = false;
                                                            }
                                                        }
                                                        else if (matchTimeString.EndsWith("-"))
                                                        {
                                                            System.String time = matchTimeString.Substring(0,6);
                                                            int comparison = thisTimeString.CompareTo(time);
                                                            if (comparison < 0)
                                                            {
                                                                isFound = false;
                                                            }
                                                        }
                                                        break;
                                                    case 13:
                                                        // DateRange = HHMMSS-HHMMSS
                                                        System.String[] times = matchTimeString.Split('-');
                                                        int comparison1 = thisTimeString.CompareTo(times[0]);
                                                        int comparison2 = thisTimeString.CompareTo(times[1]);
                                                        if ((comparison1 < 0) ||
                                                            (comparison2 > 0))
                                                        {
                                                            isFound = false;
                                                        }
                                                        break;
                                                    case 6:
                                                        // Date = HHMMSS
                                                    default:
                                                        if (!MatchString(matchTimeString, thisTimeString))
                                                        {
                                                            isFound = false;
                                                        }
                                                        break;
                                                }

                                                if (isFound == false) break;
                                            }
                                        }
                                        break;
                                    }
                                    case VR.UI:
                                    {
                                        UniqueIdentifier thisUniqueIdentifier = (UniqueIdentifier)thisAttribute.DicomValue;
                                        UniqueIdentifier matchUniqueIdentifier = (UniqueIdentifier)matchAttribute.DicomValue;

                                        // check for list of UID matching
                                        if ((thisUniqueIdentifier.Values.Count == 1) &&
                                            (matchUniqueIdentifier.Values.Count > 1))
                                        {
                                            isFound = false;

                                            // iterate over all the possible matches
                                            for (int i = 0; i < matchUniqueIdentifier.Values.Count; i++)
                                            {
                                                if (MatchString(matchUniqueIdentifier.Values[i], thisUniqueIdentifier.Values[0]))
                                                {
                                                    isFound = true;
                                                    break;
                                                }
                                            }
                                        }
                                        else if (thisUniqueIdentifier.Values.Count == matchUniqueIdentifier.Values.Count)
                                        {
                                            for (int i = 0; i < thisUniqueIdentifier.Values.Count; i++)
                                            {
                                                if (!MatchString(matchUniqueIdentifier.Values[i], thisUniqueIdentifier.Values[i]))
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            isFound = false;
                                        }
                                        break;
                                    }
                                    case VR.UL:
                                    {
                                        UnsignedLong thisUnsignedLong = (UnsignedLong)thisAttribute.DicomValue;
                                        UnsignedLong matchUnsignedLong = (UnsignedLong)matchAttribute.DicomValue;
                                        if (thisUnsignedLong.Values.Count != matchUnsignedLong.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisUnsignedLong.Values.Count; i++)
                                            {
                                                if (matchUnsignedLong.Values[i] != thisUnsignedLong.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.UN:
                                    {
                                        break;
                                    }
                                    case VR.US:
                                    {
                                        UnsignedShort thisUnsignedShort = (UnsignedShort)thisAttribute.DicomValue;
                                        UnsignedShort matchUnsignedShort = (UnsignedShort)matchAttribute.DicomValue;
                                        if (thisUnsignedShort.Values.Count != matchUnsignedShort.Values.Count)
                                        {
                                            isFound = false;
                                        }
                                        else
                                        {
                                            for (int i = 0; i < thisUnsignedShort.Values.Count; i++)
                                            {
                                                if (matchUnsignedShort.Values[i] != thisUnsignedShort.Values[i])
                                                {
                                                    isFound = false;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                    case VR.UT:
                                    {
                                        break;
                                    }

                                    default:
                                        isFound = false;
                                        break;
                                }
                            }
                        }
                        if (isFound == false)
                        {
                            break;
                        }
                    }
                }
            }

            // check for special case where we should match on the Unique Tag only - but it was not found
            if ((matchOnUniqueTagOnly == true) &&
                (uniqueTagFound == false))
            {
                // no match
                isFound = false;
            }

            return isFound;
        }
Beispiel #3
0
        /// <summary>
        /// Copy from the local Dataset into the given destination Dataset as defined by the
        /// given Tag Type list. If the copyUniqueTagOnly parameter is true - only copy the Unique Tag attribute.
        /// </summary>
        /// <param name="tagTypeList">Tag Type list used to define copy.</param>
        /// <param name="destinationDataset">Dataset being populated by the given Tag Type list.</param>
        /// <param name="copyUniqueTagOnly">Boolean indicator to define use of Unique Tag.</param>
        private void CopyTo(TagTypeList tagTypeList, AttributeSet destinationDataset, bool copyUniqueTagOnly)
        {
            if (tagTypeList != null)
            {
                foreach (TagType tagType in tagTypeList)
                {
                    // check if we should only copy the unique TagType
                    if (copyUniqueTagOnly)
                    {
                        if (tagType.Type != TagTypeEnum.TagUnique) continue;
                    }

                    DvtkData.Dimse.Attribute destinationAttribute = _dataset.GetAttribute(tagType.Tag);
                    if (destinationAttribute != null)
                    {
                        destinationDataset.Add(destinationAttribute);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Check if a Universal Match is possible on the local dataset using the Tag Type list given.
        /// </summary>
        /// <param name="tagTypeList">Tag type list used for Universal Match.</param>
        /// <returns>Boolean indicating if a Universal Match is true oe false.</returns>
        public bool UniversalMatch(TagTypeList tagTypeList)
        {
            bool UniversalMatch = true;
            if (tagTypeList.Count != 0)
            {
                foreach(TagType tagType in tagTypeList)
                {
                    DvtkData.Dimse.Attribute thisAttribute = _dataset.GetAttribute(tagType.Tag);
                    if (thisAttribute != null)
                    {
                        if (thisAttribute.Length != 0)
                        {
                            UniversalMatch = false;
                            break;
                        }
                        else if (IsTagTypeIn(tagType) == false)
                        {
                            UniversalMatch = false;
                            break;
                        }
                    }
                }
            }

            return UniversalMatch;
        }
Beispiel #5
0
 /// <summary>
 /// Check if the given match dataset is found in the local dataset using the given Tag Type list. 
 /// A check is made to see if all the attributes in the given match dataset are present in the local
 /// dataset.
 /// </summary>
 /// <param name="tagTypeList">Match Tag Type list.</param>
 /// <param name="matchDataset">Match dataset to check.</param>
 /// <returns>Boolean indicating if the match attributes are present in the local dataset.</returns>
 public bool IsFoundIn(TagTypeList tagTypeList, AttributeSet matchDataset)
 {
     return IsFoundIn(tagTypeList, matchDataset, false);
 }
Beispiel #6
0
 /// <summary>
 /// Copy from the local Dataset into the given destination Dataset as defined by the
 /// given Tag Type list.
 /// </summary>
 /// <param name="tagTypeList">Tag Type list used to define copy.</param>
 /// <param name="destinationDataset">Dataset being populated by the given Tag Type list.</param>
 public void CopyTo(TagTypeList tagTypeList, AttributeSet destinationDataset)
 {
     CopyTo(tagTypeList, destinationDataset, false);
 }
Beispiel #7
0
 /// <summary>
 /// Copy from the given source Dataset into the local Dataset as defined by the
 /// given Tag Type list.
 /// </summary>
 /// <param name="tagTypeList">Tag Type list identifying attributes to copy.</param>
 /// <param name="sourceDataset">Source Dataset used to populate the local Dataset.</param>
 public void CopyFrom(TagTypeList tagTypeList, AttributeSet sourceDataset)
 {
     if (tagTypeList != null)
     {
         foreach (TagType tagType in tagTypeList)
         {
             DvtkData.Dimse.Attribute sourceAttribute = sourceDataset.GetAttribute(tagType.Tag);
             if (sourceAttribute != null)
             {
                 _dataset.Add(sourceAttribute);
             }
         }
     }
 }
Beispiel #8
0
        /// <summary>
        /// Check if a Universal Match is possible on the local dataset using the Tag Type list given.
        /// </summary>
        /// <param name="tagTypeList">Tag type list used for Universal Match.</param>
        /// <returns>Boolean indicating if a Universal Match is true or false.</returns>
        public bool UniversalMatch(TagTypeList tagTypeList)
        {
            bool UniversalMatch = true;
            if (tagTypeList.Count != 0)
            {
                foreach(TagType tagType in tagTypeList)
                {
                    DvtkData.Dimse.Attribute thisAttribute = _dataset.GetAttribute(tagType.Tag);
                    if (thisAttribute != null)
                    {
                        if (thisAttribute.Length != 0)
                        {
                            if (thisAttribute.ValueRepresentation == VR.SQ)
                            {
                                SequenceOfItems sequenceOfItems = (SequenceOfItems)thisAttribute.DicomValue;
                                if (sequenceOfItems.Sequence.Count != 0)
                                {
                                    UniversalMatch = false;
                                }
                            }
                            else
                            {
                                UniversalMatch = false;
                            }
                            break;
                        }
                        else if (IsTagTypeIn(tagType) == false)
                        {
                            UniversalMatch = false;
                            break;
                        }
                    }
                }
            }

            return UniversalMatch;
        }
Beispiel #9
0
        /// <summary>
        /// Copy from the given source Dataset into the local Dataset as defined by the
        /// given Tag Type list.
        /// </summary>
        /// <param name="tagTypeList">Tag Type list identifying attributes to copy.</param>
        /// <param name="sourceDataset">Source Dataset used to populate the local Dataset.</param>
        public void CopyFrom(TagTypeList tagTypeList, AttributeSet sourceDataset)
        {
            if (tagTypeList != null)
            {
                foreach (TagType tagType in tagTypeList)
                {
                    DvtkData.Dimse.Attribute sourceAttribute = sourceDataset.GetAttribute(tagType.Tag);
                    if (sourceAttribute != null)
                    {
                        // if an entry already exists - remove it
                        DvtkData.Dimse.Attribute destinationAttribute = _dataset.GetAttribute(tagType.Tag);
                        if (destinationAttribute != null)
                        {
                            _dataset.Remove(destinationAttribute);
                        }
                        //if (destinationAttribute != null && destinationAttribute.Tag == Tag.MODALITIES_IN_STUDY&&destinationAttribute.ValueRepresentation==VR.CS)
                        //{
                        //    StringCollection values = ((CodeString)destinationAttribute.DicomValue).Values;
                        //    string actualModality = ((CodeString)sourceDataset.GetAttribute(Tag.MODALITY).DicomValue).Values[0];

                        //    if (actualModality!=null&& !values.Contains(actualModality.Trim()))
                        //    {
                        //        values.Add(actualModality.Trim());
                        //    }
                        //    CodeString cs=new CodeString();
                        //    cs.Values=values;
                        //    sourceAttribute.DicomValue = cs;
                        //    System.UInt32 length = 0;
                        //    foreach (String data in cs.Values)
                        //    {
                        //        length += (System.UInt32)data.Length;
                        //    }
                        //    sourceAttribute.Length = length + (System.UInt32)cs.Values.Count - 1;
                        //}
                        _dataset.Add(sourceAttribute);
                    }
                    //else if (tagType.Tag == Tag.MODALITIES_IN_STUDY)
                    //{
                    //    sourceAttribute = new DvtkData.Dimse.Attribute();
                    //    sourceAttribute.Tag = Tag.MODALITIES_IN_STUDY;
                    //    sourceAttribute.Name = "Modalities in study";
                    //    DvtkData.Dimse.Attribute destinationAttribute = _dataset.GetAttribute(tagType.Tag);
                    //    string actualModality = ((CodeString)sourceDataset.GetAttribute(Tag.MODALITY).DicomValue).Values[0];
                    //    StringCollection values=null;
                    //    if (destinationAttribute != null&&destinationAttribute.ValueRepresentation==VR.CS)
                    //    {
                    //        _dataset.Remove(destinationAttribute);
                    //        values = ((CodeString)destinationAttribute.DicomValue).Values;
                    //    }
                    //    if (values == null)
                    //        values = new StringCollection();
                    //    if (actualModality != null && !values.Contains(actualModality.Trim()))
                    //    {
                    //        values.Add(actualModality.Trim());
                    //    }
                    //    CodeString cs = new CodeString();
                    //    cs.Values = values;
                    //    sourceAttribute.DicomValue = cs;
                    //    System.UInt32 length = 0;
                    //    foreach (String data in cs.Values)
                    //    {
                    //        length += (System.UInt32)data.Length;
                    //    }
                    //    sourceAttribute.Length = length + (System.UInt32)cs.Values.Count - 1;
                    //    _dataset.Add(sourceAttribute);
                    //}
                }

            }
        }
        /// <summary>
        /// Add the given Dataset to the Information Model. The data is normalised into the Information Model.
        /// </summary>
        /// <param name="dataSet">Dataset to add to the informartion model</param>
        /// <param name="transferSyntax">The transfer syntax specified in the dcm file</param>
        /// <param name="fMI">The File Meta Information of the dcm file.</param>
        /// <param name="storeFile">Boolean indicating whether the or not the data set should be stored.</param>
        //public override void AddToInformationModel(DvtkData.Media.DicomFile dicomFile, bool storeFile)
        //{
        //    // PATIENT level
        //    PatientInformationEntity patientInformationEntity = null;
        //    // check if the patient IE is already in the patientRootList
        //    foreach (PatientInformationEntity lPatientInformationEntity in Root)
        //    {
        //        if (lPatientInformationEntity.IsFoundIn(dicomFile.DataSet))
        //        {
        //            patientInformationEntity = lPatientInformationEntity;
        //            break;
        //        }
        //    }
        //    // patient IE is not already in the patientRootList
        //    if (patientInformationEntity == null)
        //    {
        //        // create a new patient IE from the dataset and add to the patientRootList
        //        patientInformationEntity = new PatientInformationEntity();
        //        patientInformationEntity.CopyFrom(dicomFile.DataSet);
        //        //Root.Add(patientInformationEntity);
        //        // Modified by RB 20090128 - when handling an order scheduled event from an actor
        //        // we want to insert the order as the first entry in the information model so that
        //        // it is returned as the first entry in the worklist query
        //        Root.Insert(0, patientInformationEntity);
        //    }
        //    // VISIT level
        //    VisitInformationEntity visitInformationEntity = null;
        //    // check if the visit IE is already in the patient IE children
        //    foreach (VisitInformationEntity lVisitInformationEntity in patientInformationEntity.Children)
        //    {
        //        if (lVisitInformationEntity.IsFoundIn(dicomFile.DataSet))
        //        {
        //            visitInformationEntity = lVisitInformationEntity;
        //            break;
        //        }
        //    }
        //    // visit IE is not already in the patient IE children
        //    if (visitInformationEntity == null)
        //    {
        //        // create a new visit IE from the dataset and add to the patient IE children
        //        visitInformationEntity = new VisitInformationEntity();
        //        visitInformationEntity.CopyFrom(dicomFile.DataSet);
        //        patientInformationEntity.AddChild(visitInformationEntity);
        //    }
        //    // IMAGING SERVICE REQUEST level
        //    ImagingServiceRequestInformationEntity imagingServiceRequestInformationEntity = null;
        //    // check if the imaging service request IE is already in the visit IE children
        //    foreach (ImagingServiceRequestInformationEntity lImagingServiceRequestInformationEntity in visitInformationEntity.Children)
        //    {
        //        if (lImagingServiceRequestInformationEntity.IsFoundIn(dicomFile.DataSet))
        //        {
        //            imagingServiceRequestInformationEntity = lImagingServiceRequestInformationEntity;
        //            break;
        //        }
        //    }
        //    // imaging service request IE is not already in the visit IE children
        //    if (imagingServiceRequestInformationEntity == null)
        //    {
        //        // create a new imaging service request IE from the dataset and add to the visit IE children
        //        imagingServiceRequestInformationEntity = new ImagingServiceRequestInformationEntity();
        //        imagingServiceRequestInformationEntity.CopyFrom(dicomFile.DataSet);
        //        visitInformationEntity.AddChild(imagingServiceRequestInformationEntity);
        //    }
        //    // REQUESTED PROCEDURE level
        //    RequestedProcedureInformationEntity requestedProcedureInformationEntity = null;
        //    // check if the requested procedure IE is already in the imaging service request IE children
        //    foreach (RequestedProcedureInformationEntity lRequestedProcedureInformationEntity in imagingServiceRequestInformationEntity.Children)
        //    {
        //        if (lRequestedProcedureInformationEntity.IsFoundIn(dicomFile.DataSet))
        //        {
        //            requestedProcedureInformationEntity = lRequestedProcedureInformationEntity;
        //            break;
        //        }
        //    }
        //    // requested procedure IE is not already in the imaging service request IE children
        //    if (requestedProcedureInformationEntity == null)
        //    {
        //        // create a new requested procedure IE from the dataset and add to the imaging service request IE children
        //        requestedProcedureInformationEntity = new RequestedProcedureInformationEntity();
        //        requestedProcedureInformationEntity.CopyFrom(dicomFile.DataSet);
        //        imagingServiceRequestInformationEntity.AddChild(requestedProcedureInformationEntity);
        //    }
        //    // SCHEDULED PROCEDURE STEP level
        //    ScheduledProcedureStepInformationEntity scheduledProcedureStepInformationEntity = null;
        //    // check if the scheduled procedure step IE is already in the requested procedure IE children
        //    foreach (ScheduledProcedureStepInformationEntity lScheduledProcedureStepInformationEntity in requestedProcedureInformationEntity.Children)
        //    {
        //        if (lScheduledProcedureStepInformationEntity.IsFoundIn(dicomFile.DataSet))
        //        {
        //            scheduledProcedureStepInformationEntity = lScheduledProcedureStepInformationEntity;
        //            break;
        //        }
        //    }
        //    // scheduled procedure step IE is not already in the requested procedure IE children
        //    if (scheduledProcedureStepInformationEntity == null)
        //    {
        //        // create a new scheduled procedure step IE from the dataset and add to the requested procedure IE children
        //        scheduledProcedureStepInformationEntity = new ScheduledProcedureStepInformationEntity();
        //        scheduledProcedureStepInformationEntity.CopyFrom(dicomFile.DataSet);
        //        requestedProcedureInformationEntity.AddChild(scheduledProcedureStepInformationEntity);
        //    }
        //}
        /// <summary>
        /// Query the Information Model using the given Query Dataset.
        /// </summary>
        /// <param name="queryDataset">Query Dataset.</param>
        /// <returns>A collection of zero or more query reponse datasets.</returns>
        public override DataSetCollection QueryInformationModel(DataSet queryDataset)
        {
            DataSetCollection queryResponses = new DataSetCollection();

            BaseInformationEntityList matchingPatients = new BaseInformationEntityList();
            BaseInformationEntityList matchingVisits = new BaseInformationEntityList();
            BaseInformationEntityList matchingImagingServiceRequests = new BaseInformationEntityList();
            BaseInformationEntityList matchingRequestedProcedures = new BaseInformationEntityList();
            BaseInformationEntityList matchingScheduledProcedureSteps = new BaseInformationEntityList();

            SequenceItem queryItem = null;
            TagTypeList queryTagTypeList = new TagTypeList();
            TagTypeList returnTagTypeList = new TagTypeList();
            foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
            {
                // special check for the Scheduled Procedure Step Sequence
                if (attribute.ValueRepresentation == VR.SQ)
                {
                    foreach (SequenceItem s in ((SequenceOfItems)attribute.DicomValue).Sequence)
                    {
                        if (IsSequenceHavingValue(s))
                        {
                            queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                        }
                    }
                }
                // Query attribute must be present with an attribute value
                // - Do not include the Specific Character Set attribute and group length as a query attribute
                else if ((attribute.Length != 0) &&
                        (attribute.Tag != Tag.SPECIFIC_CHARACTER_SET) &&
                        (attribute.Tag.ElementNumber != 0x0000) &&
                        (attribute.ValueRepresentation != VR.SQ))
                {
                    queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                }

                // Add all attributes as return attributes
                returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));

            }

            // iterate over the Modality Worklist Information Model and save all the matching
            // Scheduled Procedure Steps
            // iterate of all Information Entities
            foreach (PatientInformationEntity patientInformationEntity in Root)
            {
                if (patientInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))

                {
                    Console.WriteLine("-----PatientInformationEntity------");
                    Console.WriteLine(patientInformationEntity.DataSet.Dump("-"));
                    matchingPatients.Add(patientInformationEntity);

                    foreach (VisitInformationEntity visitInformationEntity in patientInformationEntity.Children)
                    {
                        Console.WriteLine("-----VisitInformationEntity------");
                        Console.WriteLine(visitInformationEntity.DataSet.Dump("--"));
                        if (visitInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                        {
                            matchingVisits.Add(visitInformationEntity);

                            foreach (ImagingServiceRequestInformationEntity imagingServiceRequestInformationEntity in visitInformationEntity.Children)
                            {
                                Console.WriteLine("-----ImagingServiceRequestInformationEntity------");
                                Console.WriteLine(imagingServiceRequestInformationEntity.DataSet.Dump("---"));
                                if (imagingServiceRequestInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                                {
                                    matchingImagingServiceRequests.Add(imagingServiceRequestInformationEntity);

                                    foreach (RequestedProcedureInformationEntity requestedProcedureInformationEntity in imagingServiceRequestInformationEntity.Children)
                                    {
                                        Console.WriteLine("-----RequestedProcedureInformationEntity------");
                                        Console.WriteLine(requestedProcedureInformationEntity.DataSet.Dump("----"));
                                        if (requestedProcedureInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                                        {
                                            matchingRequestedProcedures.Add(requestedProcedureInformationEntity);

                                           // if (queryItem != null)
                                            {

                                                foreach (ScheduledProcedureStepInformationEntity scheduledProcedureStepInformationEntity in requestedProcedureInformationEntity.Children)
                                                {
                                                    Console.WriteLine("-----ScheduledProcedureStepInformationEntity------");
                                                    Console.WriteLine(scheduledProcedureStepInformationEntity.DataSet.Dump("------"));
                                                    if (scheduledProcedureStepInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                                                    {
                                                        // add the scheduled procedure step to the matched list
                                                        matchingScheduledProcedureSteps.Add(scheduledProcedureStepInformationEntity);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (matchingScheduledProcedureSteps.Count > 0)
            {
                // we now have a list of all the matching scheduled procedure steps
                foreach (ScheduledProcedureStepInformationEntity matchingScheduledProcedureStepInformationEntity in matchingScheduledProcedureSteps)
                {
                    //SequenceItem responseItem = new SequenceItem();
                    //matchingScheduledProcedureStepInformationEntity.CopyTo(returnTagTypeList, responseItem);

                    //// remove the specific character set from the responseItem - it is only present in the scheduled procedure step as a helper...
                    //DvtkData.Dimse.Attribute specificChararcterSet = responseItem.GetAttribute(Tag.SPECIFIC_CHARACTER_SET);
                    //if (specificChararcterSet != null)
                    //{
                    //    responseItem.Remove(specificChararcterSet);
                    //}

                    //DvtkData.Dimse.Attribute attribute = new DvtkData.Dimse.Attribute(0x00400100, VR.SQ, responseItem);

                    DataSet queryResponse = new DataSet();
                   // queryResponse.Add(attribute);

                    // if the specific character set attribute has been stored in the sps IE - return it in the query response
                    DvtkData.Dimse.Attribute specificCharacterSetAttribute = matchingScheduledProcedureStepInformationEntity.GetSpecificCharacterSet();
                    if (specificCharacterSetAttribute != null)
                    {
                        queryResponse.Add(specificCharacterSetAttribute);
                    }

                    RequestedProcedureInformationEntity matchingRequestedProcedureInformationEntity
                        = (RequestedProcedureInformationEntity)matchingScheduledProcedureStepInformationEntity.Parent;
                    matchingRequestedProcedureInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                    ImagingServiceRequestInformationEntity matchingImagingServiceRequestInformationEntity
                        = (ImagingServiceRequestInformationEntity)matchingRequestedProcedureInformationEntity.Parent;
                    matchingImagingServiceRequestInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                    VisitInformationEntity matchingVisitInformationEntity
                        = (VisitInformationEntity)matchingImagingServiceRequestInformationEntity.Parent;
                    matchingVisitInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                    PatientInformationEntity matchingPatientInformationEntity
                        = (PatientInformationEntity)matchingVisitInformationEntity.Parent;
                    matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                    matchingScheduledProcedureStepInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                    queryResponses.Add(queryResponse);
                }
            }
            //else if (matchingRequestedProcedures.Count > 0)
            //{
            //    // we now have a list of all the matching requested procedures
            //    foreach (RequestedProcedureInformationEntity matchingRequestedProcedureInformationEntity in matchingRequestedProcedures)
            //    {
            //        DataSet queryResponse = new DataSet();

            //        matchingRequestedProcedureInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        ImagingServiceRequestInformationEntity matchingImagingServiceRequestInformationEntity
            //            = (ImagingServiceRequestInformationEntity)matchingRequestedProcedureInformationEntity.Parent;
            //        matchingImagingServiceRequestInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        VisitInformationEntity matchingVisitInformationEntity
            //            = (VisitInformationEntity)matchingImagingServiceRequestInformationEntity.Parent;
            //        matchingVisitInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        PatientInformationEntity matchingPatientInformationEntity
            //            = (PatientInformationEntity)matchingVisitInformationEntity.Parent;
            //        matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        queryResponses.Add(queryResponse);
            //    }
            //}
            //else if (matchingImagingServiceRequests.Count > 0)
            //{
            //    // we now have a list of all the matching image service requests
            //    foreach (ImagingServiceRequestInformationEntity matchingImagingServiceRequestInformationEntity in matchingImagingServiceRequests)
            //    {
            //        DataSet queryResponse = new DataSet();

            //        matchingImagingServiceRequestInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        VisitInformationEntity matchingVisitInformationEntity
            //            = (VisitInformationEntity)matchingImagingServiceRequestInformationEntity.Parent;
            //        matchingVisitInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        PatientInformationEntity matchingPatientInformationEntity
            //            = (PatientInformationEntity)matchingVisitInformationEntity.Parent;
            //        matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        queryResponses.Add(queryResponse);
            //    }
            //}
            //else if (matchingVisits.Count > 0)
            //{
            //    // we now have a list of all the matching visits
            //    foreach (VisitInformationEntity matchingVisitInformationEntity in matchingVisits)
            //    {
            //        DataSet queryResponse = new DataSet();

            //        matchingVisitInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        PatientInformationEntity matchingPatientInformationEntity
            //            = (PatientInformationEntity)matchingVisitInformationEntity.Parent;
            //        matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        queryResponses.Add(queryResponse);
            //    }
            //}
            //else if (matchingPatients.Count > 0)
            //{
            //    // we now have a list of all the matching patients
            //    foreach (PatientInformationEntity matchingPatientInformationEntity in matchingPatients)
            //    {
            //        DataSet queryResponse = new DataSet();

            //        matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);

            //        queryResponses.Add(queryResponse);
            //    }
            //}

            return queryResponses;
        }
        /// <summary>
        /// Query the Information Model using the given Query Dataset.
        /// </summary>
        /// <param name="queryDataset">Query Dataset.</param>
        /// <returns>A collection of zero or more query reponse datasets.</returns>
        public override DataSetCollection QueryInformationModel(DataSet queryDataset)
        {
            DataSetCollection queryResponses = new DataSetCollection();

            // get the query/retrieve level
            String queryRetrieveLevel = "UNKNOWN";
            DvtkData.Dimse.Attribute queryRetrieveLevelAttribute = queryDataset.GetAttribute(Tag.QUERY_RETRIEVE_LEVEL);
            if (queryRetrieveLevelAttribute != null)
            {
                CodeString codeString = (CodeString)queryRetrieveLevelAttribute.DicomValue;
                if (codeString.Values.Count == 1)
                {
                    queryRetrieveLevel = codeString.Values[0].Trim();
                }
            }

            // query at the PATIENT level
            if (queryRetrieveLevel == "PATIENT")
            {
                TagTypeList queryTagTypeList = new TagTypeList();
                TagTypeList returnTagTypeList = new TagTypeList();
                foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                {
                    if (attribute.ValueRepresentation == VR.SQ)
                    {
                        foreach (SequenceItem s in ((SequenceOfItems)attribute.DicomValue).Sequence)
                        {
                            if (IsSequenceHavingValue(s))
                            {
                                queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                            }
                        }
                    }
                    else if ((attribute.Length != 0) &&
                        (attribute.Tag.ElementNumber != 0x0000))
                    {
                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                    }
                    if (attribute.Tag != Tag.SPECIFIC_CHARACTER_SET)
                        returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                }

                foreach (PatientInformationEntity patientInformationEntity in Root)
                {
                    if (patientInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                    {
                        // PATIENT level matches
                        DataSet queryResponse = new DataSet();

                        // if the specific character set attribute has been stored in the patient IE - return it in the query response
                        DvtkData.Dimse.Attribute specificCharacterSetAttribute = patientInformationEntity.GetSpecificCharacterSet();
                        if (specificCharacterSetAttribute != null)
                        {
                            queryResponse.Add(specificCharacterSetAttribute);
                        }

                        patientInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                        patientInformationEntity.CopyAdditionalAttributes(queryResponse);
                        queryResponses.Add(queryResponse);
                    }
                }
            }
            else
            {
                // find the matching PATIENT
                PatientInformationEntity patientInformationEntity = null;
                foreach (PatientInformationEntity lPatientInformationEntity in Root)
                {
                    if (lPatientInformationEntity.IsUniqueTagFoundIn(queryDataset))
                    {
                        patientInformationEntity = lPatientInformationEntity;
                        break;
                    }
                }
                if (patientInformationEntity != null)
                {
                    // query at the STUDY level
                    if (queryRetrieveLevel == "STUDY")
                    {
                        TagTypeList queryTagTypeList = new TagTypeList();
                        TagTypeList returnTagTypeList = new TagTypeList();
                        foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                        {
                            // do not add higher level tag
                            if (attribute.Tag == Tag.PATIENT_ID) continue;

                            if (attribute.ValueRepresentation == VR.SQ)
                            {
                                foreach (SequenceItem s in ((SequenceOfItems)attribute.DicomValue).Sequence)
                                {
                                    if (IsSequenceHavingValue(s))
                                    {
                                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                                    }
                                }
                            }
                            else if ((attribute.Length != 0) &&
                                (attribute.Tag.ElementNumber != 0x0000))
                            {
                                queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                            }
                            returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                        }

                        foreach (StudyInformationEntity studyInformationEntity in patientInformationEntity.Children)
                        {
                            if (studyInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                            {
                                // STUDY level matches
                                DataSet queryResponse = new DataSet();

                                // if the specific character set attribute has been stored in the study IE - return it in the query response
                                DvtkData.Dimse.Attribute specificCharacterSetAttribute = studyInformationEntity.GetSpecificCharacterSet();
                                if (specificCharacterSetAttribute != null)
                                {
                                    queryResponse.Add(specificCharacterSetAttribute);
                                }

                                patientInformationEntity.CopyUniqueTagTo(queryResponse);
                                studyInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                                studyInformationEntity.CopyAdditionalAttributes(queryResponse);
                                queryResponses.Add(queryResponse);
                            }
                        }
                    }
                    else
                    {
                        // find the matching STUDY
                        StudyInformationEntity studyInformationEntity = null;
                        foreach (StudyInformationEntity lStudyInformationEntity in patientInformationEntity.Children)
                        {
                            if (lStudyInformationEntity.IsUniqueTagFoundIn(queryDataset))
                            {
                                studyInformationEntity = lStudyInformationEntity;
                                break;
                            }
                        }

                        if (studyInformationEntity != null)
                        {
                            // query at the SERIES level
                            if (queryRetrieveLevel == "SERIES")
                            {
                                TagTypeList queryTagTypeList = new TagTypeList();
                                TagTypeList returnTagTypeList = new TagTypeList();
                                foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                                {
                                    // do not add higher level tags
                                    if ((attribute.Tag == Tag.PATIENT_ID) ||
                                        (attribute.Tag == Tag.STUDY_INSTANCE_UID)) continue;

                                    if (attribute.ValueRepresentation == VR.SQ)
                                    {
                                        foreach (SequenceItem s in ((SequenceOfItems)attribute.DicomValue).Sequence)
                                        {
                                            if (IsSequenceHavingValue(s))
                                            {
                                                queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                                            }
                                        }
                                    }
                                    else if ((attribute.Length != 0) &&
                                        (attribute.Tag.ElementNumber != 0x0000))
                                    {
                                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                                    }
                                    returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                                }

                                foreach (SeriesInformationEntity seriesInformationEntity in studyInformationEntity.Children)
                                {
                                    if (seriesInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                                    {
                                        // SERIES level matches
                                        DataSet queryResponse = new DataSet();

                                        // if the specific character set attribute has been stored in the series IE - return it in the query response
                                        DvtkData.Dimse.Attribute specificCharacterSetAttribute = seriesInformationEntity.GetSpecificCharacterSet();
                                        if (specificCharacterSetAttribute != null)
                                        {
                                            queryResponse.Add(specificCharacterSetAttribute);
                                        }

                                        patientInformationEntity.CopyUniqueTagTo(queryResponse);
                                        studyInformationEntity.CopyUniqueTagTo(queryResponse);
                                        seriesInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                                        seriesInformationEntity.CopyAdditionalAttributes(queryResponse);
                                        queryResponses.Add(queryResponse);
                                    }
                                }
                            }
                            else
                            {
                                // find the matching SERIES
                                SeriesInformationEntity seriesInformationEntity = null;
                                foreach (SeriesInformationEntity lSeriesInformationEntity in studyInformationEntity.Children)
                                {
                                    if (lSeriesInformationEntity.IsUniqueTagFoundIn(queryDataset))
                                    {
                                        seriesInformationEntity = lSeriesInformationEntity;
                                        break;
                                    }
                                }

                                if (seriesInformationEntity != null)
                                {
                                    // query at the IMAGE level
                                    if (queryRetrieveLevel == "IMAGE")
                                    {
                                        TagTypeList queryTagTypeList = new TagTypeList();
                                        TagTypeList returnTagTypeList = new TagTypeList();
                                        foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                                        {
                                            // do not add higher level tags
                                            if ((attribute.Tag == Tag.PATIENT_ID) ||
                                                (attribute.Tag == Tag.STUDY_INSTANCE_UID) ||
                                                (attribute.Tag == Tag.SERIES_INSTANCE_UID)) continue;

                                            if (attribute.ValueRepresentation == VR.SQ)
                                            {
                                                foreach (SequenceItem s in ((SequenceOfItems)attribute.DicomValue).Sequence)
                                                {
                                                    if (IsSequenceHavingValue(s))
                                                    {
                                                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                                                    }
                                                }
                                            }
                                            else if ((attribute.Length != 0) &&
                                                (attribute.Tag.ElementNumber != 0x0000))
                                            {
                                                queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                                            }
                                            returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                                        }

                                        foreach (InstanceInformationEntity instanceInformationEntity in seriesInformationEntity.Children)
                                        {
                                            if (instanceInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                                            {
                                                // IMAGE level matches
                                                DataSet queryResponse = new DataSet();

                                                // if the specific character set attribute has been stored in the instance IE - return it in the query response
                                                DvtkData.Dimse.Attribute specificCharacterSetAttribute = instanceInformationEntity.GetSpecificCharacterSet();
                                                if (specificCharacterSetAttribute != null)
                                                {
                                                    queryResponse.Add(specificCharacterSetAttribute);
                                                }

                                                patientInformationEntity.CopyUniqueTagTo(queryResponse);
                                                studyInformationEntity.CopyUniqueTagTo(queryResponse);
                                                seriesInformationEntity.CopyUniqueTagTo(queryResponse);
                                                instanceInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                                                instanceInformationEntity.CopyAdditionalAttributes(queryResponse);
                                                queryResponses.Add(queryResponse);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return queryResponses;
        }
        /// <summary>
        /// Check if the given instance is present in the Information Model. The instance will be at the leaf nodes of the Information Model.
        /// </summary>
        /// <param name="sopClassUid">SOP Class UID to search for.</param>
        /// <param name="sopInstanceUid">SOP Instance UID to search for.</param>
        /// <returns>Boolean - true if instance found in the Information Model, otherwise false.</returns>
        public bool IsInstanceInInformationModel(System.String sopClassUid, System.String sopInstanceUid)
        {
            bool isInstanceInInformationModel = false;

            // set up the commit tag list for comparing with the leaf
            TagTypeList commitTagTypeList = new TagTypeList();
            commitTagTypeList.Add(new TagType(Tag.SOP_INSTANCE_UID, TagTypeEnum.TagRequired));
            commitTagTypeList.Add(new TagType(Tag.SOP_CLASS_UID, TagTypeEnum.TagRequired));

            // set up the commit dataset
            DvtkData.Dimse.DataSet commitDataset = new DvtkData.Dimse.DataSet();
            DvtkData.Dimse.Attribute attribute = new DvtkData.Dimse.Attribute(0x00080016, DvtkData.Dimse.VR.UI, sopClassUid);
            commitDataset.Add(attribute);
            attribute = new DvtkData.Dimse.Attribute(0x00080018, DvtkData.Dimse.VR.UI, sopInstanceUid);
            commitDataset.Add(attribute);

            // iterate over the whole information model - we are interested in the leaf nodes
            foreach (PatientInformationEntity patientInformationEntity in Root)
            {
                foreach (StudyInformationEntity studyInformationEntity in patientInformationEntity.Children)
                {
                    foreach (SeriesInformationEntity seriesInformationEntity in studyInformationEntity.Children)
                    {
                        foreach (InstanceInformationEntity instanceInformationEntity in seriesInformationEntity.Children)
                        {
                            if (instanceInformationEntity.IsFoundIn(commitTagTypeList, commitDataset))
                            {
                                // an instance has been found with the matching commit uids
                                isInstanceInInformationModel = true;
                                break;
                            }
                        }
                    }
                }
            }

            return isInstanceInInformationModel;
        }
        /// <summary>
        /// Query the Information Model using the given Query Dataset.
        /// </summary>
        /// <param name="queryDataset">Query Dataset.</param>
        /// <returns>A collection of zero or more query reponse datasets.</returns>
        public override DataSetCollection QueryInformationModel(DataSet queryDataset)
        {
            DataSetCollection queryResponses = new DataSetCollection();

            BaseInformationEntityList matchingScheduledProcedureSteps = new BaseInformationEntityList();

            SequenceItem queryItem = null;
            TagTypeList queryTagTypeList = new TagTypeList();
            TagTypeList returnTagTypeList = new TagTypeList();
            foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
            {
                // special check for the Scheduled Procedure Step Sequence
                if (attribute.Tag == Tag.SCHEDULED_PROCEDURE_STEP_SEQUENCE)
                {
                    SequenceOfItems sequenceOfItems = (SequenceOfItems)attribute.DicomValue;
                    if (sequenceOfItems.Sequence.Count == 1)
                    {
                        queryItem = sequenceOfItems.Sequence[0];

                        foreach (DvtkData.Dimse.Attribute itemAttribute in queryItem)
                        {
                            if (itemAttribute.Length != 0)
                            {
                                queryTagTypeList.Add(new TagType(itemAttribute.Tag, TagTypeEnum.TagRequired));
                            }
                            returnTagTypeList.Add(new TagType(itemAttribute.Tag, TagTypeEnum.TagOptional));
                        }
                    }
                }
                else
                {
                    if (attribute.Length != 0)
                    {
                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                    }
                    returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                }
            }

            // iterate over the Modality Worklist Information Model and save all the matching
            // Scheduled Procedure Steps
            // iterate of all Information Entities
            foreach (PatientInformationEntity patientInformationEntity in Root)
            {
                if ((patientInformationEntity.IsFoundIn(queryTagTypeList, queryDataset)) ||
                    (patientInformationEntity.UniversalMatch(queryTagTypeList)))
                {
                    foreach (VisitInformationEntity visitInformationEntity in patientInformationEntity.Children)
                    {
                        if ((visitInformationEntity.IsFoundIn(queryTagTypeList, queryDataset)) ||
                            (visitInformationEntity.UniversalMatch(queryTagTypeList)))
                        {
                            foreach (ImagingServiceRequestInformationEntity imagingServiceRequestInformationEntity in visitInformationEntity.Children)
                            {
                                if ((imagingServiceRequestInformationEntity.IsFoundIn(queryTagTypeList, queryDataset)) ||
                                    (imagingServiceRequestInformationEntity.UniversalMatch(queryTagTypeList)))
                                {
                                    foreach (RequestedProcedureInformationEntity requestedProcedureInformationEntity in imagingServiceRequestInformationEntity.Children)
                                    {
                                        if ((requestedProcedureInformationEntity.IsFoundIn(queryTagTypeList, queryDataset)) ||
                                            (requestedProcedureInformationEntity.UniversalMatch(queryTagTypeList)))
                                        {
                                            foreach (ScheduledProcedureStepInformationEntity scheduledProcedureStepInformationEntity in requestedProcedureInformationEntity.Children)
                                            {
                                                if (scheduledProcedureStepInformationEntity.IsFoundIn(queryTagTypeList, queryItem))
                                                {
                                                    // add the scheduled procedure step to the matched list
                                                    matchingScheduledProcedureSteps.Add(scheduledProcedureStepInformationEntity);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // we now have a list of all the matching scheduled procedure steps
            foreach (ScheduledProcedureStepInformationEntity matchingScheduledProcedureStepInformationEntity in matchingScheduledProcedureSteps)
            {
                SequenceItem responseItem = new SequenceItem();
                matchingScheduledProcedureStepInformationEntity.CopyTo(returnTagTypeList, responseItem);
                DvtkData.Dimse.Attribute attribute = new DvtkData.Dimse.Attribute(0x00400100, VR.SQ, responseItem);

                DataSet queryResponse = new DataSet();
                queryResponse.Add(attribute);

                RequestedProcedureInformationEntity matchingRequestedProcedureInformationEntity
                    = (RequestedProcedureInformationEntity)matchingScheduledProcedureStepInformationEntity.Parent;
                matchingRequestedProcedureInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                ImagingServiceRequestInformationEntity matchingImagingServiceRequestInformationEntity
                    = (ImagingServiceRequestInformationEntity)matchingRequestedProcedureInformationEntity.Parent;
                matchingImagingServiceRequestInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                VisitInformationEntity matchingVisitInformationEntity
                    = (VisitInformationEntity)matchingImagingServiceRequestInformationEntity.Parent;
                matchingVisitInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                PatientInformationEntity matchingPatientInformationEntity
                    = (PatientInformationEntity)matchingVisitInformationEntity.Parent;
                matchingPatientInformationEntity.CopyTo(returnTagTypeList, queryResponse);

                queryResponses.Add(queryResponse);
            }

            return queryResponses;
        }
        /// <summary>
        /// Query the Information Model using the given Query Dataset.
        /// </summary>
        /// <param name="queryDataset">Query Dataset.</param>
        /// <returns>A collection of zero or more query reponse datasets.</returns>
        public override DataSetCollection QueryInformationModel(DataSet queryDataset)
        {
            DataSetCollection queryResponses = null;

            // get the query/retrieve level
            String queryRetrieveLevel = "UNKNOWN";
            DvtkData.Dimse.Attribute queryRetrieveLevelAttribute = queryDataset.GetAttribute(Tag.QUERY_RETRIEVE_LEVEL);
            if (queryRetrieveLevelAttribute != null)
            {
                CodeString codeString = (CodeString)queryRetrieveLevelAttribute.DicomValue;
                if (codeString.Values.Count == 1)
                {
                    queryRetrieveLevel = codeString.Values[0].Trim();
                }
            }

            // query at the PATIENT level
            if (queryRetrieveLevel == "PATIENT")
            {
                TagTypeList queryTagTypeList = new TagTypeList();
                TagTypeList returnTagTypeList = new TagTypeList();
                foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                {
                    if (attribute.Length != 0)
                    {
                        queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                    }
                    returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                }

                foreach (PatientInformationEntity patientInformationEntity in Root)
                {
                    if (patientInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                    {
                        // PATIENT level matches
                        DataSet queryResponse = new DataSet();
                        patientInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                        queryResponses.Add(queryResponse);
                    }
                }
            }
            else
            {
                // find the matching PATIENT
                PatientInformationEntity patientInformationEntity = null;
                foreach (PatientInformationEntity lPatientInformationEntity in Root)
                {
                    if (lPatientInformationEntity.IsUniqueTagFoundIn(queryDataset))
                    {
                        patientInformationEntity = lPatientInformationEntity;
                        break;
                    }
                }
                if (patientInformationEntity != null)
                {
                    // query at the STUDY level
                    if (queryRetrieveLevel == "STUDY")
                    {
                        TagTypeList queryTagTypeList = new TagTypeList();
                        TagTypeList returnTagTypeList = new TagTypeList();
                        foreach (DvtkData.Dimse.Attribute attribute in queryDataset)
                        {
                            // do not add higher level tag
                            if (attribute.Tag == Tag.PATIENT_ID) continue;

                            if (attribute.Length != 0)
                            {
                                queryTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagRequired));
                            }
                            returnTagTypeList.Add(new TagType(attribute.Tag, TagTypeEnum.TagOptional));
                        }

                        foreach (StudyInformationEntity studyInformationEntity in patientInformationEntity.Children)
                        {
                            if (studyInformationEntity.IsFoundIn(queryTagTypeList, queryDataset))
                            {
                                // STUDY level matches
                                DataSet queryResponse = new DataSet();
                                patientInformationEntity.CopyUniqueTagTo(queryResponse);
                                studyInformationEntity.CopyTo(returnTagTypeList, queryResponse);
                                queryResponses.Add(queryResponse);
                            }
                        }
                    }
                }
            }

            return queryResponses;
        }