コード例 #1
0
        /// <summary>
        /// Gets an enumeration of <see cref="VoiWindow"/>s defined in the specified data source.
        /// </summary>
        /// <param name="dataset">A DICOM data source.</param>
        /// <returns>An enumeration of <see cref="VoiWindow"/>s.</returns>
        public static IEnumerable <VoiWindow> GetWindows(IDicomAttributeProvider dataset)
        {
            string windowCenterValues = dataset[DicomTags.WindowCenter].ToString();

            if (string.IsNullOrEmpty(windowCenterValues))
            {
                yield break;
            }

            string windowWidthValues = dataset[DicomTags.WindowWidth].ToString();

            if (string.IsNullOrEmpty(windowWidthValues))
            {
                yield break;
            }

            string windowExplanationValues = dataset[DicomTags.WindowCenterWidthExplanation].ToString();

            double[] windowCenters;
            DicomStringHelper.TryGetDoubleArray(windowCenterValues, out windowCenters);

            double[] windowWidths;
            DicomStringHelper.TryGetDoubleArray(windowWidthValues, out windowWidths);

            string[] windowExplanations = DicomStringHelper.GetStringArray(windowExplanationValues);

            foreach (VoiWindow window in GetWindows(windowCenters, windowWidths, windowExplanations))
            {
                yield return(window);
            }
        }
コード例 #2
0
ファイル: VoiWindow.cs プロジェクト: ronmark1/ClearCanvas-1
        /// <summary>
        /// Sets the VOI window attributes in the data source with the specified windows.
        /// </summary>
        /// <param name="windows">The list of <see cref="VoiWindow"/>s to be set.</param>
        /// <param name="dataset">A DICOM data source.</param>
        public static void SetWindows(IEnumerable <VoiWindow> windows, IDicomAttributeProvider dataset)
        {
            var voiWindows         = windows.ToList();
            var windowCenters      = DicomStringHelper.GetDicomStringArray(voiWindows.Select(s => s.Center));
            var windowWidths       = DicomStringHelper.GetDicomStringArray(voiWindows.Select(s => s.Width));
            var windowExplanations = voiWindows.Any(s => !string.IsNullOrEmpty(s.Explanation)) ? DicomStringHelper.GetDicomStringArray(voiWindows.Select(s => s.Explanation)) : null;

            if (voiWindows.Count > 0)
            {
                dataset[DicomTags.WindowCenter].SetStringValue(windowCenters);
                dataset[DicomTags.WindowWidth].SetStringValue(windowWidths);
                if (!string.IsNullOrEmpty(windowExplanations))
                {
                    dataset[DicomTags.WindowCenterWidthExplanation].SetStringValue(windowExplanations);
                }
                else
                {
                    dataset[DicomTags.WindowCenterWidthExplanation].SetEmptyValue();
                }
            }
            else
            {
                dataset[DicomTags.WindowCenter].SetEmptyValue();
                dataset[DicomTags.WindowWidth].SetEmptyValue();
                dataset[DicomTags.WindowCenterWidthExplanation].SetEmptyValue();
            }
        }
コード例 #3
0
        public void TestStringArrayConverter()
        {
            string input = null;

            string[] output = DicomStringHelper.GetStringArray(input);
            Assert.AreEqual(output.Length, 0);

            input  = "";
            output = DicomStringHelper.GetStringArray(input);
            Assert.AreEqual(output.Length, 0);

            input  = @"the\lazy\\brown\dog";
            output = DicomStringHelper.GetStringArray(input);
            Assert.AreEqual(output[0], "the");
            Assert.AreEqual(output[1], "lazy");
            Assert.AreEqual(output[2], "");
            Assert.AreEqual(output[3], "brown");
            Assert.AreEqual(output[4], "dog");

            input  = @"\the\lazy\brown\dog";
            output = DicomStringHelper.GetStringArray(input);
            Assert.AreEqual(output[0], "");
            Assert.AreEqual(output[1], "the");
            Assert.AreEqual(output[2], "lazy");
            Assert.AreEqual(output[3], "brown");
            Assert.AreEqual(output[4], "dog");

            input  = @"the\lazy\brown\dog\";
            output = DicomStringHelper.GetStringArray(input);
            Assert.AreEqual(output[0], "the");
            Assert.AreEqual(output[1], "lazy");
            Assert.AreEqual(output[2], "brown");
            Assert.AreEqual(output[3], "dog");
            Assert.AreEqual(output[4], "");
        }
