Пример #1
0
        public static GrayscaleRenderOptions FromDataset(DicomDataset dataset)
        {
            var bits = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);
            options.RescaleSlope = dataset.Get<double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get<double>(DicomTag.RescaleIntercept, 0.0);
            if (dataset.Contains(DicomTag.WindowWidth) && dataset.Get<double>(DicomTag.WindowWidth) != 0.0) {
                options.WindowWidth = dataset.Get<double>(DicomTag.WindowWidth);
                options.WindowCenter = dataset.Get<double>(DicomTag.WindowCenter);
            } else if (dataset.Contains(DicomTag.SmallestImagePixelValue) && dataset.Contains(DicomTag.LargestImagePixelValue)) {
                var smallElement = dataset.Get<DicomElement>(DicomTag.SmallestImagePixelValue);
                var largeElement = dataset.Get<DicomElement>(DicomTag.LargestImagePixelValue);

                int smallValue = 0;
                int largeValue = 0;

                if (smallElement.ValueRepresentation == DicomVR.US) {
                    smallValue = smallElement.Get<ushort>(0);
                    largeValue = smallElement.Get<ushort>(0);
                } else {
                    smallValue = smallElement.Get<short>(0);
                    largeValue = smallElement.Get<short>(0);
                }

                options.WindowWidth = largeValue - smallValue;
                options.WindowCenter = (largeValue + smallValue) / 2.0;
            }
            options.Monochrome1 = dataset.Get<PhotometricInterpretation>(DicomTag.PhotometricInterpretation) == PhotometricInterpretation.Monochrome1;
            return options;
        }
Пример #2
0
 public void Contains_PrivateTag_SufficientlyFound()
 {
     var dataset = new DicomDataset();
     dataset.Add(new DicomTag(0x0021, 0x0010, "TEST"), "TEST");
     var found = dataset.Contains(new DicomTag(0x0021, 0x0010, "TEST"));
     Assert.True(found);
 }
        /// <summary>
        /// Creates a DICOM overlay from a GDI+ Bitmap.
        /// </summary>
        /// <param name="ds">Dataset</param>
        /// <param name="bitmap">Bitmap</param>
        /// <param name="mask">Color mask for overlay</param>
        /// <returns>DICOM overlay</returns>
        public static DicomOverlayData FromBitmap(DicomDataset ds, Bitmap bitmap, Color mask)
        {
            ushort group = 0x6000;
            while (ds.Contains(new DicomTag(group, DicomTag.OverlayBitPosition.Element))) group += 2;

            var overlay = new DicomOverlayData(ds, group)
                              {
                                  Type = DicomOverlayType.Graphics,
                                  Rows = bitmap.Height,
                                  Columns = bitmap.Width,
                                  OriginX = 1,
                                  OriginY = 1,
                                  BitsAllocated = 1,
                                  BitPosition = 1
                              };

            var array = new BitList { Capacity = overlay.Rows * overlay.Columns };

            int p = 0;
            for (var y = 0; y < bitmap.Height; y++)
            {
                for (var x = 0; x < bitmap.Width; x++, p++)
                {
                    if (bitmap.GetPixel(x, y).ToArgb() == mask.ToArgb()) array[p] = true;
                }
            }

            overlay.Data = EvenLengthBuffer.Create(new MemoryByteBuffer(array.Array));

            return overlay;
        }
Пример #4
0
        public static DicomRTReferencedStudy Read(DicomDataset ds)
        {
            var refSOPClass    = ds.GetStringOrEmpty(DicomTag.ReferencedSOPClassUID);
            var refSOPInstance = ds.GetStringOrEmpty(DicomTag.ReferencedSOPInstanceUID);
            var listSeries     = new List <DicomRTReferencedSeries>();

            if (ds.Contains(DicomTag.RTReferencedSeriesSequence))
            {
                // Changed for new OSS fo-dicom-desktop
                var seq = ds.GetSequence(DicomTag.RTReferencedSeriesSequence);
                //var seq = ds.Get<DicomSequence>(DicomTag.RTReferencedSeriesSequence);
                foreach (var item in seq)
                {
                    listSeries.Add(DicomRTReferencedSeries.Read(item));
                }
            }
            return(new DicomRTReferencedStudy(refSOPClass, refSOPInstance, listSeries));
        }
Пример #5
0
        public static bool HasEmbeddedOverlays(DicomDataset ds)
        {
            var groups = new List <ushort>();

            groups.AddRange(
                ds.Where(x => x.Tag.Group >= 0x6000 && x.Tag.Group <= 0x60FF && x.Tag.Element == 0x0010)
                .Select(x => x.Tag.Group));

            foreach (var group in groups)
            {
                if (!ds.Contains(new DicomTag(group, DicomTag.OverlayData.Element)))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #6
0
 public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null)
 {
     if (dataset.Contains(_tag))
     {
         dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
         var      value = dataset.GetString(_tag);
         string[] parts = value.Split('\\');
         for (int i = 0; i < parts.Length; i++)
         {
             if (parts[i].Length > _length)
             {
                 parts[i] = parts[i].Substring(0, _length);
             }
         }
         value = string.Join("\\", parts);
         dataset.AddOrUpdate(_tag, value);
     }
 }
Пример #7
0
        private void AddDicomTags(List <DicomTagModel> tags, DicomDataset ds)
        {
            //pass necessary dicom tags and value to client.
            List <DicomTag> tagsToAdd = new List <DicomTag>
            {
                DicomTag.PatientName, DicomTag.PatientID, DicomTag.PatientSex, DicomTag.PatientBirthDate, DicomTag.WindowWidth, DicomTag.WindowCenter, DicomTag.StudyTime,
                DicomTag.StudyDate, DicomTag.ViewPosition, DicomTag.BodyPartExamined
            };

            foreach (DicomTag t in tagsToAdd)
            {
                tags.Add(new DicomTagModel()
                {
                    group   = t.Group,
                    element = t.Element,
                    value   = ds.Contains(t) ? ds.Get <string>(t, "") : ""
                });
            }
        }
Пример #8
0
 public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null)
 {
     if (dataset.Contains(_tag))
     {
         dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
         var value = dataset.GetString(_tag);
         if (_position == DicomTrimPosition.Both)
         {
             if (_trim != null)
             {
                 value = value.Trim(_trim);
             }
             else
             {
                 value = value.Trim();
             }
         }
         else if (_position == DicomTrimPosition.Start)
         {
             if (_trim != null)
             {
                 value = value.TrimStart(_trim);
             }
             else
             {
                 value = value.TrimStart();
             }
         }
         else
         {
             if (_trim != null)
             {
                 value = value.TrimEnd(_trim);
             }
             else
             {
                 value = value.TrimEnd();
             }
         }
         dataset.AddOrUpdate(_tag, value);
     }
 }
Пример #9
0
        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>
        /// The object value.
        /// </returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            var dataset = new DicomDataset();

            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }
            if (reader.TokenType != JsonToken.StartObject)
            {
                throw new JsonReaderException("Malformed DICOM json");
            }
            reader.Read();
            while (reader.TokenType == JsonToken.PropertyName)
            {
                var      tagstr = (string)reader.Value;
                DicomTag tag    = ParseTag(tagstr);
                reader.Read();
                var item = ReadJsonDicomItem(tag, reader, serializer);
                dataset.Add(item);
                reader.Read();
            }
            foreach (var item in dataset)
            {
                if (item.Tag.IsPrivate && ((item.Tag.Element & 0xff00) != 0))
                {
                    var privateCreatorTag = new DicomTag(item.Tag.Group, (ushort)(item.Tag.Element >> 8));

                    if (dataset.Contains(privateCreatorTag))
                    {
                        item.Tag.PrivateCreator = new DicomPrivateCreator(dataset.Get <string>(privateCreatorTag));
                    }
                }
            }
            if (reader.TokenType != JsonToken.EndObject)
            {
                throw new JsonReaderException("Malformed DICOM json");
            }

            return(dataset);
        }
        /// <summary>
        /// Creates a DICOM overlay from a GDI+ Bitmap.
        /// </summary>
        /// <param name="ds">Dataset</param>
        /// <param name="bitmap">Bitmap</param>
        /// <param name="mask">Color mask for overlay</param>
        /// <returns>DICOM overlay</returns>
        public static DicomOverlayData FromBitmap(DicomDataset ds, Bitmap bitmap, Color mask)
        {
            ushort group = 0x6000;

            while (ds.Contains(new DicomTag(group, DicomTag.OverlayBitPosition.Element)))
            {
                group += 2;
            }

            var overlay = new DicomOverlayData(ds, group)
            {
                Type          = DicomOverlayType.Graphics,
                Rows          = bitmap.Height,
                Columns       = bitmap.Width,
                OriginX       = 1,
                OriginY       = 1,
                BitsAllocated = 1,
                BitPosition   = 1
            };

            var array = new BitList {
                Capacity = overlay.Rows * overlay.Columns
            };

            int p = 0;

            for (var y = 0; y < bitmap.Height; y++)
            {
                for (var x = 0; x < bitmap.Width; x++, p++)
                {
                    if (bitmap.GetPixel(x, y).ToArgb() == mask.ToArgb())
                    {
                        array[p] = true;
                    }
                }
            }

            overlay.Data = EvenLengthBuffer.Create(new MemoryByteBuffer(array.Array));

            return(overlay);
        }
Пример #11
0
        public static DicomRTReferencedSeries Read(DicomDataset ds)
        {
            var seriesInstanceUID = ds.GetStringOrEmpty(DicomTag.SeriesInstanceUID);

            var contourImages = new List <DicomRTContourImageItem>();

            if (ds.Contains(DicomTag.ContourImageSequence))
            {
                // Changed for new OSS fo-dicom-desktop
                var seq = ds.GetSequence(DicomTag.ContourImageSequence);
                //var seq = ds.Get<DicomSequence>(DicomTag.ContourImageSequence);

                foreach (var item in seq)
                {
                    var contourImageItem = DicomRTContourImageItem.Read(item);
                    contourImages.Add(contourImageItem);
                }
            }

            return(new DicomRTReferencedSeries(seriesInstanceUID, contourImages));
        }
