public void TestAgentCodeSequence()
		{
			var agent1 = new CodeSequenceMacro {CodeMeaning = "Contrastinol", CodeValue = "123", CodingSchemeDesignator = "ABC"};
			var agent2 = new CodeSequenceMacro {CodeMeaning = "Bolusinate", CodeValue = "456", CodingSchemeDesignator = "DEF"};

			var dataset = TestDataSource.CreateImageSopDataSource();
			dataset[DicomTags.ContrastBolusAgent].SetStringValue(@"Contrastinol and Bolusinate");
			dataset[DicomTags.ContrastBolusAgentSequence].AddSequenceItem(agent1.DicomSequenceItem);

			using (var sop = (ImageSop) Sop.Create(dataset))
			using (var images = new DisposableList<IPresentationImage>(PresentationImageFactory.Create(sop)))
			{
				Assert.AreEqual(@"Contrastinol", _annotationItems[_cbAgent].GetAnnotationText(images[0]));

				dataset[DicomTags.ContrastBolusAgentSequence].AddSequenceItem(agent2.DicomSequenceItem);
				Assert.AreEqual(@"Contrastinol\Bolusinate", _annotationItems[_cbAgent].GetAnnotationText(images[0]));

				agent1.CodeMeaning = string.Empty;
				Assert.AreEqual(@"123 (ABC)\Bolusinate", _annotationItems[_cbAgent].GetAnnotationText(images[0]));

				agent2.CodeMeaning = string.Empty;
				Assert.AreEqual(@"Contrastinol and Bolusinate", _annotationItems[_cbAgent].GetAnnotationText(images[0]));

				dataset[DicomTags.ContrastBolusAgent].SetNullValue();
				Assert.AreEqual(@"123 (ABC)\456 (DEF)", _annotationItems[_cbAgent].GetAnnotationText(images[0]));
			}
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Creates the PurposeOfReferenceCodeSequence in the underlying collection. Type 3.
		/// </summary>
		public CodeSequenceMacro CreatePurposeOfReferenceCodeSequence()
		{
			var dicomAttribute = DicomAttributeProvider[DicomTags.PurposeOfReferenceCodeSequence];
			if (dicomAttribute.IsNull || dicomAttribute.IsEmpty)
			{
				var dicomSequenceItem = new DicomSequenceItem();
				dicomAttribute.Values = new[] {dicomSequenceItem};
				var sequenceType = new CodeSequenceMacro(dicomSequenceItem);
				return sequenceType;
			}
			return new CodeSequenceMacro(((DicomSequenceItem[]) dicomAttribute.Values)[0]);
		}
        public DicomFile Serialize(SegmentationSerializerCallback callback)
        {
            Platform.CheckForNullReference(callback, "callback");

            Debug.Assert(!_segDocument.Saved, "Cannot serialize previously saved document");

            // TODO: validate that all Segs are coming from the same study!

            IPresentationImage firstIPresentationImage = null;
            if (_segDocument.Segs != null)
            {
                var oneSeg = _segDocument.Segs.FirstOrDefault(item => item != null && item.SegGraphics != null && item.SegGraphics.OfType<PolygonalRoiSegGraphic>().Any());
                if (oneSeg != null)
                {
                    var polyGraphic = oneSeg.SegGraphics.OfType<PolygonalRoiSegGraphic>().First();
                    firstIPresentationImage = callback(polyGraphic.ImageSopInstanceUid, polyGraphic.ImageFrameNumber);
                }
            }
            var firstImageSopProvider = firstIPresentationImage as IImageSopProvider;
            if (firstImageSopProvider == null)
                return null;

            var sourceSop = firstImageSopProvider.ImageSop; // source of the common DICOM attributes
            var dicomFile = _sopInstanceFactory.CreateFile(sourceSop);

            // NOTE. These modules are initialized by the factory:
            // patient IE
            // - PatientModule
            // - ClinicalTrialSubjectModule
            // study IE
            // - GeneralStudyModule
            // - PatientStudyModule
            // - ClinicalTrialStudyModule
            // equipment IE
            // - GeneralEquipmentModule

            // Data values
            const int instanceNumber = 1;
            var contentDateTime = DateTime.Now;

            var segDocumentIod = new SegmentationDocumentIod(dicomFile.DataSet);

            // PatientModule
            var patientModule = segDocumentIod.PatientModuleIod;
            // patientModule.PatientBreedDescription = null; // bug in CC code
            patientModule.DicomAttributeProvider[DicomTags.PatientBreedDescription].SetEmptyValue();

            // GeneralEquipmentModule
            var generalEquipmentModuleIod = segDocumentIod.GeneralEquipmentModuleIod;
            generalEquipmentModuleIod.DeviceSerialNumber = EnvironmentUtilities.MachineIdentifier;

            // GeneralSeriesModule
            var srcGeneralSeriesModuleIod = new GeneralSeriesModuleIod(sourceSop.DataSource);
            var generalSeriesModuleIod = segDocumentIod.GeneralSeriesModuleIod;
            generalSeriesModuleIod.SeriesDescription = _segDocument.SeriesDescription;
            generalSeriesModuleIod.SeriesNumber = _segDocument.SeriesNumber;
            generalSeriesModuleIod.Modality = Modality.Seg;
            generalSeriesModuleIod.SeriesInstanceUid = DicomUid.GenerateUid().UID;
            generalSeriesModuleIod.Laterality = srcGeneralSeriesModuleIod.Laterality;
            generalSeriesModuleIod.SeriesDateTime = _segDocument.CreationDateTime;
            generalSeriesModuleIod.PerformingPhysiciansName = srcGeneralSeriesModuleIod.PerformingPhysiciansName;
            generalSeriesModuleIod.PerformingPhysicianIdentificationSequence = srcGeneralSeriesModuleIod.PerformingPhysicianIdentificationSequence;
            generalSeriesModuleIod.ProtocolName = srcGeneralSeriesModuleIod.ProtocolName;
            {
                // General Description Code Sequence is missing from the GeneralSeriesModuleIod implementation
                var seriesDescriptionCodeSequence = new CodeSequenceMacro
                    {
                        CodeValue = "113076",
                        CodeMeaning = "Segmentation",
                        CodingSchemeDesignator = "DCM"
                    };
                var result = new[] { seriesDescriptionCodeSequence.DicomSequenceItem };

                generalSeriesModuleIod.DicomAttributeProvider[DicomTags.SeriesDescriptionCodeSequence].Values = result;
            }
            string userDicomName = null;
            if (_segDocument.UserInfo != null && !string.IsNullOrEmpty(_segDocument.UserInfo.Name))
            {
                userDicomName = FormatDicomName(_segDocument.UserInfo.Name);
                if (userDicomName != null)
                    generalSeriesModuleIod.OperatorsName = userDicomName;

                // NOTE: Login name is being ignored for now
            }
            generalSeriesModuleIod.BodyPartExamined = srcGeneralSeriesModuleIod.BodyPartExamined;
            generalSeriesModuleIod.PatientPosition = srcGeneralSeriesModuleIod.PatientPosition;
            generalSeriesModuleIod.RequestAttributesSequence = srcGeneralSeriesModuleIod.RequestAttributesSequence;
            //generalSeriesModuleIod.AnatomicalOrientationType = srcGeneralSeriesModuleIod.AnatomicalOrientationType;  // Not needed

            // FrameOfReferenceModule
            var srcFrameOfReferenceModuleIod = new FrameOfReferenceModuleIod(sourceSop.DataSource);
            segDocumentIod.FrameOfReferenceModuleIod.FrameOfReferenceUid = srcFrameOfReferenceModuleIod.FrameOfReferenceUid;
            segDocumentIod.FrameOfReferenceModuleIod.PositionReferenceIndicator = srcFrameOfReferenceModuleIod.PositionReferenceIndicator;

            // Initialize Segmentation Image Module first
            var segmentationImageModuleIod = segDocumentIod.SegmentationImageModuleIod;
            segmentationImageModuleIod.InitializeAttributes();

            // General Image Module and Segmentation Image Module
            var srcGeneralImageModuleIod = new GeneralImageModuleIod(sourceSop.DataSource);
            var generalImageModuleIod = segDocumentIod.GeneralImageModuleIod;
            generalImageModuleIod.InstanceNumber = instanceNumber;
            generalImageModuleIod.PatientOrientation = srcGeneralImageModuleIod.PatientOrientation;
            generalImageModuleIod.ContentDateTime = contentDateTime;
            generalImageModuleIod.ImageType = "DERIVED\\PRIMARY";
            generalImageModuleIod.AcquisitionNumber = srcGeneralImageModuleIod.AcquisitionNumber;
            generalImageModuleIod.AcquisitionDateTime = srcGeneralImageModuleIod.AcquisitionDateTime;
            generalImageModuleIod.QualityControlImage = srcGeneralImageModuleIod.QualityControlImage;
            generalImageModuleIod.BurnedInAnnotation = srcGeneralImageModuleIod.BurnedInAnnotation;
            generalImageModuleIod.RecognizableVisualFeatures = srcGeneralImageModuleIod.RecognizableVisualFeatures;
            generalImageModuleIod.LossyImageCompression = srcGeneralImageModuleIod.LossyImageCompression.HasValue && srcGeneralImageModuleIod.LossyImageCompression.Value;
            generalImageModuleIod.LossyImageCompressionMethod = srcGeneralImageModuleIod.LossyImageCompressionMethod;
            generalImageModuleIod.LossyImageCompressionRatio = srcGeneralImageModuleIod.LossyImageCompressionRatio;
            generalImageModuleIod.IrradiationEventUid = srcGeneralImageModuleIod.IrradiationEventUid;

            // Image Pixel Module and Segmentation Image Module
            var srcImagePixelModule = new ImagePixelMacroIod(sourceSop.DataSource);
            var imagePixelModule = segDocumentIod.ImagePixelModuleIod;
            imagePixelModule.Rows = srcImagePixelModule.Rows; // same height as the the image
            imagePixelModule.Columns = srcImagePixelModule.Columns; // same width as the image
            //imagePixelModule.PixelAspectRatio = srcImagePixelModule.PixelAspectRatio; // same as the image

            // Continue initialization of non-default values for the Segmentation Image Module
            segmentationImageModuleIod.ContentLabel = SanitizeDicomCsValue(_segDocument.ContentLabel);
            if (!string.IsNullOrEmpty(userDicomName))
                segmentationImageModuleIod.ContentCreatorsName = userDicomName;
            segmentationImageModuleIod.SegmentationType = SegmentationType.BINARY;

            // Per segmentation and per frame item initialization
            var docHasOneFrame = _segDocument.Segs.Where(item => item != null && item.SegGraphics != null).Sum(seg => seg.SegGraphics.OfType<PolygonalRoiSegGraphic>().Count()) == 1;
            var docHasOneSeg = _segDocument.Segs.Count(item => item != null && item.SegGraphics != null && item.SegGraphics.OfType<PolygonalRoiSegGraphic>().Any()) == 1;
            var multiFrameDimensionsModuleIod = segDocumentIod.MultiFrameDimensionModuleIod;
            multiFrameDimensionsModuleIod.InitializeAttributes();
            var segmentSequenceItems = new List<SegmentSequence>();
            var dimensionIndexSequenceItems = new List<DimensionIndexSequenceItem>();
            var dimensionOrganizationSequenceItems = new List<DimensionOrganizationSequenceItem>();
            var multiFrameFunctionalGroupsModuleIod = segDocumentIod.MultiFrameFunctionalGroupsModuleIod;
            multiFrameFunctionalGroupsModuleIod.InitializeAttributes();
            var perFrameFunctionalGroupSequenceItems = new List<FunctionalGroupsSequenceItem>();
            var frameBytesList = new List<byte[]>(); // list of pixel data for each frame
            var seriesUidToSopClassUidToSopInstanceUid = new Dictionary<string, Dictionary<string, HashSet<string>>>();
            var segmentNumber = 0;
            foreach (var seg in _segDocument.Segs)
            {
                segmentNumber++;
                Debug.Assert(segmentNumber == 1, "We're only supposed to create one Segment per document for now");

                // Segment Sequence initialization
                var segmentSequenceItemIod = segmentationImageModuleIod.CreateSegmentSequence();
                segmentSequenceItemIod.SegmentNumber = segmentNumber;
                segmentSequenceItemIod.SegmentLabel = seg.Label;
                segmentSequenceItemIod.SegmentDescription = seg.Description;
                segmentSequenceItemIod.SegmentAlgorithmType = "MANUAL";

                #region Category, Type, Anatomic Region, Anatomic Region Modifier

                var selectedCategory = seg.SelectedCategory;
                if (selectedCategory != null)
                {
                    // Category
                    var segmentedPropertyCategoryCodeSequenceItem = segmentSequenceItemIod.CreateSegmentedPropertyCategoryCodeSequence();
                    segmentedPropertyCategoryCodeSequenceItem.CodeValue = selectedCategory.CodeValue;
                    segmentedPropertyCategoryCodeSequenceItem.CodeMeaning = selectedCategory.CodeMeaning;
                    segmentedPropertyCategoryCodeSequenceItem.CodingSchemeDesignator = selectedCategory.CodingSchemeDesignator;
                    //if (!string.IsNullOrEmpty(selectedCategory.CodingSchemeVersion))
                    //    segmentedPropertyCategoryCodeSequenceItem.CodingSchemeVersion = selectedCategory.CodingSchemeVersion;
                    segmentSequenceItemIod.SegmentedPropertyCategoryCodeSequence = new[] { segmentedPropertyCategoryCodeSequenceItem };

                    // Type
                    if (selectedCategory.SelectedType != null)
                    {
                        var segmentedPropertyTypeCodeSequenceItem = segmentSequenceItemIod.CreateSegmentedPropertyTypeCodeSequence();
                        segmentedPropertyTypeCodeSequenceItem.CodeValue = selectedCategory.SelectedType.CodeValue;
                        segmentedPropertyTypeCodeSequenceItem.CodeMeaning = selectedCategory.SelectedType.CodeMeaning;
                        segmentedPropertyTypeCodeSequenceItem.CodingSchemeDesignator = selectedCategory.SelectedType.CodingSchemeDesignator;
                        //if (!string.IsNullOrEmpty(selectedCategory.SelectedType.CodingSchemeVersion))
                        //    segmentedPropertyTypeCodeSequenceItem.CodingSchemeVersion = selectedCategory.SelectedType.CodingSchemeVersion;

                        // Type modifier
                        if (selectedCategory.SelectedType.SelectedTypeModifier != null)
                        {
                            var segmentedPropertyTypeModifierCodeSequenceItem = new CodeSequenceMacro();
                            segmentedPropertyTypeModifierCodeSequenceItem.CodeValue = selectedCategory.SelectedType.SelectedTypeModifier.CodeValue;
                            segmentedPropertyTypeModifierCodeSequenceItem.CodeMeaning = selectedCategory.SelectedType.SelectedTypeModifier.CodeMeaning;
                            segmentedPropertyTypeModifierCodeSequenceItem.CodingSchemeDesignator = selectedCategory.SelectedType.SelectedTypeModifier.CodingSchemeDesignator;
                            //if (!string.IsNullOrEmpty(selectedCategory.SelectedType.SelectedTypeModifier.CodingSchemeVersion))
                            //    segmentedPropertyTypeModifierCodeSequenceItem.CodingSchemeVersion = selectedCategory.SelectedType.SelectedTypeModifier.CodingSchemeVersion;

                            segmentedPropertyTypeCodeSequenceItem.SegmentedPropertyTypeModifierCodeSequence = new[] {segmentedPropertyTypeModifierCodeSequenceItem};
                        }
                        segmentSequenceItemIod.SegmentedPropertyTypeCodeSequence = new[] { segmentedPropertyTypeCodeSequenceItem };
                    }

                    // Anatomic Region
                    var selectedAnatomicRegion = selectedCategory.SelectedAnatomicRegion;
                    if (selectedAnatomicRegion != null)
                    {
                        var anatomicRegionSequenceItem = segmentSequenceItemIod.CreateAnatomicRegionSequence();
                        anatomicRegionSequenceItem.CodeValue = selectedAnatomicRegion.CodeValue;
                        anatomicRegionSequenceItem.CodeMeaning = selectedAnatomicRegion.CodeMeaning;
                        anatomicRegionSequenceItem.CodingSchemeDesignator = selectedAnatomicRegion.CodingSchemeDesignator;
                        //if (!string.IsNullOrEmpty(selectedAnatomicRegion.CodingSchemeVersion))
                        //    anatomicRegionSequenceItem.CodingSchemeVersion = selectedAnatomicRegion.CodingSchemeVersion;

                        // Anatomic region Modifier
                        if (selectedAnatomicRegion.SelectedAnatomicRegionModifier != null)
                        {
                            var anatomicRegionModifierSequenceItem = new CodeSequenceMacro();
                            anatomicRegionModifierSequenceItem.CodeValue = selectedAnatomicRegion.SelectedAnatomicRegionModifier.CodeValue;
                            anatomicRegionModifierSequenceItem.CodeMeaning = selectedAnatomicRegion.SelectedAnatomicRegionModifier.CodeMeaning;
                            anatomicRegionModifierSequenceItem.CodingSchemeDesignator = selectedAnatomicRegion.SelectedAnatomicRegionModifier.CodingSchemeDesignator;
                            //if (!string.IsNullOrEmpty(selectedAnatomicRegion.SelectedAnatomicRegionModifier.CodingSchemeVersion))
                            //    anatomicRegionModifierSequenceItem.CodingSchemeVersion = selectedAnatomicRegion.SelectedAnatomicRegionModifier.CodingSchemeVersion;

                            anatomicRegionSequenceItem.AnatomicRegionModifierSequence = new[] { anatomicRegionModifierSequenceItem };
                        }
                        segmentSequenceItemIod.AnatomicRegionSequence = new[] { anatomicRegionSequenceItem };
                    }
                }

                #endregion

                segmentSequenceItemIod.RecomendedDisplayCIELabValue = LabColorHelpers.RgbColorToCIELabColor(seg.Color);
                segmentSequenceItems.Add(segmentSequenceItemIod);

                // Dimension Organization Sequence item
                var dimensionOrganizationUid = DicomUid.GenerateUid().UID;
                var dimensionOrganizationSequenceItem = multiFrameDimensionsModuleIod.CreateDimensionOrganizationSequenceItem();
                dimensionOrganizationSequenceItem.DimensionOrganizationUid = dimensionOrganizationUid;
                dimensionOrganizationSequenceItems.Add(dimensionOrganizationSequenceItem);

                // Dimension Index Sequence items
                var dimensionIndexSequenceItem1 = multiFrameDimensionsModuleIod.CreateDimensionIndexSequenceItem();
                dimensionIndexSequenceItem1.DimensionIndexPointer = DicomTags.StackId;
                dimensionIndexSequenceItem1.FunctionalGroupPointer = DicomTags.FrameContentSequence;
                dimensionIndexSequenceItem1.DimensionOrganizationUid = dimensionOrganizationUid;
                dimensionIndexSequenceItem1.DimensionDescriptionLabel = "Stack ID";
                dimensionIndexSequenceItems.Add(dimensionIndexSequenceItem1);
                var dimensionIndexSequenceItem2 = multiFrameDimensionsModuleIod.CreateDimensionIndexSequenceItem();
                dimensionIndexSequenceItem2.DimensionIndexPointer = DicomTags.InStackPositionNumber;
                dimensionIndexSequenceItem2.FunctionalGroupPointer = DicomTags.FrameContentSequence;
                dimensionIndexSequenceItem2.DimensionOrganizationUid = dimensionOrganizationUid;
                dimensionIndexSequenceItem2.DimensionDescriptionLabel = "In Stack Position Number";
                dimensionIndexSequenceItems.Add(dimensionIndexSequenceItem2);

                var inStackPositionIndex = 0;

                var presentationImagePolygons = new Dictionary<IPresentationImage, List<PolygonalRoiSegGraphic>>();
                foreach (var polygonalSegGraphic in seg.SegGraphics.OfType<PolygonalRoiSegGraphic>())
                {
                    var poly = polygonalSegGraphic.PolygonalRoiGraphic.Roi as PolygonalRoi;
                    if (poly != null)
                    {
                        var currentPresentationImage = callback(polygonalSegGraphic.ImageSopInstanceUid, polygonalSegGraphic.ImageFrameNumber);
                        if (presentationImagePolygons.ContainsKey(currentPresentationImage))
                            presentationImagePolygons[currentPresentationImage].Add(polygonalSegGraphic);
                        else
                            presentationImagePolygons.Add(poly.PresentationImage, new List<PolygonalRoiSegGraphic> { polygonalSegGraphic });
                    }
                    else
                    {
                        Debug.Assert(false, "Encountered non-polygonal graphic during segmentation serialization");
                    }
                }

                foreach (var presentationImage in presentationImagePolygons.Keys)
                {
                    var currentImageSopProvider = presentationImage as IImageSopProvider;

                    if (presentationImage == null)
                    {
                        Debug.Assert(false, "Failed to get IImageSopProvider for the current Segmentation graphic");
                        continue;
                    }

                    Debug.Assert(presentationImagePolygons[presentationImage].FirstOrDefault().ImageFrameNumber ==
                        currentImageSopProvider.Frame.FrameNumber,
                                 "Stored frame number must match with the current SOP Instance's value");

                    #region PerFrameFunctionalGroupSequenceItem

                    // Initialize Per Frame Functional Groups here and groups
                    var perFrameFunctionalGroupSequenceItem = multiFrameFunctionalGroupsModuleIod.CreatePerFrameFunctionalGroupsSequence();

                    if (!docHasOneSeg)
                    {
                        // Pixel Measures Functional Group (per frame)
                        InitializePixelMeasureFunctionalGroup(perFrameFunctionalGroupSequenceItem, currentImageSopProvider.Frame);

                        // Initialize Segmentation Functional Group (per frame)
                        InitializeSegmentationFunctionalGroup(perFrameFunctionalGroupSequenceItem, segmentNumber);

                        // Plane Orientation (Patient) Functional Group
                        InitializePlaneOrientationPatientFunctionalGroup(perFrameFunctionalGroupSequenceItem, currentImageSopProvider.Frame.ImageOrientationPatient);
                    }
                    if (!docHasOneFrame)
                    {
                        // Plain Position Patient Functional Group (per frame)
                        InitializePlanePositionPatientFunctionalGroup(perFrameFunctionalGroupSequenceItem, currentImageSopProvider.Frame.ImagePositionPatient);

                        // Derivation Image Functional Group (per frame)
                        InitializeDerivationImageFunctionalGroup(perFrameFunctionalGroupSequenceItem, currentImageSopProvider.ImageSop, currentImageSopProvider.Frame.FrameNumber);
                    }
                    else
                    {
                        Debug.Assert(firstImageSopProvider.ImageSop.SeriesInstanceUid == currentImageSopProvider.Frame.SeriesInstanceUid &&
                                     firstImageSopProvider.ImageSop.SopInstanceUid == currentImageSopProvider.ImageSop.SopInstanceUid,
                                     "initial image reference and the single image reference must be the same");
                    }

                    // Initialize Frame Content Functional Group
                    InitializeFrameContentFunctionalGroup(perFrameFunctionalGroupSequenceItem, segmentNumber, ++inStackPositionIndex);

                    perFrameFunctionalGroupSequenceItems.Add(perFrameFunctionalGroupSequenceItem);

                    #endregion PerFrameFunctionalGroupSequenceItem

                    // Store referenced image info in a dictionary for later use
                    {
                        var currentSeriesInstanceUid = currentImageSopProvider.ImageSop.SeriesInstanceUid;
                        var currentSopClassUid = currentImageSopProvider.ImageSop.SopClassUid;
                        var currentSopInstanceUid = currentImageSopProvider.ImageSop.SopInstanceUid;
                        if (!seriesUidToSopClassUidToSopInstanceUid.ContainsKey(currentSeriesInstanceUid))
                            seriesUidToSopClassUidToSopInstanceUid.Add(currentSeriesInstanceUid, new Dictionary<string, HashSet<string>>());
                        var sopClassToSopInstanceDic = seriesUidToSopClassUidToSopInstanceUid[currentSeriesInstanceUid];
                        if (!sopClassToSopInstanceDic.ContainsKey(currentSopClassUid))
                            sopClassToSopInstanceDic.Add(currentSopClassUid, new HashSet<string>());
                        sopClassToSopInstanceDic[currentSopClassUid].Add(currentSopInstanceUid);
                    }

                    var polygons = new List<IList<PointF>>();

                    // Get frame's pixel data here
                    foreach (var polygonalSegGraphic in presentationImagePolygons[presentationImage])
                    {
                        var poly = polygonalSegGraphic.PolygonalRoiGraphic.Roi as PolygonalRoi;
                        if (poly != null)
                        {
                            polygons.Add(poly.Polygon.Vertices);
                        }
                        else
                        {
                            Debug.Assert(false, "Encountered non-polygonal graphic during segmentation serialization");
                        }
                    }

                    var grayscalePixelData = CreateFramePixelData(presentationImage, polygons);
                    frameBytesList.Add(grayscalePixelData.Raw);
                }
            }

            segmentationImageModuleIod.SegmentSequence = segmentSequenceItems.ToArray();

            // Per Frame Functional Groups module
            multiFrameFunctionalGroupsModuleIod.PerFrameFunctionalGroupsSequence = perFrameFunctionalGroupSequenceItems.ToArray();

            #region SharedFunctionalGroupSequence

            // Shared Functional Group Sequence Item
            var sharedFunctionalGroupSequenceItem = multiFrameFunctionalGroupsModuleIod.CreateSharedFunctionalGroupsSequence();

            if (docHasOneSeg)
            {
                Debug.Assert(segmentNumber == 1, "This is for a single segment only");

                // Pixel Measures Functional Group (shared)
                InitializePixelMeasureFunctionalGroup(sharedFunctionalGroupSequenceItem, firstImageSopProvider.Frame);

                // Initialize Segmentation Functional Group (shared)
                InitializeSegmentationFunctionalGroup(sharedFunctionalGroupSequenceItem, segmentNumber);

                // Plane Orientation (Patient) Functional Group
                InitializePlaneOrientationPatientFunctionalGroup(sharedFunctionalGroupSequenceItem, firstImageSopProvider.Frame.ImageOrientationPatient);
            }

            if (docHasOneFrame)
            {
                // Plain Position Patient Functional Group
                InitializePlanePositionPatientFunctionalGroup(sharedFunctionalGroupSequenceItem, firstImageSopProvider.Frame.ImagePositionPatient);

                // Derivation Image Functional Group
                InitializeDerivationImageFunctionalGroup(sharedFunctionalGroupSequenceItem, firstImageSopProvider.ImageSop, firstImageSopProvider.Frame.FrameNumber);
            }

            multiFrameFunctionalGroupsModuleIod.SharedFunctionalGroupsSequence = sharedFunctionalGroupSequenceItem;

            #endregion SharedFunctionalGroupSequence

            // Multi-frame Dimensions module
            multiFrameDimensionsModuleIod.DimensionIndexSequence = dimensionIndexSequenceItems.ToArray();
            multiFrameDimensionsModuleIod.DimensionOrganizationSequence = dimensionOrganizationSequenceItems.ToArray();
            multiFrameDimensionsModuleIod.DimensionOrganizationType = "3D";

            // Multi-frame Functional Groups module
            multiFrameFunctionalGroupsModuleIod.SharedFunctionalGroupsSequence = sharedFunctionalGroupSequenceItem;
            multiFrameFunctionalGroupsModuleIod.PerFrameFunctionalGroupsSequence = perFrameFunctionalGroupSequenceItems.ToArray();
            multiFrameFunctionalGroupsModuleIod.NumberOfFrames = perFrameFunctionalGroupSequenceItems.Count;

            // Specimen Module
            var srcSpecimenModuleIod = new SpecimenModuleIod(sourceSop.DataSource);
            var specimenModuleIod = segDocumentIod.SpecimenModuleIod;
            //specimenModuleIod.ContainerIdentifier = srcSpecimenModuleIod.ContainerIdentifier;
            specimenModuleIod.IssuerOfTheContainterIdentifier = srcSpecimenModuleIod.IssuerOfTheContainterIdentifier;
            specimenModuleIod.AlternateContainerIdentifierSequence = srcSpecimenModuleIod.AlternateContainerIdentifierSequence;
            specimenModuleIod.ContainerTypeCodeSequence = srcSpecimenModuleIod.ContainerTypeCodeSequence;
            //specimenModuleIod.ContainerDescription = srcSpecimenModuleIod.ContainerDescription;
            specimenModuleIod.ContainerComponentSequence = srcSpecimenModuleIod.ContainerComponentSequence;
            specimenModuleIod.SpecimenDescriptionSequence = srcSpecimenModuleIod.SpecimenDescriptionSequence;

            // Common Instance Reference Module
            var referencedSeriesSequenceItems = new List<ReferencedSeriesSequenceIod>();
            foreach (
                var seriesToSopClassToSopInstanceDic in
                    seriesUidToSopClassUidToSopInstanceUid.Where(seriesToSopClassToSopInstanceDic => seriesToSopClassToSopInstanceDic.Value != null))
            {
                var referencedSopInstances = new List<ReferencedInstanceSequenceIod>();
                foreach (var sopClassToSopInstanceDic in seriesToSopClassToSopInstanceDic.Value.Where(sopClassToSopInstanceDic => sopClassToSopInstanceDic.Value != null))
                {
                    referencedSopInstances.AddRange(sopClassToSopInstanceDic.Value.Select(sopInstanceUid => new ReferencedInstanceSequenceIod
                        {
                            ReferencedSopClassUid = sopClassToSopInstanceDic.Key,
                            ReferencedSopInstanceUid = sopInstanceUid
                        }));
                }
                if (referencedSopInstances.Count > 0)
                {
                    referencedSeriesSequenceItems.Add(new ReferencedSeriesSequenceIod
                        {
                            SeriesInstanceUid = seriesToSopClassToSopInstanceDic.Key,
                            ReferencedInstanceSequence = referencedSopInstances.ToArray()
                        });
                }
            }
            if (referencedSeriesSequenceItems.Count > 0)
            {
                var commonInstanceReferenceModuleIod = segDocumentIod.CommonInstanceReferenceModuleIod;
                commonInstanceReferenceModuleIod.InitializeAttributes();
                commonInstanceReferenceModuleIod.ReferencedSeriesSequence = referencedSeriesSequenceItems.ToArray();
            }

            // SOP Common Module
            var srcSopCommonModuleIod = new SopCommonModuleIod(sourceSop.DataSource);
            var sopCommonModuleIod = segDocumentIod.SopCommonModuleIod;
            sopCommonModuleIod.SopClass = SopClass.SegmentationStorage;
            sopCommonModuleIod.SopInstanceUid = DicomUid.GenerateUid().UID;
            //sopCommonModuleIod.SpecificCharacterSet = "UTF-8"; // TBD -it's ISO_IR 192 by default
            sopCommonModuleIod.InstanceCreationDateTime = contentDateTime;
            sopCommonModuleIod.InstanceCreatorUid = InstanceCreatorUid;
            sopCommonModuleIod.TimezoneOffsetFromUtc = contentDateTime.ToString("zzz", DateTimeFormatInfo.InvariantInfo);
            //sopCommonModuleIod.LongitudinalTemporalInformationModified = srcSopCommonModuleIod.LongitudinalTemporalInformationModified; // has a bug in CC

            // Pixel data
            {
                Debug.Assert(frameBytesList.TrueForAll(bytes => bytes.Length == frameBytesList[0].Length), "Allocated buffers for all frames must be of the same size");
                var byteBuffer = new byte[frameBytesList[0].Length * frameBytesList.Count];
                using (var stream = new MemoryStream(byteBuffer))
                {
                    foreach (var frameBytes in frameBytesList)
                        stream.Write(frameBytes, 0, frameBytes.Length);
                }
                // Byte Packing
                // TODO FIXME: we can do in-place byte packing without allocating the second array!
                var packetBuffer = new byte[(int) Math.Ceiling(byteBuffer.Length/8.0)];
                var numberOfFullBytes = byteBuffer.Length/8;
                for (var i = 0; i < numberOfFullBytes; i++)
                {
                    var newByte = packetBuffer[i];
                    for (var y = 0; y < 8; y++)
                    {
                        var bitMask = (byte) (1 << y);
                        newByte = (byte) ((byteBuffer[8*i + y] & 0xFF) > 0 ? newByte | bitMask : newByte & ~bitMask);
                    }
                    packetBuffer[i] = newByte;
                }
                // last byte(s) TODO VK: handle padding for non-even number of bytes. make sure padded bits are initialized to 0
                if (numberOfFullBytes < packetBuffer.Length)
                {
                    // Pack leftover bytes ( < 8)
                    Debug.Assert(packetBuffer.Length - numberOfFullBytes == 1, "Wrong destination bytes count during packing");
                    Debug.Assert(byteBuffer.Length - numberOfFullBytes*8 < 8, "Wrong leftover bytes count during packing");
                    var newByte = packetBuffer[packetBuffer.Length - 1];
                    for (var y = numberOfFullBytes * 8; y < byteBuffer.Length; y++)
                    {
                        var bitMask = (byte) (1 << (y%8));
                        newByte = (byte) ((byteBuffer[y] & 0xFF) > 0 ? newByte | bitMask : newByte & ~bitMask);
                    }
                    packetBuffer[packetBuffer.Length - 1] = newByte;
                }
                var pdAttribute = new DicomAttributeOW(DicomTags.PixelData);
                using (var stream = pdAttribute.AsStream())
                {
                    stream.Write(packetBuffer, 0, packetBuffer.Length);
                }

                multiFrameFunctionalGroupsModuleIod.DicomAttributeProvider[DicomTags.PixelData] = pdAttribute;
            }

            dicomFile.MediaStorageSopClassUid = SopClass.SegmentationStorageUid;
            dicomFile.MediaStorageSopInstanceUid = segDocumentIod.SopInstanceUid;

            // Update the original document with new values
            _segDocument.SeriesInstanceUid = segDocumentIod.SeriesInstanceUid;
            _segDocument.SopInstanceUid = segDocumentIod.SopInstanceUid;

            return dicomFile;
        }
		/// <summary>
		/// Creates a single instance of a PrimaryAnatomicStructureModifierSequence item. Does not modify the PrimaryAnatomicStructureModifierSequence in the underlying collection.
		/// </summary>
		public CodeSequenceMacro CreatePrimaryAnatomicStructureModifierSequenceItem()
		{
			var iodBase = new CodeSequenceMacro(new DicomSequenceItem());
			return iodBase;
		}
Ejemplo n.º 5
0
        public override StudyItemList Query(QueryParameters queryParams, IApplicationEntity targetServer)
        {
            Platform.CheckForNullReference(queryParams, "queryParams");
            Platform.CheckForNullReference(targetServer, "targetServer");

            var selectedServer = targetServer.ToServiceNode();

            //.NET strings are unicode, therefore, so is all the query data.
            const string utf8 = "ISO_IR 192";
            var requestCollection = new DicomAttributeCollection { SpecificCharacterSet = utf8 };
            requestCollection[DicomTags.SpecificCharacterSet].SetStringValue(utf8);

			requestCollection[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY");
			requestCollection[DicomTags.StudyInstanceUid].SetStringValue("");

			requestCollection[DicomTags.PatientId].SetStringValue(queryParams["PatientId"]);
			requestCollection[DicomTags.AccessionNumber].SetStringValue(queryParams["AccessionNumber"]);
			requestCollection[DicomTags.PatientsName].SetStringValue(queryParams["PatientsName"]);
			requestCollection[DicomTags.ReferringPhysiciansName].SetStringValue(queryParams["ReferringPhysiciansName"]);
			requestCollection[DicomTags.StudyDate].SetStringValue(queryParams["StudyDate"]);
			requestCollection[DicomTags.StudyTime].SetStringValue("");
			requestCollection[DicomTags.StudyDescription].SetStringValue(queryParams["StudyDescription"]);
			requestCollection[DicomTags.PatientsBirthDate].SetStringValue("");
			requestCollection[DicomTags.ModalitiesInStudy].SetStringValue(queryParams["ModalitiesInStudy"]);
			requestCollection[DicomTags.NumberOfStudyRelatedInstances].SetStringValue("");
			requestCollection[DicomTags.InstanceAvailability].SetEmptyValue(); // must not be included in request

			requestCollection[DicomTags.PatientSpeciesDescription].SetStringValue(GetString(queryParams, "PatientSpeciesDescription"));
			var codeValue = GetString(queryParams, "PatientSpeciesCodeSequenceCodeValue");
			var codeMeaning = GetString(queryParams, "PatientSpeciesCodeSequenceCodeMeaning");
			if (codeValue != null || codeMeaning != null)
			{
				var codeSequenceMacro = new CodeSequenceMacro
				{
					CodingSchemeDesignator = "",
					CodeValue = codeValue,
					CodeMeaning = codeMeaning
				};
				requestCollection[DicomTags.PatientSpeciesCodeSequence].AddSequenceItem(codeSequenceMacro.DicomSequenceItem);
			}

			requestCollection[DicomTags.PatientBreedDescription].SetStringValue(GetString(queryParams, "PatientBreedDescription"));
			codeValue = GetString(queryParams, "PatientBreedCodeSequenceCodeValue");
			codeMeaning = GetString(queryParams, "PatientBreedCodeSequenceCodeMeaning");
			if (codeValue != null || codeMeaning != null)
			{
				var codeSequenceMacro = new CodeSequenceMacro
				{
					CodingSchemeDesignator = "",
					CodeValue = codeValue,
					CodeMeaning = codeMeaning
				};
				requestCollection[DicomTags.PatientBreedCodeSequence].AddSequenceItem(codeSequenceMacro.DicomSequenceItem);
			}

			requestCollection[DicomTags.ResponsiblePerson].SetStringValue(GetString(queryParams, "ResponsiblePerson"));
			requestCollection[DicomTags.ResponsiblePersonRole].SetStringValue("");
			requestCollection[DicomTags.ResponsibleOrganization].SetStringValue(GetString(queryParams,"ResponsibleOrganization"));

			IList<DicomAttributeCollection> results = Query(selectedServer, requestCollection);
			
			StudyItemList studyItemList = new StudyItemList();
			foreach (DicomAttributeCollection result in results)
			{
				StudyItem item = new StudyItem(result[DicomTags.StudyInstanceUid].GetString(0, ""), selectedServer);

				//TODO: add DicomField attributes to the StudyItem class (implement typeconverter for PersonName class).
				item.PatientsBirthDate = result[DicomTags.PatientsBirthDate].GetString(0, "");
				item.AccessionNumber = result[DicomTags.AccessionNumber].GetString(0, "");
				item.StudyDescription = result[DicomTags.StudyDescription].GetString(0, "");
				item.StudyDate = result[DicomTags.StudyDate].GetString(0, "");
				item.StudyTime = result[DicomTags.StudyTime].GetString(0, "");
				item.PatientId = result[DicomTags.PatientId].GetString(0, "");
				item.PatientsName = new PersonName(result[DicomTags.PatientsName].GetString(0, ""));
				item.ReferringPhysiciansName = new PersonName(result[DicomTags.ReferringPhysiciansName].GetString(0, ""));
				item.ModalitiesInStudy = DicomStringHelper.GetStringArray(result[DicomTags.ModalitiesInStudy].ToString());
				DicomAttribute attribute = result[DicomTags.NumberOfStudyRelatedInstances];
				if (!attribute.IsEmpty && !attribute.IsNull)
					item.NumberOfStudyRelatedInstances = attribute.GetInt32(0, 0);

				item.SpecificCharacterSet = result.SpecificCharacterSet;
				item.InstanceAvailability = result[DicomTags.InstanceAvailability].GetString(0, "");
				if (String.IsNullOrEmpty(item.InstanceAvailability))
					item.InstanceAvailability = "ONLINE";

				item.PatientSpeciesDescription = result[DicomTags.PatientSpeciesDescription].GetString(0, "");
				var patientSpeciesCodeSequence = result[DicomTags.PatientSpeciesCodeSequence];
				if (!patientSpeciesCodeSequence.IsNull && patientSpeciesCodeSequence.Count > 0)
				{
					var codeSequenceMacro = new CodeSequenceMacro(((DicomSequenceItem[])result[DicomTags.PatientSpeciesCodeSequence].Values)[0]);
					item.PatientSpeciesCodeSequenceCodingSchemeDesignator = codeSequenceMacro.CodingSchemeDesignator;
					item.PatientSpeciesCodeSequenceCodeValue = codeSequenceMacro.CodeValue;
					item.PatientSpeciesCodeSequenceCodeMeaning = codeSequenceMacro.CodeMeaning;
				}

				item.PatientBreedDescription = result[DicomTags.PatientBreedDescription].GetString(0, "");
				var patientBreedCodeSequence = result[DicomTags.PatientBreedCodeSequence];
				if (!patientBreedCodeSequence.IsNull && patientBreedCodeSequence.Count > 0)
				{
					var codeSequenceMacro = new CodeSequenceMacro(((DicomSequenceItem[])result[DicomTags.PatientBreedCodeSequence].Values)[0]);
					item.PatientBreedCodeSequenceCodingSchemeDesignator = codeSequenceMacro.CodingSchemeDesignator;
					item.PatientBreedCodeSequenceCodeValue = codeSequenceMacro.CodeValue;
					item.PatientBreedCodeSequenceCodeMeaning = codeSequenceMacro.CodeMeaning;
				}

				item.ResponsiblePerson = new PersonName(result[DicomTags.ResponsiblePerson].GetString(0, ""));
				item.ResponsiblePersonRole = result[DicomTags.ResponsiblePersonRole].GetString(0, "");
				item.ResponsibleOrganization = result[DicomTags.ResponsibleOrganization].GetString(0, "");
				studyItemList.Add(item);
			}

        	AuditHelper.LogQueryIssued(selectedServer.AETitle, selectedServer.ScpParameters.HostName, EventSource.CurrentUser,
        	                           EventResult.Success, SopClass.StudyRootQueryRetrieveInformationModelFindUid,
        	                           requestCollection);

			return studyItemList;
        }
		/// <summary>
		/// Creates a single instance of a ContrastBolusAgentSequence item. Does not modify the ContrastBolusAgentSequence in the underlying collection.
		/// </summary>
		public CodeSequenceMacro CreateContrastBolusAgentSequenceItem()
		{
			var iodBase = new CodeSequenceMacro(new DicomSequenceItem());
			return iodBase;
		}
		/// <summary>
		/// Creates the PatientGantryRelationshipCodeSequence in the underlying collection. Type 2.
		/// </summary>
		public CodeSequenceMacro CreatePatientGantryRelationshipCodeSequence()
		{
			var dicomAttribute = DicomAttributeProvider[DicomTags.PatientGantryRelationshipCodeSequence];
			if (dicomAttribute.IsNull || dicomAttribute.IsEmpty)
			{
				var dicomSequenceItem = new DicomSequenceItem();
				dicomAttribute.Values = new[] {dicomSequenceItem};
				var sequenceType = new CodeSequenceMacro(dicomSequenceItem);
				return sequenceType;
			}
			return new CodeSequenceMacro(((DicomSequenceItem[]) dicomAttribute.Values)[0]);
		}
Ejemplo n.º 8
0
        /// <summary>
        /// Update an <see cref="DicomAttributeCollection"/> with pixel data related tags.
        /// </summary>
        /// <param name="dataset">The collection to update.</param>
        public override void UpdateAttributeCollection(DicomAttributeCollection 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.RemoveAttribute(DicomTags.BluePaletteColorLookupTableDescriptor);
				dataset.RemoveAttribute(DicomTags.BluePaletteColorLookupTableData);
				dataset.RemoveAttribute(DicomTags.RedPaletteColorLookupTableDescriptor);
				dataset.RemoveAttribute(DicomTags.RedPaletteColorLookupTableData);
				dataset.RemoveAttribute(DicomTags.GreenPaletteColorLookupTableDescriptor);
				dataset.RemoveAttribute(DicomTags.GreenPaletteColorLookupTableData);
			}

			dataset.SaveDicomFields(this);
            dataset[DicomTags.PixelData] = _sq;
        }
Ejemplo n.º 9
0
		/// <summary>
		/// Creates a single instance of a DerivationCodeSequence item. Does not modify the DerivationCodeSequence in the underlying collection.
		/// </summary>
		public CodeSequenceMacro CreateDerivationCodeSequence()
		{
			var iodBase = new CodeSequenceMacro(new DicomSequenceItem());
			return iodBase;
		}
		public void TestEnhancedAgentCodeSequence()
		{
			var agent1 = new CodeSequenceMacro {CodeMeaning = "Contrastinol", CodeValue = "123", CodingSchemeDesignator = "ABC"};
			var agent2 = new CodeSequenceMacro {CodeMeaning = "Bolusinate", CodeValue = "456", CodingSchemeDesignator = "DEF"};
			var agent3 = new CodeSequenceMacro {CodeMeaning = "Dilithium", CodeValue = "789", CodingSchemeDesignator = "GHI"};

			var usageFrame1 = new ContrastBolusUsageFunctionalGroup
			                  	{
			                  		ContrastBolusUsageSequence = new[]
			                  		                             	{
			                  		                             		new ContrastBolusUsageSequenceItem {ContrastBolusAgentNumber = 1},
			                  		                             		new ContrastBolusUsageSequenceItem {ContrastBolusAgentNumber = 3}
			                  		                             	}
			                  	};
			var usageFrame2 = new ContrastBolusUsageFunctionalGroup
			                  	{
			                  		ContrastBolusUsageSequence = new[]
			                  		                             	{
			                  		                             		new ContrastBolusUsageSequenceItem {ContrastBolusAgentNumber = 2}
			                  		                             	}
			                  	};
			var usageFrame3 = new ContrastBolusUsageFunctionalGroup(new DicomSequenceItem())
			                  	{
			                  		ContrastBolusUsageSequence = new[]
			                  		                             	{
			                  		                             		new ContrastBolusUsageSequenceItem {ContrastBolusAgentNumber = 999},
			                  		                             		new ContrastBolusUsageSequenceItem {ContrastBolusAgentNumber = 2}
			                  		                             	}
			                  	};
			var usageFrame4 = new ContrastBolusUsageFunctionalGroup(new DicomSequenceItem());

			var dataset = TestDataSource.CreateImageSopDataSource(4);
			dataset[DicomTags.ContrastBolusAgent].SetStringValue(@"Contrastinol and Bolusinate");
			dataset[DicomTags.ContrastBolusAgentSequence].AddSequenceItem(agent1.DicomSequenceItem);
			dataset[DicomTags.ContrastBolusAgentSequence].AddSequenceItem(agent2.DicomSequenceItem);
			dataset[DicomTags.ContrastBolusAgentSequence].AddSequenceItem(agent3.DicomSequenceItem);
			dataset[DicomTags.PerFrameFunctionalGroupsSequence].AddSequenceItem(usageFrame1.DicomSequenceItem);
			dataset[DicomTags.PerFrameFunctionalGroupsSequence].AddSequenceItem(usageFrame2.DicomSequenceItem);
			dataset[DicomTags.PerFrameFunctionalGroupsSequence].AddSequenceItem(usageFrame3.DicomSequenceItem);
			dataset[DicomTags.PerFrameFunctionalGroupsSequence].AddSequenceItem(usageFrame4.DicomSequenceItem);

			agent1.DicomSequenceItem[DicomTags.ContrastBolusAgentNumber].SetInt32(0, 1);
			agent2.DicomSequenceItem[DicomTags.ContrastBolusAgentNumber].SetInt32(0, 2);
			agent3.DicomSequenceItem[DicomTags.ContrastBolusAgentNumber].SetInt32(0, 3);

			using (var sop = (ImageSop) Sop.Create(dataset))
			using (var images = new DisposableList<IPresentationImage>(PresentationImageFactory.Create(sop)))
			{
				Assert.AreEqual(@"Contrastinol\Dilithium", _annotationItems[_cbAgent].GetAnnotationText(images[0]), "Frame 1");
				Assert.AreEqual(@"Bolusinate", _annotationItems[_cbAgent].GetAnnotationText(images[1]), "Frame 2");
				Assert.AreEqual(@"Bolusinate", _annotationItems[_cbAgent].GetAnnotationText(images[2]), "Frame 3");
				Assert.IsEmpty(_annotationItems[_cbAgent].GetAnnotationText(images[3]), "Frame 4");

				agent1.CodeMeaning = string.Empty;
				agent2.CodeMeaning = string.Empty;
				Assert.AreEqual(@"123 (ABC)\Dilithium", _annotationItems[_cbAgent].GetAnnotationText(images[0]), "Frame 1");
				Assert.AreEqual(@"456 (DEF)", _annotationItems[_cbAgent].GetAnnotationText(images[1]), "Frame 2");
				Assert.AreEqual(@"456 (DEF)", _annotationItems[_cbAgent].GetAnnotationText(images[2]), "Frame 3");
				Assert.IsEmpty(_annotationItems[_cbAgent].GetAnnotationText(images[3]), "Frame 4");

				agent3.CodeMeaning = string.Empty;
				Assert.AreEqual(@"123 (ABC)\789 (GHI)", _annotationItems[_cbAgent].GetAnnotationText(images[0]));
				Assert.AreEqual(@"456 (DEF)", _annotationItems[_cbAgent].GetAnnotationText(images[1]), "Frame 2");
				Assert.AreEqual(@"456 (DEF)", _annotationItems[_cbAgent].GetAnnotationText(images[2]), "Frame 3");
				Assert.IsEmpty(_annotationItems[_cbAgent].GetAnnotationText(images[3]), "Frame 4");
			}
		}
Ejemplo n.º 11
0
		private bool AreEqual(CodeSequenceMacro x, KeyObjectSelectionDocumentTitle y)
		{
			return x == null ? y == null : (y != null && x.CodeValue == y.CodeValue && x.CodingSchemeDesignator == y.CodingSchemeDesignator);
		}
		/// <summary>
		/// Creates a single instance of a AnatomicRegionModifierSequence item. Does not modify the AnatomicRegionModifierSequence in the underlying collection.
		/// </summary>
		public CodeSequenceMacro CreateAnatomicRegionModifierSequenceItem()
		{
			var iodBase = new CodeSequenceMacro(new DicomSequenceItem());
			return iodBase;
		}
 public CodeSequenceMacro CreateSegmentedPropertyCategoryCodeSequence()
 {
     CodeSequenceMacro iodBase = new CodeSequenceMacro(new DicomSequenceItem());
     return iodBase;
 }
Ejemplo n.º 14
0
        public override StudyItemList Query(QueryParameters queryParams, IApplicationEntity server)
        {
			Platform.CheckForNullReference(queryParams, "queryParams");

            //.NET strings are unicode, therefore, so is all the query data.
            const string utf8 = "ISO_IR 192";
            var collection = new DicomAttributeCollection {SpecificCharacterSet = utf8};
            collection[DicomTags.SpecificCharacterSet].SetStringValue(utf8);

            collection[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY");
            collection[DicomTags.PatientId].SetStringValue(queryParams["PatientId"]);
            collection[DicomTags.AccessionNumber].SetStringValue(queryParams["AccessionNumber"]);
            collection[DicomTags.PatientsName].SetStringValue(queryParams["PatientsName"]);
			collection[DicomTags.ReferringPhysiciansName].SetStringValue(queryParams["ReferringPhysiciansName"]);
			collection[DicomTags.StudyDate].SetStringValue(queryParams["StudyDate"]);
			collection[DicomTags.StudyTime].SetStringValue("");
			collection[DicomTags.StudyDescription].SetStringValue(queryParams["StudyDescription"]);
        	collection[DicomTags.PatientsBirthDate].SetStringValue("");
            collection[DicomTags.ModalitiesInStudy].SetStringValue(queryParams["ModalitiesInStudy"]);
			collection[DicomTags.StudyInstanceUid].SetStringValue(queryParams["StudyInstanceUid"]);
			collection[DicomTags.NumberOfStudyRelatedInstances].SetStringValue("");
			collection[DicomTags.InstanceAvailability].SetEmptyValue(); // must not be included in request

			collection[DicomTags.PatientSpeciesDescription].SetStringValue(GetString(queryParams, "PatientSpeciesDescription"));
			var codeValue = GetString(queryParams, "PatientSpeciesCodeSequenceCodeValue");
			var codeMeaning = GetString(queryParams, "PatientSpeciesCodeSequenceCodeMeaning");
			if (codeValue != null || codeMeaning != null)
			{
				var codeSequenceMacro = new CodeSequenceMacro
					{
						CodingSchemeDesignator = "",
						CodeValue = codeValue,
						CodeMeaning = codeMeaning
					};
				collection[DicomTags.PatientSpeciesCodeSequence].AddSequenceItem(codeSequenceMacro.DicomSequenceItem);
            }

			collection[DicomTags.PatientBreedDescription].SetStringValue(GetString(queryParams, "PatientBreedDescription"));
			codeValue = GetString(queryParams, "PatientBreedCodeSequenceCodeValue");
			codeMeaning = GetString(queryParams, "PatientBreedCodeSequenceCodeMeaning");
			if (codeValue != null || codeMeaning != null)
			{
				var codeSequenceMacro = new CodeSequenceMacro
					{
						CodingSchemeDesignator = "",
						CodeValue = codeValue,
						CodeMeaning = codeMeaning
					};
				collection[DicomTags.PatientBreedCodeSequence].AddSequenceItem(codeSequenceMacro.DicomSequenceItem);
            }

			collection[DicomTags.ResponsiblePerson].SetStringValue(GetString(queryParams, "ResponsiblePerson"));
			collection[DicomTags.ResponsiblePersonRole].SetStringValue("");
			collection[DicomTags.ResponsibleOrganization].SetStringValue(GetString(queryParams, "ResponsibleOrganization"));

            var localServer = ServerDirectory.GetLocalServer();
            var studyItemList = new StudyItemList();
			using (var context = new DataAccessContext())
			{
				foreach (DicomAttributeCollection result in context.GetStudyStoreQuery().Query(collection))
				{
                    var item = new StudyItem(result[DicomTags.StudyInstanceUid].ToString(), localServer);
					item.SpecificCharacterSet = result.SpecificCharacterSet;
					item.PatientId = result[DicomTags.PatientId].ToString();
					item.PatientsName = new PersonName(result[DicomTags.PatientsName].ToString());
					item.ReferringPhysiciansName = new PersonName(result[DicomTags.ReferringPhysiciansName].GetString(0, ""));
					item.PatientsBirthDate = result[DicomTags.PatientsBirthDate].ToString();
					item.StudyDate = result[DicomTags.StudyDate].ToString();
					item.StudyTime = result[DicomTags.StudyTime].ToString();
					item.StudyDescription = result[DicomTags.StudyDescription].ToString();
					item.ModalitiesInStudy = DicomStringHelper.GetStringArray(result[DicomTags.ModalitiesInStudy].ToString());
					item.AccessionNumber = result[DicomTags.AccessionNumber].ToString();
					item.NumberOfStudyRelatedInstances = result[DicomTags.NumberOfStudyRelatedInstances].GetInt32(0, 0);
					item.InstanceAvailability = result[DicomTags.InstanceAvailability].GetString(0, "");
					if (String.IsNullOrEmpty(item.InstanceAvailability))
						item.InstanceAvailability = "ONLINE";

					item.PatientSpeciesDescription = result[DicomTags.PatientSpeciesDescription].GetString(0, "");
					var patientSpeciesCodeSequence = result[DicomTags.PatientSpeciesCodeSequence];
					if (!patientSpeciesCodeSequence.IsNull && patientSpeciesCodeSequence.Count > 0)
					{
						var codeSequenceMacro = new CodeSequenceMacro(((DicomSequenceItem[]) result[DicomTags.PatientSpeciesCodeSequence].Values)[0]);
						item.PatientSpeciesCodeSequenceCodingSchemeDesignator = codeSequenceMacro.CodingSchemeDesignator;
						item.PatientSpeciesCodeSequenceCodeValue = codeSequenceMacro.CodeValue;
						item.PatientSpeciesCodeSequenceCodeMeaning = codeSequenceMacro.CodeMeaning;
					}

					item.PatientBreedDescription = result[DicomTags.PatientBreedDescription].GetString(0, "");
					var patientBreedCodeSequence = result[DicomTags.PatientBreedCodeSequence];
					if (!patientBreedCodeSequence.IsNull && patientBreedCodeSequence.Count > 0)
					{
						var codeSequenceMacro = new CodeSequenceMacro(((DicomSequenceItem[])result[DicomTags.PatientBreedCodeSequence].Values)[0]);
                        item.PatientBreedCodeSequenceCodingSchemeDesignator = codeSequenceMacro.CodingSchemeDesignator;
						item.PatientBreedCodeSequenceCodeValue = codeSequenceMacro.CodeValue;
						item.PatientBreedCodeSequenceCodeMeaning = codeSequenceMacro.CodeMeaning;
					}

					item.ResponsiblePerson = new PersonName(result[DicomTags.ResponsiblePerson].GetString(0, ""));
					item.ResponsiblePersonRole = result[DicomTags.ResponsiblePersonRole].GetString(0, "");
					item.ResponsibleOrganization = result[DicomTags.ResponsibleOrganization].GetString(0, "");

					studyItemList.Add(item);
				}
			}

			AuditHelper.LogQueryIssued(null, null, EventSource.CurrentUser, EventResult.Success,
									   SopClass.StudyRootQueryRetrieveInformationModelFindUid, collection);

			return studyItemList;
		}