コード例 #4
0
            private static string ConvertListOfUidCriteria(string listOfUidCriteria, string columnName)
            {
                string uids = StringUtilities.Combine(DicomStringHelper.GetStringArray(listOfUidCriteria), ", ",
                                                      delegate(string value) { return(String.Format("'{0}'", value)); });

                return(String.Format("{0} in ( {1} )", columnName, uids));
            }
コード例 #5
0
ファイル: Sop.cs プロジェクト: zhan2016/MacroMedicalSystem
 internal IStudyRootStudyIdentifier GetStudyIdentifier()
 {
     return(new StudyRootStudyIdentifier(this, this, null)
     {
         SpecificCharacterSet = DicomStringHelper.GetDicomStringArray(SpecificCharacterSet),
         RetrieveAE = DataSource.Server,
         InstanceAvailability = "ONLINE"
     });
 }
コード例 #6
0
 /// <summary>
 /// Returns a delegate that will get the value of <paramref name="dicomTag"/> (all positions),
 /// from an <see cref="ImageSop"/> as an array of <see cref="string"/>s.
 /// </summary>
 public static FrameDataRetrieverDelegate <string[]> GetStringArrayRetriever(uint dicomTag)
 {
     return(delegate(Frame frame)
     {
         string value;
         value = frame.ParentImageSop[dicomTag].ToString();
         return DicomStringHelper.GetStringArray(value ?? "");
     });
 }
コード例 #7
0
        /// <summary>
        /// Sets the VOI window attributes in the data source with the specified windows.
        /// </summary>
        /// <param name="windows">The list of <see cref="VoiWindow"/>s to be set.</param>
        /// <param name="dataset">A DICOM data source.</param>
        public static void SetWindows(IEnumerable <VoiWindow> windows, IDicomAttributeProvider dataset)
        {
            var windowCenters      = DicomStringHelper.GetDicomStringArray(windows.Select(s => s.Center));
            var windowWidths       = DicomStringHelper.GetDicomStringArray(windows.Select(s => s.Width));
            var windowExplanations = DicomStringHelper.GetDicomStringArray(windows.Select(s => s.Explanation));

            dataset[DicomTags.WindowCenter].SetStringValue(windowCenters);
            dataset[DicomTags.WindowWidth].SetStringValue(windowWidths);
            dataset[DicomTags.WindowCenterWidthExplanation].SetStringValue(windowExplanations);
        }
コード例 #8
0
        /// <summary>
        /// Parses a <see cref="PatientOrientation"/> from a DICOM multi-valued string.
        /// </summary>
        /// <param name="multiValuedString">Patient orientation, defined in orientation of rows and orientation of columns, separated by a backslash.</param>
        /// <param name="anatomicalOrientationType">The anatomical orientation type code.</param>
        /// <returns>
        /// NULL if there are not exactly 2 parsed values in the input string.
        /// </returns>
        public static PatientOrientation FromString(string multiValuedString, string anatomicalOrientationType)
        {
            if (string.IsNullOrEmpty(multiValuedString))
            {
                return(null);
            }
            var values = DicomStringHelper.GetStringArray(multiValuedString);

            return(values != null && values.Length == 2 ? new PatientOrientation(values[0], values[1], anatomicalOrientationType) : null);
        }