Пример #12
0
        public static IReadOnlyDictionary <string, DicomRTStructureSetROI> Read(DicomDataset ds)
        {
            var rois = new Dictionary <string, DicomRTStructureSetROI>();

            if (ds.Contains(DicomTag.StructureSetROISequence))
            {
                // Changed for new OSS fo-dicom-desktop
                var seq = ds.GetSequence(DicomTag.StructureSetROISequence);
                //var seq = ds.Get<DicomSequence>(DicomTag.StructureSetROISequence);
                foreach (var item in seq)
                {
                    var roiNumber              = item.GetStringOrEmpty(DicomTag.ROINumber);
                    var referencedFrameUID     = item.GetStringOrEmpty(DicomTag.ReferencedFrameOfReferenceUID);
                    var roiName                = item.GetStringOrEmpty(DicomTag.ROIName);
                    var roiGenerationAlgorithm = ParseRoiAlgorithm(item.GetStringOrEmpty(DicomTag.ROIGenerationAlgorithm));
                    rois.Add(
                        roiNumber, new DicomRTStructureSetROI(roiNumber, roiName, referencedFrameUID, roiGenerationAlgorithm));
                }
            }
            return(rois);
        }
Пример #13
0
        private DicomDataset ReadJsonDataset(JToken obj)
        {
            var dataset = new DicomDataset();

            if (!_autoValidate)
            {
                dataset = dataset.NotValidated();
            }
            if (obj.Type == JTokenType.Null)
            {
                return(null);
            }
            if (!(obj is JObject itemObject))
            {
                throw new JsonReaderException("Malformed DICOM json");
            }

            foreach (var property in itemObject.Properties())
            {
                var      tagstr = property.Name;
                DicomTag tag    = ParseTag(tagstr);
                var      item   = ReadJsonDicomItem(tag, property.Value);
                dataset.Add(item);
            }

            foreach (var item in dataset)
            {
                if (item.Tag.IsPrivate && ((item.Tag.Element & 0xff00) != 0))
                {
                    var privateCreatorTag = new DicomTag(item.Tag.Group, (ushort)(item.Tag.Element >> 8));

                    if (dataset.Contains(privateCreatorTag))
                    {
                        item.Tag.PrivateCreator = new DicomPrivateCreator(dataset.GetSingleValue <string>(privateCreatorTag));
                    }
                }
            }

            return(dataset);
        }
Пример #14
0
        public static void Fill <T>(this DicomDataset ds)
        {
            var propsInfo = typeof(T).GetProperties();

            //.Where(prop => Attribute.IsDefined(prop, typeof(DicomTagAttribute), true));

            foreach (var propInfo in propsInfo)
            {
                var tagAttr = (DicomTagAttribute)Attribute.GetCustomAttribute(propInfo, typeof(DicomTagAttribute), true);
                if (tagAttr == null)
                {
                    continue;
                }

                DicomTag tag = tagAttr.Value;

                if (!ds.Contains(tag))
                {
                    ds.AddOrUpdate(tag, string.Empty);
                }
            }
        }
        public static DicomRTFrameOFReference Read(DicomDataset ds)
        {
            // Changed for new OSS fo-dicom-desktop
            var frameReferencedUID = ds.GetString(DicomTag.FrameOfReferenceUID);
            //var frameReferencedUID = ds.Get(DicomTag.FrameOfReferenceUID, string.Empty);

            var referencedStudies = new List <DicomRTReferencedStudy>();

            if (ds.Contains(DicomTag.RTReferencedStudySequence))
            {
                // Changed for new OSS fo-dicom-desktop
                var seq = ds.GetSequence(DicomTag.RTReferencedStudySequence);
                //var seq = ds.Get<DicomSequence>(DicomTag.RTReferencedStudySequence);
                foreach (var item in seq)
                {
                    referencedStudies.Add(DicomRTReferencedStudy.Read(item));
                }
            }
            return(new DicomRTFrameOFReference(
                       frameReferencedUID,
                       referencedStudies));
        }
Пример #16
0
 public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null)
 {
     if (dataset.Contains(_tag))
     {
         dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
         var value = dataset.GetString(_tag);
         if (_position == DicomTrimPosition.Start || _position == DicomTrimPosition.Both)
         {
             while (value.StartsWith(_trim))
             {
                 value = value.Substring(_trim.Length);
             }
         }
         if (_position == DicomTrimPosition.End || _position == DicomTrimPosition.Both)
         {
             while (value.EndsWith(_trim))
             {
                 value = value.Substring(0, value.Length - _trim.Length);
             }
         }
         dataset.AddOrUpdate(_tag, value);
     }
 }
 static private DicomItem GetAttributeValue(DicomDataset dataset, DicomTag attributeTag, DicomVR vr)
 {
     if (dataset.Contains(attributeTag) && dataset.GetDicomItem <DicomItem>(attributeTag).ValueRepresentation == vr)
     {
         return(dataset.GetDicomItem <DicomItem>(attributeTag));
     }
     foreach (var item in dataset)
     {
         if (item.ValueRepresentation != DicomVR.SQ)
         {
             continue;
         }
         foreach (var sequenceDataset in dataset.GetSequence(item.Tag))
         {
             var value = GetAttributeValue(sequenceDataset, attributeTag, vr);
             if (value != null)
             {
                 return(value);
             }
         }
     }
     return(null);
 }
Пример #18
0
        /// <summary>
        /// Read an RT Contour Item from the given dataset.
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static DicomRTContourItem Read(DicomDataset ds)
        {
            // Changed for new OSS fo-dicom-desktop
            var numberOfPoints = ds.GetSingleValue <int>(DicomTag.NumberOfContourPoints);
            // fo-dicom internally parses strings to decimal using InvariantCulture and then converts to double
            var data = ds.GetValues <double>(DicomTag.ContourData);
            //var numberOfPoints = ds.Get<int>(DicomTag.NumberOfContourPoints);
            //// fo-dicom internally parses strings to decimal using InvariantCulture and then converts to double
            //var data = ds.Get<double[]>(DicomTag.ContourData);
            var geometricType = ds.GetTrimmedStringOrEmpty(DicomTag.ContourGeometricType);
            List <DicomRTContourImageItem> listImages = new List <DicomRTContourImageItem>();

            if (ds.Contains(DicomTag.ContourImageSequence))
            {
                // Changed for new OSS fo-dicom-desktop
                var seqImages = ds.GetSequence(DicomTag.ContourImageSequence);
                //var seqImages = ds.Get<DicomSequence>(DicomTag.ContourImageSequence);
                foreach (var item in seqImages)
                {
                    listImages.Add(DicomRTContourImageItem.Read(item));
                }
            }
            return(new DicomRTContourItem(data, numberOfPoints, geometricType, listImages));
        }
Пример #19
0
        public void ContainsPrivateTagsChangesNothingWhenNotPresent()
        {
            var dataSet = new DicomDataset
            {
                { DicomTag.SOPInstanceUID, "2.999.1241" },
                { DicomTag.SOPClassUID, "2.999.1242" }
            };

            DicomPrivateCreator privateCreator = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR");
            DicomDictionary     privDict       = DicomDictionary.Default[privateCreator];

            var privTag = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.DT);

            privDict.Add(privTag);

            var dataBefore = SerializeDicom_(dataSet);

            var val = dataSet.Contains(privTag.Tag);

            var dataAfter = SerializeDicom_(dataSet);

            Assert.Equal(dataBefore, dataAfter);
            Assert.False(val);
        }
        public static DicomRTStructureSet Read(DicomDataset ds)
        {
            var label       = ds.GetTrimmedStringOrEmpty(DicomTag.StructureSetLabel);
            var name        = ds.GetTrimmedStringOrEmpty(DicomTag.StructureSetName);
            var description = ds.GetTrimmedStringOrEmpty(DicomTag.StructureSetDescription);

            var date = ds.GetStringOrEmpty(DicomTag.StructureSetDate);
            var time = ds.GetStringOrEmpty(DicomTag.StructureSetTime);

            var frames = new List <DicomRTFrameOFReference>();

            if (!ds.Contains(DicomTag.ReferencedFrameOfReferenceSequence))
            {
                return(new DicomRTStructureSet(label, name, description, date, time, frames));
            }
            // Changed for new OSS fo-dicom-desktop
            var seq = ds.GetSequence(DicomTag.ReferencedFrameOfReferenceSequence);

            //var seq = ds.Get<DicomSequence>(DicomTag.ReferencedFrameOfReferenceSequence);

            frames.AddRange(seq.Select(DicomRTFrameOFReference.Read));

            return(new DicomRTStructureSet(label, name, description, date, time, frames));
        }
Пример #21
0
        private static void ProcessOverlays(DicomDataset input, DicomDataset output)
        {
            DicomOverlayData[] overlays = null;
            if (input.InternalTransferSyntax.IsEncapsulated)
            {
                overlays = DicomOverlayData.FromDataset(output);
            }
            else
            {
                overlays = DicomOverlayData.FromDataset(input);
            }

            foreach (var overlay in overlays)
            {
                var dataTag = new DicomTag(overlay.Group, DicomTag.OverlayData.Element);

                // don't run conversion on non-embedded overlays
                if (output.Contains(dataTag))
                {
                    continue;
                }

                output.Add(new DicomTag(overlay.Group, DicomTag.OverlayBitsAllocated.Element), (ushort)1);
                output.Add(new DicomTag(overlay.Group, DicomTag.OverlayBitPosition.Element), (ushort)0);

                var data = overlay.Data;
                if (output.InternalTransferSyntax.IsExplicitVR)
                {
                    output.Add(new DicomOtherByte(dataTag, data));
                }
                else
                {
                    output.Add(new DicomOtherWord(dataTag, data));
                }
            }
        }
Пример #22
0
        private DicomDirectoryRecord CreateRecordSequenceItem(DicomDirectoryRecordType recordType, DicomDataset dataset)
        {
            if (recordType == null)
            {
                throw new ArgumentNullException("recordType");
            }
            if (dataset == null)
            {
                throw new ArgumentNullException("dataset");
            }

            var sequenceItem = new DicomDirectoryRecord();

            //add record item attributes
            sequenceItem.Add <uint>(DicomTag.OffsetOfTheNextDirectoryRecord, 0);
            sequenceItem.Add <ushort>(DicomTag.RecordInUseFlag, 0xFFFF);
            sequenceItem.Add <uint>(DicomTag.OffsetOfReferencedLowerLevelDirectoryEntity, 0);
            sequenceItem.Add <string>(DicomTag.DirectoryRecordType, recordType.ToString());

            //copy the current dataset character set
            sequenceItem.Add(dataset.FirstOrDefault(d => d.Tag == DicomTag.SpecificCharacterSet));

            foreach (var tag in recordType.Tags)
            {
                if (dataset.Contains(tag))
                {
                    sequenceItem.Add(dataset.Get <DicomItem>(tag));
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Cannot find tag {0} for record type {1}", tag, recordType);
                }
            }

            return(sequenceItem);
        }
