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])); } }
/// <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; }
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]); }
/// <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; }
/// <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"); } }
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; }
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; }