コード例 #9
0
        /// <summary>
        /// Creates a <see cref="PatientOrientation"/> object from a dicom multi-valued string.
        /// </summary>
        /// <returns>
        /// Null if there are not exactly 2 parsed values in the input string.
        /// </returns>
        public static PatientOrientation FromString(string multiValuedString)
        {
            string[] values = DicomStringHelper.GetStringArray(multiValuedString);
            if (values != null && values.Length == 2)
            {
                return(new PatientOrientation(values[0], values[1]));
            }

            return(null);
        }
コード例 #10
0
        /// <summary>
        /// Creates an <see cref="ImagePositionPatient"/> object from a dicom multi-valued string.
        /// </summary>
        /// <returns>
        /// Null if there are not exactly 3 parsed values in the input string.
        /// </returns>
        public static ImagePositionPatient FromString(string multiValuedString)
        {
            double[] values;
            if (DicomStringHelper.TryGetDoubleArray(multiValuedString, out values) && values.Length == 3)
            {
                return(new ImagePositionPatient(values[0], values[1], values[2]));
            }

            return(null);
        }
コード例 #11
0
        /// <summary>
        /// Creates a <see cref="PixelAspectRatio"/> object from a dicom multi-valued string.
        /// </summary>
        /// <returns>
        /// Null if there are not exactly 2 parsed values in the input string.
        /// </returns>
        public static PixelAspectRatio FromString(string multiValuedString)
        {
            int[] values;
            if (DicomStringHelper.TryGetIntArray(multiValuedString, out values) && values.Length == 2)
            {
                return(new PixelAspectRatio(values[0], values[1]));
            }

            return(null);
        }
コード例 #12
0
        public static PixelSpacing FromString(string multiValuedString)
        {
            double[] values;
            if (DicomStringHelper.TryGetDoubleArray(multiValuedString, out values) && values.Length == 2)
            {
                return(new PixelSpacing(values[0], values[1]));
            }

            return(null);
        }
コード例 #13
0
ファイル: PixelSpacing.cs プロジェクト: bangush/server-1
        /// <summary>
        /// Parses a <see cref="PixelSpacing"/> from a DICOM multi-valued string.
        /// </summary>
        /// <param name="multiValuedString">Pixel spacing, defined in row spacing and column spacing, separated by a backslash.</param>
        /// <returns>
        /// NULL if there are not exactly 2 parsed values in the input string.
        /// </returns>
        public static PixelSpacing FromString(string multiValuedString)
        {
            if (string.IsNullOrEmpty(multiValuedString))
            {
                return(null);
            }

            double[] values;
            return(DicomStringHelper.TryGetDoubleArray(multiValuedString, out values) && values.Length == 2 ? new PixelSpacing(values[0], values[1]) : null);
        }
コード例 #14
0
        /// <summary>
        /// Deserializes the key object selection SOP instance into a list of constituent images and associated presentation states.
        /// </summary>
        public IList <IKeyObjectContentItem> Deserialize()
        {
            List <IKeyObjectContentItem> contentItems = new List <IKeyObjectContentItem>();

            SrDocumentContentModuleIod srDocument = _document.SrDocumentContent;

            if (srDocument.ContentSequence != null)
            {
                foreach (IContentSequence contentItem in srDocument.ContentSequence.Where(contentItem => contentItem.RelationshipType == RelationshipType.Contains))
                {
                    if (contentItem.ValueType == ValueType.Image)
                    {
                        IImageReferenceMacro imageReference = contentItem;
                        if (imageReference.ReferencedSopSequence == null)
                        {
                            Platform.Log(LogLevel.Warn, "Invalid Key Object Selection document has no Referenced SOP Sequence.");
                            continue;
                        }

                        string referencedSopInstanceUid        = imageReference.ReferencedSopSequence.ReferencedSopInstanceUid;
                        string presentationStateSopInstanceUid = null;

                        if (imageReference.ReferencedSopSequence.ReferencedSopSequence != null)
                        {
                            presentationStateSopInstanceUid = imageReference.ReferencedSopSequence.ReferencedSopSequence.ReferencedSopInstanceUid;
                        }

                        string referencedFrameNumbers = imageReference.ReferencedSopSequence.ReferencedFrameNumber;
                        int[]  frameNumbers;
                        if (!string.IsNullOrEmpty(referencedFrameNumbers) &&
                            DicomStringHelper.TryGetIntArray(referencedFrameNumbers, out frameNumbers) && frameNumbers.Length > 0)
                        {
                            foreach (int frameNumber in frameNumbers)
                            {
                                KeyImageContentItem item = new KeyImageContentItem(referencedSopInstanceUid, frameNumber, presentationStateSopInstanceUid, _document);
                                contentItems.Add(item);
                            }
                        }
                        else
                        {
                            KeyImageContentItem item = new KeyImageContentItem(referencedSopInstanceUid, presentationStateSopInstanceUid, _document);
                            contentItems.Add(item);
                        }
                    }
                }
            }
            else
            {
                Platform.Log(LogLevel.Warn, "Invalid Key Object Selection document has no Content Sequence.");
            }

            return(contentItems.AsReadOnly());
        }