Пример #23
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag) && dataset.Get<string>(_tag, -1, String.Empty) == _match) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				dataset.Add(_tag, _value);
			}
		}
        /// <summary>
        /// Create <see cref="GrayscaleRenderOptions"/>  from <paramref name="dataset"/> and populate the options properties with values:
        /// Bit Depth
        /// Rescale Slope
        /// Rescale Intercept
        /// Window Width
        /// Window Center
        /// </summary>
        /// <param name="dataset">Dataset to extract <see cref="GrayscaleRenderOptions"/> from</param>
        /// <returns>New grayscale render options instance</returns>
        public static GrayscaleRenderOptions FromDataset(DicomDataset dataset)
        {
            if (dataset.Contains(DicomTag.WindowWidth) && dataset.Get<double>(DicomTag.WindowWidth) >= 1.0
                && dataset.Contains(DicomTag.WindowCenter))
            {
                //If dataset contains WindowWidth and WindowCenter valid attributes used initially for the grayscale options
                return FromWindowLevel(dataset);
            }

            if (dataset.Contains(DicomTag.SmallestImagePixelValue) && dataset.Contains(DicomTag.LargestImagePixelValue)
                && dataset.Get<int>(DicomTag.SmallestImagePixelValue)
                < dataset.Get<int>(DicomTag.LargestImagePixelValue))
            {
                //If dataset contains valid SmallesImagePixelValue and LargesImagePixelValue attributes, use range to calculate
                //WindowWidth and WindowCenter
                return FromImagePixelValueTags(dataset);
            }

            //If reached here, minimum and maximum pixel values calculated from pixels data to calculate
            //WindowWidth and WindowCenter
            return FromMinMax(dataset);
        }
        public async Task <Priority> CheckAndDelayOnWaitConditions(RoutedItem ri)
        {
            RoutedItemEx routedItem = (RoutedItemEx)ri;
            var          taskInfo   = $"task: {routedItem.TaskID}";

            /*
             * check and delay on wait conditions
             * DICOM TAG (0000,0700)
             * LOW = 0002H
             * MEDIUM = 0000H
             * HIGH = 0001H
             */
            //Engage: Waits get engaged when DICOM Priority Tag detected, and get disengaged when done
            ushort priority = 3;

            try
            {
                if (routedItem.sourceDicomFile != null)
                {
                    DicomDataset dataSet = routedItem.sourceDicomFile.Dataset;

                    string uuid = null;
                    try
                    {
                        if (dataSet.Contains(DicomTag.StudyInstanceUID))
                        {
                            uuid = dataSet.GetValue <string>(DicomTag.StudyInstanceUID, 0);
                        }
                    }
                    catch (DicomDataException e)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no StudyInstanceUID field. {e.Message} {e.StackTrace}");
                    }

                    Profile currentProfile = _profileStorage.Current;

                    try
                    {
                        if (dataSet.Contains(DicomTag.Priority))
                        {
                            priority = dataSet.GetValue <ushort>(DicomTag.Priority, 0);
                        }
                        else
                        {
                            _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field.");
                        }
                    }
                    catch (DicomDataException e)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field. {e.Message} {e.StackTrace}");
                    }

                    if (priority < 3)
                    {
                        _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} has priority {priority}.");
                        if (priority.Equals(0x01))
                        {
                            currentProfile.highWait = true;
                            _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with high priority detected.  Setting highWait flag.");
                        }

                        if (priority.Equals(0x00))
                        {
                            currentProfile.mediumWait = true;
                            _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with medium priority detected.  Setting highWait flag.");
                        }
                    }

                    //Wait on Condition:
                    if (currentProfile.highWait || currentProfile.mediumWait)
                    { //something important is in mid transfer so check and wait if med or low
                        if (priority < 3 || priority.Equals(0x02))
                        {
                            //low or no priority is subject to both highWait and mediumWait conditions
                            if (currentProfile.highWait && !priority.Equals(0x01))
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                            if (currentProfile.mediumWait && !priority.Equals(0x00) && !priority.Equals(0x01))
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} mediumWait causing {currentProfile.mediumWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.mediumWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                        }
                        else if (priority.Equals(0x00))
                        {
                            //medium priority is subject to only highWait conditions
                            if (currentProfile.highWait)
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                        }
                    }
                }
            }
            catch (TaskCanceledException)
            {
                _logger.Log(LogLevel.Information, $"Task was canceled.");
            }
            catch (Exception e)
            {
                _logger.LogFullException(e);
            }
            return(_util.GetPriority(priority));
        }
Пример #26
0
        public void ContainsPrivateTagsChangesNothingWhenPresent()
        {
            DicomPrivateCreator privateCreator = DicomDictionary.Default.GetPrivateCreator("TESTCREATOR");
            DicomDictionary privDict = DicomDictionary.Default[privateCreator];

            var privTag = new DicomDictionaryEntry(DicomMaskedTag.Parse("0011", "xx10"), "TestPrivTagName", "TestPrivTagKeyword", DicomVM.VM_1, false, DicomVR.DT);

            privDict.Add(privTag);

            var dataSet = new DicomDataset
            {
                {DicomTag.SOPInstanceUID, "2.999.1241"},
                {DicomTag.SOPClassUID, "2.999.1242"},
                {privTag.Tag, "19700101123456"}
            };

            var dataBefore = SerializeDicom_(dataSet);

            var val = dataSet.Contains(privTag.Tag);

            var dataAfter = SerializeDicom_(dataSet);

            Assert.Equal(dataBefore, dataAfter);
            Assert.True(val);
        }
Пример #27
0
		public DicomDataset Transcode(DicomDataset dataset) {
			if (!dataset.Contains(DicomTag.PixelData)) {
				var newDataset = dataset.Clone();
				newDataset.InternalTransferSyntax = OutputSyntax;
				newDataset.RecalculateGroupLengths(false);
				return newDataset;
			}

			if (!InputSyntax.IsEncapsulated && !OutputSyntax.IsEncapsulated) {
				// transcode from uncompressed to uncompressed
				var newDataset = dataset.Clone();
				newDataset.InternalTransferSyntax = OutputSyntax;

				var oldPixelData = DicomPixelData.Create(dataset, false);
				var newPixelData = DicomPixelData.Create(newDataset, true);

				for (int i = 0; i < oldPixelData.NumberOfFrames; i++) {
					var frame = oldPixelData.GetFrame(i);
					newPixelData.AddFrame(frame);
				}

				ProcessOverlays(dataset, newDataset);

				newDataset.RecalculateGroupLengths(false);

				return newDataset;
			}

			if (InputSyntax.IsEncapsulated && OutputSyntax.IsEncapsulated) {
				// transcode from compressed to compressed
				var temp = Decode(dataset, DicomTransferSyntax.ExplicitVRLittleEndian, InputCodec, InputCodecParams);
				return Encode(temp, OutputSyntax, OutputCodec, OutputCodecParams);
			}

			if (InputSyntax.IsEncapsulated) {
				// transcode from compressed to uncompressed
				return Decode(dataset, OutputSyntax, InputCodec, InputCodecParams);
			}

			if (OutputSyntax.IsEncapsulated) {
				// transcode from uncompressed to compressed
				return Encode(dataset, OutputSyntax, OutputCodec, OutputCodecParams);
			}

			throw new DicomCodecException("Unable to find transcoding solution for {0} to {1}", InputSyntax.UID.Name, OutputSyntax.UID.Name);
		}
Пример #28
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				string[] parts = value.Split('\\');
				for (int i = 0; i < parts.Length; i++) {
					if (parts[i].Length > _length)
						parts[i] = parts[i].Substring(0, _length);
				}
				value = String.Join("\\", parts);
				dataset.Add(_tag, value);
			}
		}
Пример #29
0
 public bool Match(DicomDataset dataset)
 {
     return(dataset.Contains(_tag));
 }