コード例 #15
0
ファイル: GradientDirection.cs プロジェクト: bangush/server-1
        /// <summary>
        /// Parses a <see cref="GradientDirection"/> from a DICOM multi-valued string.
        /// </summary>
        /// <param name="multiValuedString">Gradient direction, defined as X Y and Z, separated by a backslash.</param>
        /// <returns>
        /// NULL if there are not exactly 2 parsed values in the input string.
        /// </returns>
        public static GradientDirection FromString(string multiValuedString)
        {
            if (string.IsNullOrEmpty(multiValuedString))
            {
                return(null);
            }
            double[] values;
            if (DicomStringHelper.TryGetDoubleArray(multiValuedString, out values) && values.Length == 3)
            {
                new GradientDirection(values[0], values[1], values[2]);
            }

            return(null);
        }
コード例 #16
0
 public IList <StudyEntry> QueryByStudyInstanceUid(IEnumerable <string> studyInstanceUids)
 {
     return(Real.GetStudyEntries(
                new GetStudyEntriesRequest
     {
         Criteria = new StudyEntry
         {
             Study = new StudyRootStudyIdentifier
             {
                 StudyInstanceUid = DicomStringHelper.GetDicomStringArray(studyInstanceUids)
             }
         }
     }).StudyEntries);
 }
コード例 #17
0
        /// <summary>
        /// Creates an <see cref="ImageOrientationPatient"/> object from a DICOM multi-valued string.
        /// </summary>
        /// <param name="multiValuedString">A DICOM multi-valued string containing the 6 components of the row and column cosine vectors.</param>
        /// <returns>
        /// Returns NULL if there are not exactly six parseable values in the input string.
        /// </returns>
        public static ImageOrientationPatient FromString(string multiValuedString)
        {
            if (string.IsNullOrEmpty(multiValuedString))
            {
                return(null);
            }

            double[] values;
            if (DicomStringHelper.TryGetDoubleArray(multiValuedString, out values) && values.Length == 6)
            {
                return(new ImageOrientationPatient(values[0], values[1], values[2], values[3], values[4], values[5]));
            }
            return(null);
        }
コード例 #18
0
		/// <summary>
		/// Returns a delegate that will get the value of <paramref name="dicomTag"/> (all positions),
		/// from an <see cref="ImageSop"/> as an array of <see cref="double"/>s.
		/// </summary>
		public static FrameDataRetrieverDelegate<double[]> GetDoubleArrayRetriever(uint dicomTag)
		{
			return delegate(Frame frame)
				{
					string value;
					value = frame[dicomTag].ToString();
					double[] values;
					if (!DicomStringHelper.TryGetDoubleArray(value ?? "", out values))
						values = new double[] { };

					return values;

				};
		}
コード例 #19
0
        /// <summary>
        /// Returns a delegate that will get the value of <paramref name="dicomTag"/> (all positions),
        /// from an <see cref="ImageSop"/> as an array of <see cref="int"/>s.
        /// </summary>
        public static FrameDataRetrieverDelegate <int[]> GetIntArrayRetriever(uint dicomTag)
        {
            return(delegate(Frame frame)
            {
                string value;
                value = frame.ParentImageSop[dicomTag].ToString();

                int[] values;
                if (!DicomStringHelper.TryGetIntArray(value ?? "", out values))
                {
                    values = new int[] {}
                }
                ;

                return values;
            });
        }
コード例 #20
0
        /// <summary>
        /// Performs a STUDY query for the given Study Instance Uids.
        /// </summary>
        public IList <StudyRootStudyIdentifier> QueryByStudyInstanceUid(IEnumerable <string> studyInstanceUids)
        {
            foreach (string studyInstanceUid in studyInstanceUids)
            {
                Platform.CheckForEmptyString(studyInstanceUid, "studyInstanceUid");

                if (studyInstanceUid.Contains("*") || studyInstanceUid.Contains("?"))
                {
                    throw new ArgumentException("Study Instance Uid cannot contain wildcard characters.");
                }
            }

            StudyRootStudyIdentifier criteria = new StudyRootStudyIdentifier();

            criteria.StudyInstanceUid = DicomStringHelper.GetDicomStringArray(studyInstanceUids);
            return(StudyQuery(criteria));
        }
コード例 #21
0
        public void TestIntArrayConverter()
        {
            string input = null;

            int[] output;
            DicomStringHelper.TryGetIntArray(input, out output);
            Assert.AreEqual(output.Length, 0);

            input = "";
            DicomStringHelper.TryGetIntArray(input, out output);
            Assert.AreEqual(output.Length, 0);

            input = @"0\1\30";
            DicomStringHelper.TryGetIntArray(input, out output);
            Assert.AreEqual(output[0], 0);
            Assert.AreEqual(output[1], 1);
            Assert.AreEqual(output[2], 30);
        }
コード例 #22
0
        public void TestDoubleArrayConverter()
        {
            string input = null;

            double[] output;
            DicomStringHelper.TryGetDoubleArray(input, out output);
            Assert.AreEqual(output.Length, 0);

            input = "";
            DicomStringHelper.TryGetDoubleArray(input, out output);
            Assert.AreEqual(output.Length, 0);

            input = @"0\1.2\2.3";
            DicomStringHelper.TryGetDoubleArray(input, out output);
            Assert.AreEqual(output[0], 0);
            Assert.AreEqual(output[1], 1.2);
            Assert.AreEqual(output[2], 2.3);
        }
コード例 #23
0
        public void TestPersonNameArrayConverter()
        {
            string input = null;

            PersonName[] output = DicomStringHelper.GetPersonNameArray(input);
            Assert.AreEqual(output.Length, 0);

            input  = "";
            output = DicomStringHelper.GetPersonNameArray(input);
            Assert.AreEqual(output.Length, 0);

            input  = @"Doe^John^^^\Doe^Jane^^^";
            output = DicomStringHelper.GetPersonNameArray(input);
            Assert.AreEqual(output[0].FirstName, "John");
            Assert.AreEqual(output[0].LastName, "Doe");

            Assert.AreEqual(output[1].FirstName, "Jane");
            Assert.AreEqual(output[1].LastName, "Doe");
        }