Пример #30
0
        void StoreImage(DicomDataset ds, string modality)
        {
            DicomImage di = new DicomImage(ds);

            // store in cached resource
            var idc = new ImageDataContract();
            idc.PatientId = ds.Get<string>(DicomTag.PatientID);

            if (ds.Contains(DicomTag.PixelSpacing))
            {
                idc.PixelSpacing = new VoxelSize()
                {
                    X = Convert.ToSingle(ds.Get<double>(DicomTag.PixelSpacing, 0)),
                    Y = Convert.ToSingle(ds.Get<double>(DicomTag.PixelSpacing, 1)),
                };
            }
            else
            {
                idc.PixelSpacing = new VoxelSize() 
                { 
                    X = 1.0f, 
                    Y = 1.0f, 
                };
            }

            idc.ImagePosition = new ImagePosition()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 0)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 1)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 2)),
            };

            idc.ImageOrientation = new ImageOrientation();
            idc.ImageOrientation.Row = new DirectionCosine()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 0)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 1)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 2)),
            };

            idc.ImageOrientation.Column = new DirectionCosine()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 3)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 4)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 5)),
            };

            idc.Width = di.Width;
            idc.Height = di.Height;
            idc.Label = string.Format("{0} {1}",
                modality,
                ds.GetDateTime(DicomTag.SeriesDate, DicomTag.SeriesTime).ToString());
            idc.SeriesInstanceUID = ds.Get<string>(DicomTag.SeriesInstanceUID);

            // store for association closed event
            _seriesInstanceUIDs.Add(idc.SeriesInstanceUID);

            string for_uid = ds.Get<string>(DicomTag.FrameOfReferenceUID);
            idc.FrameOfReferenceUID = for_uid;

            LocalImageResourceManagerClient
                cache1 = new LocalImageResourceManagerClient();

            idc = cache1.AddImage(idc);
            double repoGb = cache1.GetRepositorySizeGB();

            cache1.Close();

            if (di.PhotometricInterpretation == PhotometricInterpretation.Monochrome1
                || di.PhotometricInterpretation == PhotometricInterpretation.Monochrome2)
            {
                var dsForWl = di.Dataset;
                if (_firstImageIn.ContainsKey(idc.SeriesInstanceUID))
                {
                    dsForWl = _firstImageIn[idc.SeriesInstanceUID].Dataset;
                }
                else
                {
                    _firstImageIn.TryAdd(idc.SeriesInstanceUID, di);
                }

                var gro = GrayscaleRenderOptions.FromDataset(dsForWl);
                var voilut = VOILUT.Create(gro);

                var ipd = PixelDataFactory.Create(di.PixelData, 0);

                int[] outPixelsInt = new int[di.Width * di.Height];
                ipd.Render(voilut, outPixelsInt);

                ushort[] outPixelsUshort = Array.ConvertAll(outPixelsInt,
                    new Converter<int, ushort>(inInt => (ushort)(inInt)));
                var handle = idc.PixelBuffer.GetHandle();
                handle.WriteArray<ushort>(0, outPixelsUshort, 0, outPixelsUshort.Length);
                idc.PixelBuffer.ReleaseHandle();
                idc.PixelBuffer.CloseMapping();

                // inform of found image
                ImageResponseClient proxy = ImageResponseClient.CreateProxy();
                proxy.OnImageStored(idc.ImageId, repoGb);
                proxy.Close();
            }
        }
        /// <summary>
        /// Returns a basic type (string, double, int array, dictionary etc) for the given <paramref name="item"/> in the <paramref name="dataset"/>.
        /// </summary>
        /// <param name="dataset"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static object GetCSharpValue(DicomDataset dataset, DicomItem item)
        {
            if (dataset == null || !dataset.Any())
            {
                throw new ArgumentException("The DicomDataset is invalid as it is null or has no elements.");
            }

            if (item == null || item.Tag == null || item.ValueRepresentation == null)
            {
                throw new ArgumentException("The DicomItem is invalid as it is either null, has a null Tag, or null ValueRepresentation: " + item);
            }

            if (!dataset.Contains(item))
            {
                throw new ArgumentException("The DicomDataset does not contain the item");
            }

            if (item.Tag == DicomTag.PixelData)
            {
                return(null);
            }

            switch (item.ValueRepresentation.Code)
            {
            // AE - Application Entity
            case "AE":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // AS - Age String
            case "AS":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // AT - Attribute Tag
            case "AT":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // CS - Code String
            case "CS":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // DA - Date
            case "DA":
                return(GetValueFromDatasetWithMultiplicity <DateTime>(dataset, item.Tag));

            // DS - Decimal String
            case "DS":
                return(GetValueFromDatasetWithMultiplicity <decimal>(dataset, item.Tag));

            // DT - Date Time
            case "DT":
                return(GetValueFromDatasetWithMultiplicity <DateTime>(dataset, item.Tag));

            // FL - Floating Point Single
            case "FL":
                return(GetValueFromDatasetWithMultiplicity <float>(dataset, item.Tag));

            // FD - Floating Point Double
            case "FD":
                return(GetValueFromDatasetWithMultiplicity <double>(dataset, item.Tag));

            // IS - Integer String
            case "IS":
                return(GetValueFromDatasetWithMultiplicity <int>(dataset, item.Tag));

            // LO - Long String
            case "LO":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // LT - Long Text
            case "LT":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // OB - Other Byte String
            case "OB":
                return(GetValueFromDatasetWithMultiplicity <byte>(dataset, item.Tag));

            // OD - Other Double String
            case "OD":
                return(GetValueFromDatasetWithMultiplicity <double>(dataset, item.Tag));

            // OF - Other Float String
            case "OF":
                return(GetValueFromDatasetWithMultiplicity <float>(dataset, item.Tag));

            // OL - Other Long
            case "OL":
                return(GetValueFromDatasetWithMultiplicity <uint>(dataset, item.Tag));

            // OW - Other Word String
            case "OW":
                return(GetValueFromDatasetWithMultiplicity <ushort>(dataset, item.Tag));

            // PN - Person Name
            case "PN":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // SH - Short String
            case "SH":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // SL - Signed Long
            case "SL":
                return(GetValueFromDatasetWithMultiplicity <int>(dataset, item.Tag));

            // SQ - Sequence
            case "SQ":
                return(GetSequenceFromDataset(dataset, item.Tag));

            // SS - Signed Short
            case "SS":
                return(GetValueFromDatasetWithMultiplicity <short>(dataset, item.Tag));

            // ST - Short Text
            case "ST":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // TM - Time
            case "TM":

                var tm = GetValueFromDatasetWithMultiplicity <DateTime>(dataset, item.Tag);

                // Need to handle case where we couldn't parse to DateTime so returned string instead
                return(tm is DateTime
                            ? ConvertToTimeSpanArray(tm)
                            : tm);

            // UC - Unlimited Characters
            case "UC":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // UI - Unique Identifier
            case "UI":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // UL - Unsigned Long
            case "UL":
                return(GetValueFromDatasetWithMultiplicity <uint>(dataset, item.Tag));

            // UN - Unknown
            case "UN":
                return(GetValueFromDatasetWithMultiplicity <byte>(dataset, item.Tag));

            // UR - URL
            case "UR":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // US - Unsigned Short
            case "US":
                return(GetValueFromDatasetWithMultiplicity <ushort>(dataset, item.Tag));

            // UT - Unlimited Text
            case "UT":
                return(GetValueFromDatasetWithMultiplicity <string>(dataset, item.Tag));

            // NONE
            case "NONE":
                return(GetValueFromDatasetWithMultiplicity <object>(dataset, item.Tag));

            default:
                //return GetValueFromDatasetWithMultiplicity<object>(dataset, item.Tag);
                throw new Exception("Unknown VR code: " +
                                    item.ValueRepresentation.Code +
                                    "(" + item.ValueRepresentation.Name + ")");
            }
        }
		private static void ProcessOverlays(DicomDataset input, DicomDataset output) {
			DicomOverlayData[] overlays = null;
			if (input.InternalTransferSyntax.IsEncapsulated)
				overlays = DicomOverlayData.FromDataset(output);
			else
				overlays = DicomOverlayData.FromDataset(input);

			foreach (var overlay in overlays) {
				var dataTag = new DicomTag(overlay.Group, DicomTag.OverlayData.Element);

				// don't run conversion on non-embedded overlays
				if (output.Contains(dataTag))
					continue;

				output.Add(new DicomTag(overlay.Group, DicomTag.OverlayBitsAllocated.Element), (ushort)1);
				output.Add(new DicomTag(overlay.Group, DicomTag.OverlayBitPosition.Element), (ushort)0);

				var data = overlay.Data;
				if (output.InternalTransferSyntax.IsExplicitVR)
					output.Add(new DicomOtherByte(dataTag, data));
				else
					output.Add(new DicomOtherWord(dataTag, data));
			}
		}
Пример #33
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				dataset.Add(_tag, value.ToLower());
			}
		}
Пример #34
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				string[] parts = value.Split(_seperators);
				value = String.Format(_format, parts);
				dataset.Add(_tag, value);
			}
		}
Пример #35
0
		private void Load(DicomDataset ds) {
			_rows = ds.Get<ushort>(OverlayTag(DicomTag.OverlayRows));
			_columns = ds.Get<ushort>(OverlayTag(DicomTag.OverlayColumns));
			
			var type = ds.Get<string>(OverlayTag(DicomTag.OverlayType), "Unknown");
			if (type.StartsWith("R"))
				_type = DicomOverlayType.ROI;
			else
				_type = DicomOverlayType.Graphics;

			DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);
			if (ds.Contains(tag)) {
				_originX = ds.Get<short>(tag, 0, 1);
				_originY = ds.Get<short>(tag, 1, 1);
			}

			_bitsAllocated = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
			_bitPosition = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

			tag = OverlayTag(DicomTag.OverlayData);
			if (ds.Contains(tag)) {
				var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
				_data = elem.Buffer;
			} else {
				// overlay embedded in high bits of pixel data
				if (ds.InternalTransferSyntax.IsEncapsulated)
					throw new DicomImagingException("Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation.");

				var pixels = DicomPixelData.Create(ds);

				// (1,1) indicates top left pixel of image
				int ox = Math.Max(0, _originX - 1);
				int oy = Math.Max(0, _originY - 1);
				int ow = Math.Min(_rows, pixels.Width - _rows - ox);
				int oh = Math.Min(_columns, pixels.Height - _columns - oy);

				var frame = pixels.GetFrame(0);

				// calculate length of output buffer
				var count = (_rows * _columns) / 8;
				if (((_rows * _columns) % 8) != 0)
					count++;
				if ((count & 1) != 0)
					count++;

				var bytes = new byte[count];
				var bits = new BitArray(bytes);
				int mask = 1 << _bitPosition;

				if (pixels.BitsAllocated == 8) {
					var data = ByteBufferEnumerator<byte>.Create(frame).ToArray();

					for (int y = oy; y < oh; y++) {
						int n = (y * pixels.Width) + ox;
						int i = (y - oy) * _columns;
						for (int x = ox; x < ow; x++) {
							if ((data[n] & mask) != 0)
								bits[i] = true;
							n++;
							i++;
						}
					}
				} else if (pixels.BitsAllocated == 16) {
					// we don't really care if the pixel data is signed or not
					var data = ByteBufferEnumerator<ushort>.Create(frame).ToArray();

					for (int y = oy; y < oh; y++) {
						int n = (y * pixels.Width) + ox;
						int i = (y - oy) * _columns;
						for (int x = ox; x < ow; x++) {
							if ((data[n] & mask) != 0)
								bits[i] = true;
							n++;
							i++;
						}
					}
				} else {
					throw new DicomImagingException("Unable to extract embedded overlay from pixel data with bits stored greater than 16.");
				}

				_data = new MemoryByteBuffer(bytes);
			}

			_description = ds.Get<string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
			_subtype = ds.Get<string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
			_label = ds.Get<string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

			_frames = ds.Get<int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
			_frameOrigin = ds.Get<ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

			//TODO: include ROI
		}
Пример #36
0
        public static List <DicomDataset> QueryWorklistItems(DicomDataset request)
        {
            if (_isRealTime)
            {
                //记录查询时间
                System.Diagnostics.Stopwatch stopWatch1 = new System.Diagnostics.Stopwatch();
                stopWatch1.Start();
                DateTime dtRequestBeg = DateTime.Now;
                Logger.Info($">>QueryWorklistItems CreateWorklistQuery BeginTime: {dtRequestBeg.ToString("yyyy-MM-dd HH:mm:ss")}");
                Log.Loger($">>QueryWorklistItems CreateWorklistQuery BeginTime: {dtRequestBeg.ToString("yyyy-MM-dd HH:mm:ss")}");

                DateTime endDate   = System.DateTime.Today.AddDays(1).AddSeconds(-1);
                DateTime startDate = endDate.AddDays(_cacheDays * -1);
                string   patientId = string.Empty;

                if (!request.TryGetSingleValue(DicomTag.PatientID, out patientId))
                {
                    patientId = null;
                }
                if (request.Contains(DicomTag.ScheduledProcedureStepSequence))
                {
                    DicomDataset procedureStep = request.GetSequence(DicomTag.ScheduledProcedureStepSequence).First();

                    var scheduledProcedureStepStartDate = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepStartDate, string.Empty);
                    var scheduledProcedureStepEndDate   = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepEndDate, string.Empty);
                    Logger.Info($"Exam scheduledProcedureStepStartDate: {scheduledProcedureStepStartDate}");
                    Log.Loger($"Exam scheduledProcedureStepStartDate: {scheduledProcedureStepStartDate}");
                    Logger.Info($"Exam scheduledProcedureStepEndDate: {scheduledProcedureStepEndDate}");
                    Log.Loger($"Exam scheduledProcedureStepEndDate: {scheduledProcedureStepEndDate}");

                    var index = scheduledProcedureStepStartDate.IndexOf("-");
                    if (index >= 0)
                    {
                        scheduledProcedureStepEndDate = scheduledProcedureStepStartDate.Substring(index + 1);
                        Logger.Info($"Exam New scheduledProcedureStepEndDate: {scheduledProcedureStepEndDate}");
                        Log.Loger($"Exam New scheduledProcedureStepEndDate: {scheduledProcedureStepEndDate}");

                        scheduledProcedureStepStartDate = scheduledProcedureStepStartDate.Substring(0, index);
                        Logger.Info($"Exam New scheduledProcedureStepStartDate: {scheduledProcedureStepStartDate}");
                        Log.Loger($"Exam New scheduledProcedureStepStartDate: {scheduledProcedureStepStartDate}");
                    }
                    scheduledProcedureStepStartDate = scheduledProcedureStepStartDate.Replace(":", "").Replace(" ", "");
                    scheduledProcedureStepEndDate   = scheduledProcedureStepEndDate.Replace(":", "").Replace(" ", "");

                    if (!string.IsNullOrEmpty(scheduledProcedureStepStartDate) && scheduledProcedureStepStartDate != "*")
                    {
                        startDate = new DicomDateTime(DicomTag.ScheduledProcedureStepStartDate, scheduledProcedureStepStartDate).Get <System.DateTime>();
                    }
                    if (!string.IsNullOrEmpty(scheduledProcedureStepEndDate) && scheduledProcedureStepEndDate != "*")
                    {
                        endDate = new DicomDateTime(DicomTag.ScheduledProcedureStepStartDate, scheduledProcedureStepEndDate).Get <System.DateTime>();
                    }
                }

                DicomDateRange dr    = new DicomDateRange(startDate, endDate);
                var            cfind = DicomCFindRequest.CreateWorklistQuery(patientId, null, null, null, null, dr);

                //记录查询时间
                DateTime dtRequestEnd = DateTime.Now;
                Logger.Info($">>CreateWorklistQuery EndTime: {dtRequestEnd.ToString("yyyy-MM-dd HH:mm:ss")}");
                Log.Loger($">>CreateWorklistQuery EndTime: {dtRequestEnd.ToString("yyyy-MM-dd HH:mm:ss")}");
                stopWatch1.Stop();
                Logger.Info($">>CreateWorklistQuery SpentTime: {stopWatch1.Elapsed.TotalSeconds}");
                Log.Loger($">>CreateWorklistQuery SpentTime: {stopWatch1.Elapsed.TotalSeconds}");
                Log.Loger($"\r\n");

                var newWorklistItems = GetWorkList(cfind);
                Logger.Info($"Get new work list, length: {newWorklistItems.Count}");
                Log.Loger($"Get new work list, length: {newWorklistItems.Count}");
                return(newWorklistItems);
            }
            else
            {
                if (CurrentWorklistItems != null && CurrentWorklistItems.Count == 0)
                {
                    var newWorklistItems = GetCachedWorklist();
                    Logger.Info($"Get new work list, length: {newWorklistItems.Count}");
                    Log.Loger($"Get new work list, length: {newWorklistItems.Count}");
                    CurrentWorklistItems = newWorklistItems;
                }
                return(CurrentWorklistItems);
            }
        }
Пример #37
0
 public void Contains_SamePrivateTagsDifferentPrivateCreator_ReturnsTrue()
 {
     var dataset = new DicomDataset { new DicomUnknown(new DicomTag(0x3005, 0x3025, "PRIVATE")) };
     Assert.True(dataset.Contains(new DicomTag(0x3005, 0x1525, "PRIVATE")));
 }
Пример #38
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				if (_position == DicomTrimPosition.Both) {
					if (_trim != null)
						value = value.Trim(_trim);
					else
						value = value.Trim();
				} else if (_position == DicomTrimPosition.Start) {
					if (_trim != null)
						value = value.TrimStart(_trim);
					else
						value = value.TrimStart();
				} else {
					if (_trim != null)
						value = value.TrimEnd(_trim);
					else
						value = value.TrimEnd();
				}
				dataset.Add(_tag, value);
			}
		}
Пример #39
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				value = Regex.Replace(value, _pattern, _replacement);
				dataset.Add(_tag, value);
			}
		}
Пример #40
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				if (_totalLength < 0)
					value = value.PadLeft(-_totalLength, _paddingChar);
				else
					value = value.PadRight(_totalLength, _paddingChar);
				dataset.Add(_tag, value);
			}
		}
Пример #41
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_src)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _dst);
				dataset.Add(_dst, dataset.Get<IByteBuffer>(_src));
			}
		}
Пример #42
0
		public void Transform(DicomDataset dataset, DicomDataset modifiedAttributesSequenceItem = null) {
			if (dataset.Contains(_tag)) {
				dataset.CopyTo(modifiedAttributesSequenceItem, _tag);
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				if (_position == DicomTrimPosition.Start || _position == DicomTrimPosition.Both)
					while (value.StartsWith(_trim))
						value = value.Substring(_trim.Length);
				if (_position == DicomTrimPosition.End || _position == DicomTrimPosition.Both)
					while (value.EndsWith(_trim))
						value = value.Substring(0, value.Length - _trim.Length);
				dataset.Add(_tag, value);
			}
		}
Пример #43
0
		private DicomDirectoryRecord CreateRecordSequenceItem(DicomDirectoryRecordType recordType, DicomDataset dataset) {
			if (recordType == null)
				throw new ArgumentNullException("recordType");
			if (dataset == null)
				throw new ArgumentNullException("dataset");

			var sequenceItem = new DicomDirectoryRecord();

			//add record item attributes
			sequenceItem.Add<uint>(DicomTag.OffsetOfTheNextDirectoryRecord, 0);
			sequenceItem.Add<ushort>(DicomTag.RecordInUseFlag, 0xFFFF);
			sequenceItem.Add<uint>(DicomTag.OffsetOfReferencedLowerLevelDirectoryEntity, 0);
			sequenceItem.Add<string>(DicomTag.DirectoryRecordType, recordType.ToString());

			//copy the current dataset character set
			sequenceItem.Add(dataset.FirstOrDefault(d => d.Tag == DicomTag.SpecificCharacterSet));

			foreach (var tag in recordType.Tags) {
				if (dataset.Contains(tag)) {
					sequenceItem.Add(dataset.Get<DicomItem>(tag));
				} else {
					System.Diagnostics.Debug.WriteLine("Cannot find tag {0} for record type {1}", tag, recordType);
				}
			}

			return sequenceItem;
		}
Пример #44
0
		public bool Match(DicomDataset dataset) {
			return dataset.Contains(_tag);
		}
        public static IEnumerable <string> Compare(DicomDataset a, DicomDataset b, bool ignoreTrailingNull = false)
        {
            if (a == null || b == null)
            {
                throw new ArgumentException("Dataset " + (a == null ? "A" : "B") + " was null");
            }

            var differences = new List <string>();

            if (!a.Any())
            {
                if (!b.Any())
                {
                    return(differences);
                }

                differences.Add("A contained no elements, but B did");
                return(differences);
            }

            if (!b.Any())
            {
                differences.Add("B contained no elements, but A did");
                return(differences);
            }

            if (a.Count() != b.Count())
            {
                differences.Add("A and B did not contain the same number of elements");
            }

            foreach (DicomItem item in a)
            {
                if (!b.Contains(item.Tag))
                {
                    differences.Add($"B did not contain tag {item.Tag} {item.Tag.DictionaryEntry.Keyword} from A");
                    continue;
                }

                if (item.ValueRepresentation.IsString)
                {
                    string before = a.GetString(item.Tag);
                    string after  = b.GetString(item.Tag);

                    if (string.Equals(before, after))
                    {
                        continue;
                    }

                    if (ignoreTrailingNull && Math.Abs(before.Length - after.Length) == 1)
                    {
                        string longest = before.Length > after.Length ? before : after;

                        // Check for a single trailing NUL character (int value == 0)
                        if (longest[longest.Length - 1] == 0)
                        {
                            continue;
                        }
                    }

                    differences.Add(string.Format("Tag {0} {1} {2} had value \"{3}\" in A and \"{4}\" in B",
                                                  item.Tag, item.ValueRepresentation, item.Tag.DictionaryEntry.Keyword, before, after));
                }
                else if (item.ValueRepresentation == DicomVR.SQ)
                {
                    DicomSequence seqA = a.GetSequence(item.Tag);
                    DicomSequence seqB = b.GetSequence(item.Tag);

                    if (seqA.Count() != seqB.Count())
                    {
                        differences.Add(string.Format("Sequence of tag {0} {1} had {2} elements in A, but {3} in B",
                                                      item.Tag, item.Tag.DictionaryEntry.Keyword, seqA.Count(), seqB.Count()));
                        continue;
                    }

                    for (var i = 0; i < seqA.Count(); ++i)
                    {
                        differences.AddRange(Compare(seqA.Items[i], seqB.Items[i]));
                    }
                }
                else
                {
                    object[] valA = a.GetValues <object>(item.Tag);
                    object[] valB = b.GetValues <object>(item.Tag);

                    if (!(valA.Any() || valB.Any()))
                    {
                        continue;
                    }

                    if (valA.Length != valB.Length)
                    {
                        differences.Add(string.Format("Tag {0} {1} {2} had {3} values in A and {4} values in B",
                                                      item.Tag, item.ValueRepresentation, item.Tag.DictionaryEntry.Keyword, valA.Length, valB.Length));
                    }

                    List <object> diffs = valA.Except(valB).ToList();

                    if (!diffs.Any())
                    {
                        continue;
                    }

                    differences.Add("\tDifferent values were: " + string.Join(", ", diffs));
                }
            }

            return(differences);
        }