コード例 #24
0
        public void TestListFormatters()
        {
            string input  = @"The\brown\dog\\jumped";
            string result = DicomDataFormatHelper.StringListFormat(DicomStringHelper.GetStringArray(input));

            Assert.AreEqual(result, "The,\nbrown,\ndog,\njumped");

            input  = @"Doe^John^^^";
            result = DicomDataFormatHelper.PersonNameFormatter(new PersonName(input));
            Assert.AreEqual(result, "Doe, John");

            input  = @"^John^^^";
            result = DicomDataFormatHelper.PersonNameFormatter(new PersonName(input));
            Assert.AreEqual(result, "John");

            input  = @"Doe^^^^";
            result = DicomDataFormatHelper.PersonNameFormatter(new PersonName(input));
            Assert.AreEqual(result, "Doe");

            input  = @"Doe^John^^^\Doe^Jane^^^";
            result = DicomDataFormatHelper.PersonNameListFormatter(DicomStringHelper.GetPersonNameArray(input));
            Assert.AreEqual(result, "Doe, John,\nDoe, Jane");

            input  = @"^John^^^\Doe^Jane^^^";
            result = DicomDataFormatHelper.PersonNameListFormatter(DicomStringHelper.GetPersonNameArray(input));
            Assert.AreEqual(result, "John,\nDoe, Jane");

            input  = @"^John^^^\Doe^^^^";
            result = DicomDataFormatHelper.PersonNameListFormatter(DicomStringHelper.GetPersonNameArray(input));
            Assert.AreEqual(result, "John,\nDoe");

            input  = @"^^^^\Doe^^^^";
            result = DicomDataFormatHelper.PersonNameListFormatter(DicomStringHelper.GetPersonNameArray(input));
            Assert.AreEqual(result, "Doe");

            input  = @"^^^^\^^^^";
            result = DicomDataFormatHelper.PersonNameListFormatter(DicomStringHelper.GetPersonNameArray(input));
            Assert.AreEqual(result, "");
        }
コード例 #25
0
        public static string[] ToStringArray(object value, TypeConverter converter)
        {
            if (value == null)
            {
                return new string[] { }
            }
            ;

            if (value.GetType().IsArray)
            {
                Array array = value as Array;

                if (array == null)
                {
                    return new string[] { }
                }
                ;

                string[] stringArray = new string[array.Length];
                int      i           = 0;
                foreach (object arrayValue in array)
                {
                    stringArray[i++] = ToString(arrayValue, converter);
                }

                return(stringArray);
            }
            else if (value is string)
            {
                //Assume strings are (potentially) multi-valued.  If they're not, then this has no effect anyway.
                return(DicomStringHelper.GetStringArray(((string)value) ?? ""));
            }
            else
            {
                return(new string[] { ToString(value, converter) });
            }
        }
    }
}
コード例 #26
0
        public StudyEntry ToStoreEntry()
        {
            var entry = new StudyEntry
            {
                Study = new StudyRootStudyIdentifier(this)
                {
                    InstanceAvailability = "ONLINE",
                    RetrieveAE           = ServerDirectory.GetLocalServer(),
                    SpecificCharacterSet = SpecificCharacterSet
                },
                Data = new StudyEntryData
                {
                    DeleteTime = DeleteTime,
                    InstitutionNamesInStudy = DicomStringHelper.GetStringArray(InstitutionNamesInStudy),
                    SourceAETitlesInStudy   = DicomStringHelper.GetStringArray(SourceAETitlesInStudy),
                    StationNamesInStudy     = DicomStringHelper.GetStringArray(StationNamesInStudy),
                    StoreTime = StoreTime
                }
            };

            return(entry);
        }
コード例 #27
0
        public IList <StudyRootStudyIdentifier> LocateStudyByInstanceUid(IEnumerable <string> studyInstanceUids, out LocateFailureInfo[] failures)
        {
            var instanceUids = studyInstanceUids.ToArray();

            foreach (string studyInstanceUid in instanceUids)
            {
                Platform.CheckForEmptyString(studyInstanceUid, "studyInstanceUid");

                if (studyInstanceUid.Contains("*") || studyInstanceUid.Contains("?"))
                {
                    throw new ArgumentException("Study Instance Uid cannot contain wildcard characters.");
                }
            }

            var criteria = new StudyRootStudyIdentifier {
                StudyInstanceUid = DicomStringHelper.GetDicomStringArray(instanceUids)
            };
            var result = LocateStudies(new LocateStudiesRequest {
                Criteria = criteria
            });

            failures = result.Failures.ToArray();
            return(result.Studies);
        }