Пример #46
0
		public bool Match(DicomDataset dataset) {
			if (dataset.Contains(_tag)) {
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				return value.EndsWith(_value);
			}
			return false;
		}
Пример #47
0
        private void PopulateInstance(DicomMessageBase request,
                                      DicomMessageBase response, IEnumerable <DicomTag> tagList,
                                      DicomDataset sourceDataSet)
        {
            DicomDataset dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");


            var characterSet = GetPreferredCharacterSet();

            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }
            else if (sourceDataSet.Contains(DicomTags.SpecificCharacterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(sourceDataSet[DicomTags.SpecificCharacterSet].ToString());
                dataSet.SpecificCharacterSet = sourceDataSet[DicomTags.SpecificCharacterSet].ToString(); // this will ensure the data is encoded using the specified character set
            }

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                    case DicomTags.PatientId:
                        dataSet[DicomTags.PatientId].SetStringValue(request.DataSet[DicomTags.PatientId].ToString());
                        break;

                    case DicomTags.StudyInstanceUid:
                        dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                            request.DataSet[DicomTags.StudyInstanceUid].ToString());
                        break;

                    case DicomTags.SeriesInstanceUid:
                        dataSet[DicomTags.SeriesInstanceUid].SetStringValue(
                            request.DataSet[DicomTags.SeriesInstanceUid].ToString());
                        break;

                    case DicomTags.QueryRetrieveLevel:
                        dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                        break;

                    default:
                        if (sourceDataSet.Contains(tag))
                        {
                            dataSet[tag] = sourceDataSet[tag].Copy();
                        }
                        else if (!tag.IsPrivate)
                        {
                            dataSet[tag].SetNullValue();
                        }
                        break;

                    // Meta tags that should have not been in the RQ, but we've already set
                    case DicomTags.RetrieveAeTitle:
                    case DicomTags.InstanceAvailability:
                    case DicomTags.SpecificCharacterSet:
                        break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());

                    if (!tag.IsPrivate)
                    {
                        dataSet[tag].SetNullValue();
                    }
                }
            }
        }
Пример #48
0
		public bool Match(DicomDataset dataset) {
			if (dataset.Contains(_tag)) {
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				return _regex.IsMatch(value);
			}
			return false;
		}
Пример #49
0
        /// <summary>
        /// Create image rendering pipeline according to the <see cref="DicomPixelData.PhotometricInterpretation">photometric interpretation</see>
        /// of the pixel data.
        /// </summary>
        private static PipelineData CreatePipelineData(DicomDataset dataset, DicomPixelData pixelData)
        {
            var pi      = pixelData.PhotometricInterpretation;
            var samples = dataset.GetSingleValueOrDefault(DicomTag.SamplesPerPixel, (ushort)0);

            // temporary fix for JPEG compressed YBR images
            if ((dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess1 ||
                 dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess2_4) && samples == 3)
            {
                pi = PhotometricInterpretation.Rgb;
            }

            // temporary fix for JPEG 2000 Lossy images
            if (pi == PhotometricInterpretation.YbrIct || pi == PhotometricInterpretation.YbrRct)
            {
                pi = PhotometricInterpretation.Rgb;
            }

            if (pi == null)
            {
                // generally ACR-NEMA
                if (samples == 0 || samples == 1)
                {
                    pi = dataset.Contains(DicomTag.RedPaletteColorLookupTableData)
                        ? PhotometricInterpretation.PaletteColor
                        : PhotometricInterpretation.Monochrome2;
                }
                else
                {
                    // assume, probably incorrectly, that the image is RGB
                    pi = PhotometricInterpretation.Rgb;
                }
            }

            IPipeline pipeline;
            GrayscaleRenderOptions renderOptions = null;

            if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2)
            {
                //Monochrome1 or Monochrome2 for grayscale image
                renderOptions = GrayscaleRenderOptions.FromDataset(dataset);
                pipeline      = new GenericGrayscalePipeline(renderOptions);
            }
            else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull ||
                     pi == PhotometricInterpretation.YbrFull422 || pi == PhotometricInterpretation.YbrPartial422)
            {
                //RGB for color image
                pipeline = new RgbColorPipeline();
            }
            else if (pi == PhotometricInterpretation.PaletteColor)
            {
                //PALETTE COLOR for Palette image
                pipeline = new PaletteColorPipeline(pixelData);
            }
            else
            {
                throw new DicomImagingException("Unsupported pipeline photometric interpretation: {0}", pi);
            }

            return(new PipelineData {
                Pipeline = pipeline, RenderOptions = renderOptions
            });
        }
Пример #50
0
        private static void ProcessOverlays(DicomDataset input, DicomDataset output)
        {
            var overlays = DicomOverlayData.FromDataset(input.InternalTransferSyntax.IsEncapsulated ? output : input);

            foreach (var overlay in overlays)
            {
                var dataTag = new DicomTag(overlay.Group, DicomTag.OverlayData.Element);

                // Don't run conversion on non-embedded overlays.
                if (output.Contains(dataTag)) continue;

                // If embedded overlay, Overlay Bits Allocated should equal Bits Allocated (#110).
                var bitsAlloc = output.Get(DicomTag.BitsAllocated, (ushort)0);
                output.AddOrUpdate(new DicomTag(overlay.Group, DicomTag.OverlayBitsAllocated.Element), bitsAlloc);

                var data = overlay.Data;
                if (output.InternalTransferSyntax.IsExplicitVR) output.AddOrUpdate(new DicomOtherByte(dataTag, data));
                else output.AddOrUpdate(new DicomOtherWord(dataTag, data));
            }
        }
Пример #51
0
		public bool Match(DicomDataset dataset) {
			if (dataset.Contains(_tag)) {
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				return String.IsNullOrEmpty(value);
			}
			return true;
		}
Пример #52
0
        public static IEnumerable <DicomDataset> FilterWorklistItems(DicomDataset request, List <WorklistItem> allWorklistItems)
        {
            var exams = allWorklistItems.AsQueryable();

            if (request.TryGetSingleValue(DicomTag.PatientID, out string patientId))
            {
                exams = exams.Where(x => x.PatientID.Equals(patientId));
            }

            var patientName = request.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);

            if (!string.IsNullOrEmpty(patientName))
            {
                exams = AddNameCondition(exams, patientName);
            }

            DicomDataset procedureStep = null;

            if (request.Contains(DicomTag.ScheduledProcedureStepSequence))
            {
                procedureStep = request.GetSequence(DicomTag.ScheduledProcedureStepSequence).First();

                // Required Matching keys
                var scheduledStationAET = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledStationAETitle, string.Empty);
                if (!string.IsNullOrEmpty(scheduledStationAET))
                {
                    exams = exams.Where(x => x.ScheduledAET == scheduledStationAET);
                }

                var performingPhysician = procedureStep.GetSingleValueOrDefault(DicomTag.PerformingPhysicianName, string.Empty);
                if (!string.IsNullOrEmpty(performingPhysician))
                {
                    exams = exams.Where(x => x.PerformingPhysician == performingPhysician);
                }

                var modality = procedureStep.GetSingleValueOrDefault(DicomTag.Modality, string.Empty);
                if (!string.IsNullOrEmpty(modality))
                {
                    exams = exams.Where(x => x.Modality == modality);
                }

                // if only date is specified, then using standard matching
                // but if both are specified, then MWL defines a combined match
                var scheduledProcedureStepStartDateTime = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepStartDateTime, string.Empty);
                if (!string.IsNullOrEmpty(scheduledProcedureStepStartDateTime))
                {
                    exams = AddDateCondition(exams, scheduledProcedureStepStartDateTime);
                }

                // Optional (but commonly used) matching keys.
                var procedureStepLocation = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepLocation, string.Empty);
                if (!string.IsNullOrEmpty(procedureStepLocation))
                {
                    exams = exams.Where(x => x.ExamRoom.Equals(procedureStepLocation));
                }

                var procedureDescription = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepDescription, string.Empty);
                if (!string.IsNullOrEmpty(procedureDescription))
                {
                    exams = exams.Where(x => x.ExamDescription.Equals(procedureDescription));
                }
            }

            var results = exams.ToList();

            //  Parsing result
            foreach (var result in results)
            {
                var resultingSPS         = new DicomDataset();
                var resultDataset        = new DicomDataset();
                var resultingSPSSequence = new DicomSequence(DicomTag.ScheduledProcedureStepSequence, resultingSPS);

                if (procedureStep != null)
                {
                    resultDataset.Add(resultingSPSSequence);
                }

                // add results to "main" dataset
                AddIfExistsInRequest(resultDataset, request, DicomTag.AccessionNumber, result.AccessionNumber);                                   // T2
                AddIfExistsInRequest(resultDataset, request, DicomTag.InstitutionName, result.HospitalName);
                AddIfExistsInRequest(resultDataset, request, DicomTag.ReferringPhysicianName, result.ReferringPhysician);                         // T2

                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientName, result.Surname + "^" + result.Forename + "^^" + result.Title); //T1
                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientID, result.PatientID);                                               // T1
                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientBirthDate, result.DateOfBirth);                                      // T2
                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientSex, result.Sex);                                                    //T2

                AddIfExistsInRequest(resultDataset, request, DicomTag.StudyInstanceUID, result.StudyUID);                                         // T1

                AddIfExistsInRequest(resultDataset, request, DicomTag.RequestingPhysician, result.ReferringPhysician);                            //T2
                AddIfExistsInRequest(resultDataset, request, DicomTag.RequestedProcedureDescription, result.ExamDescription);                     //T1C

                AddIfExistsInRequest(resultDataset, request, DicomTag.RequestedProcedureID, result.ProcedureID);                                  // T1

                // Scheduled Procedure Step sequence T1
                // add results to procedure step dataset
                // Return if requested
                if (procedureStep != null)
                {
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledStationAETitle, result.ScheduledAET);                 // T1
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepStartDate, result.ExamDateAndTime);      //T1
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepStartTime, result.ExamDateAndTime);      //T1
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.Modality, result.Modality);                                    // T1

                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledPerformingPhysicianName, result.PerformingPhysician); //T2
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepDescription, result.ExamDescription);    // T1C
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepID, result.ProcedureStepID);             // T1
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledStationName, result.ExamRoom);                        //T2
                    AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepLocation, result.ExamRoom);              //T2
                }

                // Put blanks in for unsupported fields which are type 2 (i.e. must have a value even if NULL)
                // In a real server, you may wish to support some or all of these, but they are not commonly supported
                AddIfExistsInRequest(resultDataset, request, DicomTag.ReferencedStudySequence, new DicomDataset());           // Ref//d Study Sequence
                AddIfExistsInRequest(resultDataset, request, DicomTag.Priority, "");                                          // Priority
                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientTransportArrangements, "");                      // Transport Arrangements
                AddIfExistsInRequest(resultDataset, request, DicomTag.AdmissionID, "");                                       // Admission ID
                AddIfExistsInRequest(resultDataset, request, DicomTag.CurrentPatientLocation, "");                            // Patient Location
                AddIfExistsInRequest(resultDataset, request, DicomTag.ReferencedPatientSequence, new DicomDataset());         // Ref//d Patient Sequence
                AddIfExistsInRequest(resultDataset, request, DicomTag.PatientWeight, "");                                     // Weight
                AddIfExistsInRequest(resultDataset, request, DicomTag.ConfidentialityConstraintOnPatientDataDescription, ""); // Confidentiality Constraint

                // Send Reponse Back
                yield return(resultDataset);
            }
        }
Пример #53
0
		public bool Match(DicomDataset dataset) {
			if (dataset.Contains(_tag)) {
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				return value.Wildcard(_pattern);
			}
			return false;
		}
Пример #54
0
        private void Load(DicomDataset ds)
        {
            _rows = ds.Get<ushort>(OverlayTag(DicomTag.OverlayRows));
            _columns = ds.Get<ushort>(OverlayTag(DicomTag.OverlayColumns));
            _type = ds.Get<string>(OverlayTag(DicomTag.OverlayType), "Unknown");

            DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);
            if (ds.Contains(tag)) {
                short[] xy = ds.Get<short[]>(tag);
                if (xy != null && xy.Length == 2) {
                    _originX = xy[0];
                    _originY = xy[1];
                }
            }

            _bitsAllocated = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
            _bitPosition = ds.Get<ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

            tag = OverlayTag(DicomTag.OverlayData);
            if (ds.Contains(tag)) {
                var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
                _data = elem.Buffer;
            }

            _description = ds.Get<string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
            _subtype = ds.Get<string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
            _label = ds.Get<string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

            _frames = ds.Get<int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
            _frameOrigin = ds.Get<ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

            //TODO: include ROI
        }
Пример #55
0
		public bool Match(DicomDataset dataset) {
			if (dataset.Contains(_tag)) {
				var value = dataset.Get<string>(_tag, -1, String.Empty);
				foreach (string v in _values)
					if (v == value)
						return true;
			}
			return false;
		}
Пример #56
0
        private void Load(DicomDataset ds)
        {
            _rows    = ds.Get <ushort>(OverlayTag(DicomTag.OverlayRows));
            _columns = ds.Get <ushort>(OverlayTag(DicomTag.OverlayColumns));

            var type = ds.Get <string>(OverlayTag(DicomTag.OverlayType), "Unknown");

            if (type.StartsWith("R"))
            {
                _type = DicomOverlayType.ROI;
            }
            else
            {
                _type = DicomOverlayType.Graphics;
            }

            DicomTag tag = OverlayTag(DicomTag.OverlayOrigin);

            if (ds.Contains(tag))
            {
                _originX = ds.Get <short>(tag, 0, 1);
                _originY = ds.Get <short>(tag, 1, 1);
            }

            _bitsAllocated = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitsAllocated), 0, 1);
            _bitPosition   = ds.Get <ushort>(OverlayTag(DicomTag.OverlayBitPosition), 0, 0);

            tag = OverlayTag(DicomTag.OverlayData);
            if (ds.Contains(tag))
            {
                var elem = ds.FirstOrDefault(x => x.Tag == tag) as DicomElement;
                _data = elem.Buffer;
            }
            else
            {
                // overlay embedded in high bits of pixel data
                if (ds.InternalTransferSyntax.IsEncapsulated)
                {
                    throw new DicomImagingException("Attempted to extract embedded overlay from compressed pixel data. Decompress pixel data before attempting this operation.");
                }

                var pixels = DicomPixelData.Create(ds);

                // (1,1) indicates top left pixel of image
                int ox = Math.Max(0, _originX - 1);
                int oy = Math.Max(0, _originY - 1);
                int ow = _rows - (pixels.Width - _rows - ox);
                int oh = _columns - (pixels.Height - _columns - oy);

                var frame = pixels.GetFrame(0);

                // calculate length of output buffer
                var count = (_rows * _columns) / 8;
                if (((_rows * _columns) % 8) != 0)
                {
                    count++;
                }
                if ((count & 1) != 0)
                {
                    count++;
                }

                var bytes = new byte[count];
                var bits  = new BitArray(bytes);
                int mask  = 1 << _bitPosition;

                if (pixels.BitsAllocated == 8)
                {
                    var data = ByteBufferEnumerator <byte> .Create(frame).ToArray();

                    for (int y = oy; y < oh; y++)
                    {
                        int n = (y * pixels.Width) + ox;
                        int i = (y - oy) * _columns;
                        for (int x = ox; x < ow; x++)
                        {
                            if ((data[n] & mask) != 0)
                            {
                                bits[i] = true;
                            }
                            n++;
                            i++;
                        }
                    }
                }
                else if (pixels.BitsAllocated == 16)
                {
                    // we don't really care if the pixel data is signed or not
                    var data = ByteBufferEnumerator <ushort> .Create(frame).ToArray();

                    for (int y = oy; y < oh; y++)
                    {
                        int n = (y * pixels.Width) + ox;
                        int i = (y - oy) * _columns;
                        for (int x = ox; x < ow; x++)
                        {
                            if ((data[n] & mask) != 0)
                            {
                                bits[i] = true;
                            }
                            n++;
                            i++;
                        }
                    }
                }
                else
                {
                    throw new DicomImagingException("Unable to extract embedded overlay from pixel data with bits stored greater than 16.");
                }

                _data = new MemoryByteBuffer(bytes);
            }

            _description = ds.Get <string>(OverlayTag(DicomTag.OverlayDescription), String.Empty);
            _subtype     = ds.Get <string>(OverlayTag(DicomTag.OverlaySubtype), String.Empty);
            _label       = ds.Get <string>(OverlayTag(DicomTag.OverlayLabel), String.Empty);

            _frames      = ds.Get <int>(OverlayTag(DicomTag.NumberOfFramesInOverlay), 0, 1);
            _frameOrigin = ds.Get <ushort>(OverlayTag(DicomTag.ImageFrameOrigin), 0, 1);

            //TODO: include ROI
        }
Пример #57
0
        public static bool HasEmbeddedOverlays(DicomDataset ds)
        {
            var groups = new List<ushort>();
            groups.AddRange(
                ds.Where(x => x.Tag.Group >= 0x6000 && x.Tag.Group <= 0x60FF && x.Tag.Element == 0x0010)
                    .Select(x => x.Tag.Group));

            foreach (var group in groups)
            {
                if (!ds.Contains(new DicomTag(group, DicomTag.OverlayData.Element))) return true;
            }

            return false;
        }
Пример #58
0
        /// <summary>
        /// Update an <see cref="DicomDataset"/> with pixel data related tags.
        /// </summary>
        /// <param name="dataset">The collection to update.</param>
        public override void UpdateAttributeCollection(DicomDataset dataset)
        {
            if (dataset.Contains(DicomTags.NumberOfFrames) || NumberOfFrames > 1)
            {
                dataset[DicomTags.NumberOfFrames].SetInt32(0, NumberOfFrames);
            }
            if (dataset.Contains(DicomTags.PlanarConfiguration))
            {
                dataset[DicomTags.PlanarConfiguration].SetInt32(0, PlanarConfiguration);
            }
            if (dataset.Contains(DicomTags.LossyImageCompression) || LossyImageCompression.Length > 0)
            {
                dataset[DicomTags.LossyImageCompression].SetString(0, LossyImageCompression);
            }
            if (dataset.Contains(DicomTags.LossyImageCompressionRatio) || (LossyImageCompressionRatio != 1.0f && LossyImageCompressionRatio != 0.0f))
            {
                dataset[DicomTags.LossyImageCompressionRatio].SetFloat32(0, LossyImageCompressionRatio);
            }
            if (dataset.Contains(DicomTags.LossyImageCompressionMethod) || LossyImageCompressionMethod.Length > 0)
            {
                dataset[DicomTags.LossyImageCompressionMethod].SetString(0, LossyImageCompressionMethod);
            }
            if (dataset.Contains(DicomTags.DerivationDescription) || DerivationDescription.Length > 0)
            {
                string currentValue = dataset[DicomTags.DerivationDescription].ToString();

                dataset[DicomTags.DerivationDescription].SetStringValue(DerivationDescription);
                if (!currentValue.Equals(DerivationDescription))
                {
                    DicomSequenceItem item  = new DicomSequenceItem();
                    CodeSequenceMacro macro = new CodeSequenceMacro(item);
                    macro.CodeMeaning            = "Lossy Compression";
                    macro.CodeValue              = "113040";
                    macro.CodingSchemeDesignator = "DCM";
                    macro.ContextGroupVersion    = new DateTime(2005, 8, 22);
                    macro.ContextIdentifier      = "7203";
                    macro.MappingResource        = "DCMR";

                    dataset[DicomTags.DerivationCodeSequence].AddSequenceItem(item);
                }
            }
            if (dataset.Contains(DicomTags.RescaleSlope) || DecimalRescaleSlope != 1.0M || DecimalRescaleIntercept != 0.0M)
            {
                dataset[DicomTags.RescaleSlope].SetString(0, RescaleSlope);
            }
            if (dataset.Contains(DicomTags.RescaleIntercept) || DecimalRescaleSlope != 1.0M || DecimalRescaleIntercept != 0.0M)
            {
                dataset[DicomTags.RescaleIntercept].SetString(0, RescaleIntercept);
            }

            if (dataset.Contains(DicomTags.WindowCenter) || LinearVoiLuts.Count > 0)
            {
                Window.SetWindowCenterAndWidth(dataset, LinearVoiLuts);
            }

            //Remove the palette color lut, if the pixels were translated to RGB
            if (dataset.Contains(DicomTags.RedPaletteColorLookupTableData) &&
                dataset.Contains(DicomTags.BluePaletteColorLookupTableData) &&
                dataset.Contains(DicomTags.GreenPaletteColorLookupTableData) &&
                !HasPaletteColorLut)
            {
                dataset.RemoveElement(DicomTags.BluePaletteColorLookupTableDescriptor);
                dataset.RemoveElement(DicomTags.BluePaletteColorLookupTableData);
                dataset.RemoveElement(DicomTags.RedPaletteColorLookupTableDescriptor);
                dataset.RemoveElement(DicomTags.RedPaletteColorLookupTableData);
                dataset.RemoveElement(DicomTags.GreenPaletteColorLookupTableDescriptor);
                dataset.RemoveElement(DicomTags.GreenPaletteColorLookupTableData);
            }

            dataset.SaveDicomFields(this);
            dataset[DicomTags.PixelData] = _sq;
        }