コード例 #28
0
            // NOTE: this method is not bulletproof in the (very, very, very!) unusual case where there are
            // wildcards in the modalities in study criteria, but we still try to narrow down the result set
            // that is going to be post-filtered.
            private static string ConvertModalitiesInStudyCriteria(string criteria, string columnName)
            {
                //Modalities in study is a special case, where we allow list matching (not dicom compliant).
                string[]      criteriaValues = DicomStringHelper.GetStringArray(criteria);
                StringBuilder builder        = new StringBuilder();

                int i = 0;

                foreach (string criteriaValue in criteriaValues)
                {
                    criteria = criteriaValue;
                    string filter = "";
                    if (!ContainsWildcardCharacters(criteria))
                    {
                        filter = String.Format("{0} = '{1}' OR ", columnName, criteria);
                    }
                    else
                    {
                        ReplaceWildcardCharacters(ref criteria);
                        filter = String.Format("{0} LIKE '{1}' OR ", columnName, criteria);
                    }

                    filter += String.Format(@"{0} LIKE '{1}\%' " +
                                            @" OR {0} LIKE '%\{1}' " +
                                            @" OR {0} LIKE '%\{1}\%' ", columnName, criteria);

                    if (i++ > 0)
                    {
                        builder.Append(" OR ");
                    }

                    builder.AppendFormat(" ({0}) ", filter);
                }

                return(builder.ToString());
            }
コード例 #29
0
 private static string FormatMultiValues(IEnumerable <IDicomAttributeProvider> frames, Func <IDicomAttributeProvider, uint, string, string> formatter, uint dicomTag, string formatString)
 {
     return(DicomStringHelper.GetDicomStringArray(frames.Select(f => formatter(f, dicomTag, formatString))));
 }