Пример #59
0
        /// <summary>
        /// Create <see cref="GrayscaleRenderOptions"/>  from <paramref name="dataset"/> and populate the options properties with values:
        /// Bit Depth
        /// Rescale Slope
        /// Rescale Intercept
        /// Window Width
        /// Window Center
        /// </summary>
        /// <param name="dataset">Dataset to extract <see cref="GrayscaleRenderOptions"/> from</param>
        /// <returns>New grayscale render options instance</returns>
        public static GrayscaleRenderOptions FromDataset(DicomDataset dataset)
        {
            var bits = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);

            options.RescaleSlope = dataset.Get<double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get<double>(DicomTag.RescaleIntercept, 0.0);

            if (dataset.Contains(DicomTag.WindowWidth) && dataset.Get<double>(DicomTag.WindowWidth) != 0.0) {
                //If dataset contains WindowWidth and WindowCenter valid attributes used initially for the grayscale options
                return FromWindowLevel(dataset);
            } else if (dataset.Contains(DicomTag.SmallestImagePixelValue) && dataset.Contains(DicomTag.LargestImagePixelValue)) {
                //If dataset contains valid SmallesImagePixelValue and LargesImagePixelValue attributes, use range to calculate
                //WindowWidth and WindowCenter
                return FromImagePixelValueTags(dataset);
            } else {
                //If reached here, minimum and maximum pixel values calculated from pixels data to calculate
                //WindowWidth and WindowCenter
                return FromMinMax(dataset);
            }

            options.VOILUTFunction = dataset.Get<string>(DicomTag.VOILUTFunction, "LINEAR");
            options.Monochrome1 = dataset.Get<PhotometricInterpretation>(DicomTag.PhotometricInterpretation) == PhotometricInterpretation.Monochrome1;

            return options;
        }
        /// <summary>
        /// Converts a volume 3D into a collection of Dicom files (split by slice on the primary plane).
        /// This code writes the patient position as HFS (this might not be correct but was needed at some point to view the output).
        ///
        /// Note: This code has not been tested with MR data. It also assumes the Photometric Interpretation to be MONOCHROME2.
        /// Use with extreme care - many Dicom elements have to be halluzinated here, and there's no
        /// guarantee that the resulting Dicom will be usable beyond what is needed in InnerEye.
        /// </summary>
        /// <param name="volume">The volume to convert.</param>
        /// <param name="modality">The image modality.</param>
        /// <param name="seriesDescription">The value to use as the Dicom series description.</param>
        /// <param name="patientID">The patient ID that should be used in the Dicom files. If null,
        /// a randomly generated patient ID will be used.</param>
        /// <param name="studyInstanceID">The study ID that should be used in the Dicom files (DicomTag.StudyInstanceUID). If null,
        /// a randomly generated study ID will be used.</param>
        /// <param name="additionalDicomItems">Additional Dicom items that will be added to each of the slice datasets. This can
        /// be used to pass in additional information like manufacturer.</param>
        /// <returns>The collection of Dicom files that represents the Dicom image series.</returns>
        public static IEnumerable <DicomFile> Convert(Volume3D <short> volume,
                                                      ImageModality modality,
                                                      string seriesDescription          = null,
                                                      string patientID                  = null,
                                                      string studyInstanceID            = null,
                                                      DicomDataset additionalDicomItems = null)
        {
            seriesDescription = seriesDescription ?? string.Empty;
            patientID         = CreateUidIfEmpty(patientID);
            studyInstanceID   = CreateUidIfEmpty(studyInstanceID);

            if (!IsValidDicomLongString(seriesDescription))
            {
                throw new ArgumentException("The series description is not a valid Dicom Long String.", nameof(seriesDescription));
            }

            if (!IsValidDicomLongString(patientID))
            {
                throw new ArgumentException("The patient ID is not a valid Dicom Long String.", nameof(patientID));
            }

            if (!IsValidDicomLongString(studyInstanceID))
            {
                throw new ArgumentException("The study instance ID is not a valid Dicom Long String.", nameof(studyInstanceID));
            }

            var spacingZ = volume.SpacingZ;
            var imageOrientationPatient = new decimal[6];

            var directionColumn1 = volume.Direction.Column(0);
            var directionColumn2 = volume.Direction.Column(1);

            imageOrientationPatient[0] = (decimal)directionColumn1.X;
            imageOrientationPatient[1] = (decimal)directionColumn1.Y;
            imageOrientationPatient[2] = (decimal)directionColumn1.Z;
            imageOrientationPatient[3] = (decimal)directionColumn2.X;
            imageOrientationPatient[4] = (decimal)directionColumn2.Y;
            imageOrientationPatient[5] = (decimal)directionColumn2.Z;

            var frameOfReferenceUID = CreateUID().UID;
            var seriesUID           = CreateUID().UID;
            var sopInstanceUIDs     = new DicomUID[volume.DimZ];

            // DicomUID.Generate() is not thread safe. We must create unique DicomUID's single threaded.
            // https://github.com/fo-dicom/fo-dicom/issues/546
            for (var i = 0; i < sopInstanceUIDs.Length; i++)
            {
                sopInstanceUIDs[i] = CreateUID();
            }

            var results = new DicomFile[volume.DimZ];

            Parallel.For(0, volume.DimZ, i =>
            {
                var sliceLocation        = (i * spacingZ) + volume.Origin.Z;
                var imagePositionPatient = volume.Transform.DataToDicom.Transform(new Point3D(0, 0, i));

                var dataset = new DicomDataset()
                {
                    { DicomTag.ImageType, new[] { "DERIVED", "PRIMARY", "AXIAL" } },
                    { DicomTag.PatientPosition, "HFS" },
                    { new DicomOtherWord(DicomTag.PixelData, new MemoryByteBuffer(ExtractSliceAsByteArray(volume, i))) },
                    { new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, sopInstanceUIDs[i]) },
                    { new DicomUniqueIdentifier(DicomTag.SeriesInstanceUID, seriesUID) },
                    { new DicomUniqueIdentifier(DicomTag.PatientID, patientID) },
                    { new DicomUniqueIdentifier(DicomTag.StudyInstanceUID, studyInstanceID) },
                    { new DicomUniqueIdentifier(DicomTag.FrameOfReferenceUID, frameOfReferenceUID) },
                    { new DicomLongString(DicomTag.SeriesDescription, seriesDescription) },
                    { new DicomUnsignedShort(DicomTag.Columns, (ushort)volume.DimX) },
                    { new DicomUnsignedShort(DicomTag.Rows, (ushort)volume.DimY) },
                    { new DicomDecimalString(DicomTag.PixelSpacing, (decimal)volume.SpacingY, (decimal)volume.SpacingX) }, // Note: Spacing X & Y are not the expected way around
                    { new DicomDecimalString(DicomTag.ImagePositionPatient, (decimal)imagePositionPatient.X, (decimal)imagePositionPatient.Y, (decimal)imagePositionPatient.Z) },
                    { new DicomDecimalString(DicomTag.ImageOrientationPatient, imageOrientationPatient) },
                    { new DicomDecimalString(DicomTag.SliceLocation, (decimal)sliceLocation) },
                    { new DicomUnsignedShort(DicomTag.SamplesPerPixel, DicomSeriesInformationValidator.ExpectedSamplesPerPixel) },
                    { new DicomUnsignedShort(DicomTag.PixelRepresentation, 1) },
                    { new DicomUnsignedShort(DicomTag.BitsStored, DicomSeriesInformationValidator.ExpectedBitsAllocated) },
                    { new DicomUnsignedShort(DicomTag.BitsAllocated, DicomSeriesInformationValidator.ExpectedBitsAllocated) },
                    { new DicomUnsignedShort(DicomTag.HighBit, DicomSeriesInformationValidator.ExpectedBitsAllocated - 1) },
                    { new DicomCodeString(DicomTag.PhotometricInterpretation, DicomSeriesInformationValidator.ExpectedPhotometricInterpretation) }
                };

                if (modality == ImageModality.CT)
                {
                    dataset.Add(DicomTag.SOPClassUID, DicomUID.CTImageStorage);
                    dataset.Add(DicomTag.Modality, ImageModality.CT.ToString());

                    dataset.Add(new DicomItem[]
                    {
                        new DicomDecimalString(DicomTag.RescaleIntercept, 0),
                        new DicomDecimalString(DicomTag.RescaleSlope, 1),
                    });
                }
                else if (modality == ImageModality.MR)
                {
                    dataset.Add(DicomTag.SOPClassUID, DicomUID.MRImageStorage);
                    dataset.Add(DicomTag.Modality, ImageModality.MR.ToString());
                }

                if (additionalDicomItems != null)
                {
                    foreach (var item in additionalDicomItems.Clone())
                    {
                        if (!dataset.Contains(item.Tag))
                        {
                            dataset.Add(item);
                        }
                    }
                }

                results[i] = new DicomFile(dataset);
            });

            return(results);
        }