コード例 #30
0
        public MRImageAnnotationItemProvider()
            : base("AnnotationItemProviders.Dicom.MRImage", new AnnotationResourceResolver(typeof(MRImageAnnotationItemProvider).Assembly))
        {
            _annotationItems = new List <IAnnotationItem>();

            AnnotationResourceResolver resolver = new AnnotationResourceResolver(this);

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.EchoTime",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                bool tagExists = frame[DicomTags.EffectiveEchoTime].TryGetFloat64(0, out value) || frame[DicomTags.EchoTime].TryGetFloat64(0, out value);
                if (tagExists)
                {
                    return(String.Format(SR.FormatMilliseconds, value.ToString("F2")));
                }

                return("");
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.MagneticFieldStrength",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                bool tagExists = frame[DicomTags.MagneticFieldStrength].TryGetFloat64(0, out value);
                if (tagExists)
                {
                    return(String.Format(SR.FormatTeslas, value.ToString("F1")));
                }

                return("");
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.AcquisitionMatrix",
                    resolver,
                    delegate(Frame frame)
            {
                // the acquisition matrix of an MR image refers to the dimensions of the raw data as acquired by the modality
                // which is encoded in frequency domain, so the two axes are phase and frequency
                // it seems that we simply want the width x height of the raw data here
                // which is basically figuring out whether phase is rows or cols, and formatting the numbers appropriately
                string phaseDirection = frame[DicomTags.InPlanePhaseEncodingDirection].ToString().ToUpperInvariant();

                var acqAttrib = frame[DicomTags.AcquisitionMatrix];
                if (!acqAttrib.IsEmpty && acqAttrib.Count >= 4)
                {
                    // the order of the values in this attribute is: freq-rows \ freq-cols \ phase-rows \ phase-cols
                    // the acquisition matrix tag is used by MR Image module, which uses the code string COL and ROW
                    switch (phaseDirection)
                    {
                    case "COL":
                        const int phaseColumns  = 3;
                        const int frequencyRows = 0;
                        return(String.Format(SR.Format2Dimensions, acqAttrib.GetUInt16(phaseColumns, 0), acqAttrib.GetUInt16(frequencyRows, 0)));

                    case "ROW":
                    default:
                        const int frequencyColumns = 1;
                        const int phaseRows        = 2;
                        return(String.Format(SR.Format2Dimensions, acqAttrib.GetUInt16(frequencyColumns, 0), acqAttrib.GetUInt16(phaseRows, 0)));
                    }
                }
                else
                {
                    int phaseSteps, frequencySteps;
                    if (frame[DicomTags.MrAcquisitionFrequencyEncodingSteps].TryGetInt32(0, out frequencySteps) &&
                        frame[DicomTags.MrAcquisitionPhaseEncodingStepsInPlane].TryGetInt32(0, out phaseSteps))
                    {
                        // in the MR FOV/Geometry functional group, the code strings are COLUMN, ROW and OTHER
                        switch (phaseDirection)
                        {
                        case "COLUMN":
                            return(string.Format(SR.Format2Dimensions, phaseSteps, frequencySteps));

                        case "ROW":
                            return(string.Format(SR.Format2Dimensions, frequencySteps, phaseSteps));
                        }
                    }
                }

                return(string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.ReceiveCoilName",
                    resolver,
                    delegate(Frame frame)
            {
                string value;
                value = frame[DicomTags.ReceiveCoilName].GetString(0, null);
                return(value);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.RepetitionTime",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                bool tagExists = frame[DicomTags.RepetitionTime].TryGetFloat64(0, out value);
                if (tagExists)
                {
                    return(String.Format(SR.FormatMilliseconds, value.ToString("F2")));
                }

                return("");
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.EchoTrainLength",
                    resolver,
                    delegate(Frame frame)
            {
                int value;
                bool tagExists = frame[DicomTags.EchoTrainLength].TryGetInt32(0, out value);
                if (tagExists)
                {
                    return(String.Format("{0}", value));
                }

                return("");
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.InversionTime",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                var tagExists = frame[DicomTags.InversionTime].TryGetFloat64(0, out value);
                if (tagExists)
                {
                    return(string.Format(SR.FormatMilliseconds, value.ToString("F2")));
                }

                DicomAttribute dicomAttribute;
                if (((IDicomAttributeProvider)frame).TryGetAttribute(DicomTags.InversionTimes, out dicomAttribute) && !dicomAttribute.IsEmpty && !dicomAttribute.IsNull)
                {
                    var values = dicomAttribute.Values as double[];
                    if (values != null)
                    {
                        return(string.Format(SR.FormatMilliseconds, DicomStringHelper.GetDicomStringArray(values, "F2")));
                    }
                }
                return(string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.TriggerTime",
                    resolver,
                    delegate(Frame frame)
            {
                // TODO CR (30 Sep 2013): Update to support enhanced MR - this tag is actually for cardiac MR, and now appears in the cardiac synchronization functional group
                double value;
                var tagExists = frame[DicomTags.TriggerTime].TryGetFloat64(0, out value);
                return(tagExists ? string.Format(SR.FormatMilliseconds, value.ToString("F2")) : string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.NumberOfAverages",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                var tagExists = frame[DicomTags.NumberOfAverages].TryGetFloat64(0, out value);
                return(tagExists ? string.Format("{0}", value) : string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.PixelBandwidth",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                var tagExists = frame[DicomTags.PixelBandwidth].TryGetFloat64(0, out value);
                return(tagExists ? string.Format(SR.FormatHertzPerPixel, value.ToString("F2")) : string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );

            _annotationItems.Add
            (
                new DicomAnnotationItem <string>
                (
                    "Dicom.MRImage.FlipAngle",
                    resolver,
                    delegate(Frame frame)
            {
                double value;
                var tagExists = frame[DicomTags.FlipAngle].TryGetFloat64(0, out value);
                return(tagExists ? string.Format(SR.FormatDegrees, value.ToString("F2")) : string.Empty);
            },
                    DicomDataFormatHelper.RawStringFormat
                )
            );
        }