Пример #1
0
            /// <summary>
            /// Creates and populates a <see cref="Volume"/> from the builder's source frames.
            /// </summary>
            public Volume Build()
            {
                PrepareFrames(_frames);                 // this also sorts the frames into order by slice location

                // Construct a model SOP data source based on the first frame's DICOM header
                var sopDataSourcePrototype = VolumeSopDataSourcePrototype.Create(_frames.Select(f => (IDicomAttributeProvider)f.Sop.DataSource).ToList(), 16, 16, false);

                // compute normalized modality LUT
                double normalizedSlope, normalizedIntercept;

                ComputeNormalizedModalityLut(_frames, out normalizedSlope, out normalizedIntercept);
                sopDataSourcePrototype[DicomTags.RescaleSlope].SetFloat64(0, normalizedSlope);
                sopDataSourcePrototype[DicomTags.RescaleIntercept].SetFloat64(0, normalizedIntercept);
                sopDataSourcePrototype[DicomTags.RescaleType] = _frames[0].Sop.DataSource[DicomTags.RescaleType].Copy();
                sopDataSourcePrototype[DicomTags.Units]       = _frames[0].Sop.DataSource[DicomTags.Units].Copy();           // PET series use this attribute to designate rescale units

                // compute normalized VOI windows
                VoiWindow.SetWindows(ComputeNormalizedVoiWindows(_frames, normalizedSlope, normalizedIntercept), sopDataSourcePrototype);

                // compute the volume padding value
                var pixelPaddingValue = ComputePixelPaddingValue(_frames, normalizedSlope, normalizedIntercept);

                int minVolumeValue, maxVolumeValue;
                var volumeArray = BuildVolumeArray(pixelPaddingValue, normalizedSlope, normalizedIntercept, out minVolumeValue, out maxVolumeValue);
                var volume      = new Volume(null, volumeArray, VolumeSize, VoxelSpacing, ImagePositionPatient, ImageOrientationPatient, sopDataSourcePrototype, pixelPaddingValue, _frames[0].Frame.SeriesInstanceUid, minVolumeValue, maxVolumeValue);

                return(volume);
            }
Пример #2
0
        private Volume(short[] dataInt16, ushort[] dataUInt16, Size3D dimensions, Vector3D spacing, Vector3D originPatient, Matrix orientationPatient, VolumeSopDataSourcePrototype sopDataSourcePrototype, int paddingValue, string sourceSeriesInstanceUid, int minVolumeValue, int maxVolumeValue)
        {
            Platform.CheckTrue(dataInt16 != null ^ dataUInt16 != null, "Exactly one of dataInt16 and dataUInt16 must be non-null.");
            _volumeDataInt16          = dataInt16;
            _volumeDataUInt16         = dataUInt16;
            _sourceSeriesInstanceUid  = sourceSeriesInstanceUid;
            _minVolumeValue           = minVolumeValue;
            _maxVolumeValue           = maxVolumeValue;
            _arrayDimensions          = dimensions;
            _voxelSpacing             = spacing;
            _originPatient            = originPatient;
            _orientationPatientMatrix = orientationPatient;
            _modelDicom   = sopDataSourcePrototype;
            _paddingValue = paddingValue;

            // Generate a descriptive name for the volume
            PersonName patientName       = new PersonName(sopDataSourcePrototype[DicomTags.PatientsName].ToString());
            string     patientId         = sopDataSourcePrototype[DicomTags.PatientId].ToString();
            string     seriesDescription = sopDataSourcePrototype[DicomTags.SeriesDescription].ToString();

            if (string.IsNullOrEmpty(seriesDescription))
            {
                _description = string.Format(SR.FormatVolumeLabel, patientName.FormattedName, patientId, seriesDescription);
            }
            else
            {
                _description = string.Format(SR.FormatVolumeLabelWithSeries, patientName.FormattedName, patientId, seriesDescription);
            }
        }
Пример #3
0
			public static VolumeSopDataSourcePrototype Create(IDicomAttributeProvider source, int bitsAllocated, int bitsStored, bool isSigned)
			{
				VolumeSopDataSourcePrototype prototype = new VolumeSopDataSourcePrototype();
				DicomAttributeCollection volumeDataSet = prototype._collection;

				// perform exact copy on the Patient Module
				foreach (uint tag in PatientModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Clinical Trial Subject Module
				foreach (uint tag in ClinicalTrialSubjectModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the General Study Module
				foreach (uint tag in GeneralStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Patient Study Module
				foreach (uint tag in PatientStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Clinical Trial Study Module
				foreach (uint tag in ClinicalTrialStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// TODO JY: flesh out these other modules.

				// generate and cache Series Module attributes that are common among all slicings
				volumeDataSet[DicomTags.Modality] = source[DicomTags.Modality].Copy();
				volumeDataSet[DicomTags.SeriesNumber].SetStringValue("0");
				volumeDataSet[DicomTags.SeriesDescription] = source[DicomTags.SeriesDescription].Copy();

				// generate General Equipment Module
				// these is a ticket to properly implement the GenEq module in all created instances.
				// the ticket is specific to KO and PR, but it should equally apply to these MPR SCs

				// generate SC Equipment Module
				volumeDataSet[DicomTags.ConversionType].SetStringValue("WSD");

				// generate General Image Module
				volumeDataSet[DicomTags.ImageType].SetStringValue(@"DERIVED\SECONDARY");
				volumeDataSet[DicomTags.PixelSpacing] = source[DicomTags.PixelSpacing].Copy();
				volumeDataSet[DicomTags.FrameOfReferenceUid] = source[DicomTags.FrameOfReferenceUid].Copy();

				// generate Image Pixel Module
				volumeDataSet[DicomTags.SamplesPerPixel] = source[DicomTags.SamplesPerPixel].Copy();
				volumeDataSet[DicomTags.PhotometricInterpretation] = source[DicomTags.PhotometricInterpretation].Copy();
				volumeDataSet[DicomTags.BitsAllocated].SetInt32(0, bitsAllocated);
				volumeDataSet[DicomTags.BitsStored].SetInt32(0, bitsStored);
				volumeDataSet[DicomTags.HighBit].SetInt32(0, bitsStored - 1);
				volumeDataSet[DicomTags.PixelRepresentation].SetInt32(0, isSigned ? 1 : 0);

				// generate SOP Common Module
				volumeDataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid);

				return prototype;
			}
Пример #4
0
 /// <summary>
 /// Constructs a <see cref="Volume"/> using a volume data array of unsigned 16-bit words.
 /// </summary>
 /// <remarks>
 /// Consider using one of the static helpers such as <see cref="Create(ClearCanvas.ImageViewer.IDisplaySet)"/> to construct and automatically fill a <see cref="Volume"/>.
 /// </remarks>
 public Volume(ushort[] data, Size3D dimensions, Vector3D spacing, Vector3D originPatient,
               Matrix orientationPatient, IList <IDicomAttributeProvider> dicomAttributeModel, int paddingValue, string sourceSeriesInstanceUid)
     : this(null, data, dimensions, spacing, originPatient, orientationPatient,
            VolumeSopDataSourcePrototype.Create(dicomAttributeModel, 16, 16, false), paddingValue, sourceSeriesInstanceUid, 0, 0)
 {
 }
Пример #5
0
            public static VolumeSopDataSourcePrototype Create(IList <IDicomAttributeProvider> sourceSops, int bitsAllocated, int bitsStored, bool isSigned)
            {
                const string enumYes      = "YES";
                const string enumNo       = "NO";
                const string enumLossy    = "01";
                const string enumLossless = "00";

                VolumeSopDataSourcePrototype prototype     = new VolumeSopDataSourcePrototype();
                DicomAttributeCollection     volumeDataSet = prototype._collection;
                IDicomAttributeProvider      source        = sourceSops[0];

                // perform exact copy on the Patient Module
                foreach (uint tag in PatientModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Clinical Trial Subject Module
                foreach (uint tag in ClinicalTrialSubjectModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the General Study Module
                foreach (uint tag in GeneralStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Patient Study Module
                foreach (uint tag in PatientStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Clinical Trial Study Module
                foreach (uint tag in ClinicalTrialStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the General Series Module except for tags that will be overridden as part of reformatting
                foreach (uint tag in GeneralSeriesModuleIod.DefinedTags.Except(new[] { DicomTags.LargestPixelValueInSeries, DicomTags.SmallestPixelValueInSeries, DicomTags.SeriesInstanceUid }))
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Clinical Trial Series Module
                foreach (uint tag in ClinicalTrialSeriesModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on additional modality specific modules in the series IE
                foreach (uint tag in ModalitySpecificSeriesModuleTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the General Equipment Module
                foreach (uint tag in GeneralEquipmentModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // generate values for SC Equipment Module
                var scEquipment = new ScEquipmentModuleIod(volumeDataSet);

                scEquipment.ConversionType = @"WSD";
                scEquipment.SecondaryCaptureDeviceManufacturer           = @"ClearCanvas Inc.";
                scEquipment.SecondaryCaptureDeviceManufacturersModelName = ProductInformation.GetName(true, false);
                scEquipment.SecondaryCaptureDeviceSoftwareVersions       = new[] { ProductInformation.GetVersion(true, true, true) };

                // fill series-consistent values for the Frame of Reference Module
                volumeDataSet[DicomTags.FrameOfReferenceUid] = source[DicomTags.FrameOfReferenceUid].Copy();

                // generate values for the General Image Module
                var burnedInAnnotationValues         = sourceSops.Select(s => s[DicomTags.BurnedInAnnotation].GetBoolean(0, enumYes, enumNo)).ToList();
                var burnedInAnnotation               = burnedInAnnotationValues.Any(v => v.GetValueOrDefault(false)) ? true : (burnedInAnnotationValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?)null);
                var recognizableVisualFeaturesValues = sourceSops.Select(s => s[DicomTags.RecognizableVisualFeatures].GetBoolean(0, enumYes, enumNo)).ToList();
                var recognizableVisualFeatures       = recognizableVisualFeaturesValues.Any(v => v.GetValueOrDefault(false)) ? true : (recognizableVisualFeaturesValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?)null);
                var lossyImageCompressionValues      = sourceSops.Select(s => s[DicomTags.LossyImageCompression].GetBoolean(0, enumLossy, enumLossless)).ToList();
                var lossyImageCompression            = lossyImageCompressionValues.Any(v => v.GetValueOrDefault(false)) ? true : (lossyImageCompressionValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?)null);
                var lossyImageCompressionRatioValues = sourceSops.Select(s => s[DicomTags.LossyImageCompressionRatio].GetFloat32(0, 0)).ToList();
                var lossyImageCompressionRatio       = lossyImageCompressionRatioValues.Max();

                volumeDataSet[DicomTags.ImageType].SetStringValue(@"DERIVED\SECONDARY");
                volumeDataSet[DicomTags.DerivationDescription].SetStringValue(@"Multiplanar Reformatting");
                volumeDataSet[DicomTags.DerivationCodeSequence].Values = new[] { new CodeSequenceMacro {
                                                                                     CodingSchemeDesignator = "DCM", CodeValue = "113072", CodeMeaning = "Multiplanar reformatting"
                                                                                 }.DicomSequenceItem };
                volumeDataSet[DicomTags.BurnedInAnnotation].SetBoolean(0, burnedInAnnotation, enumYes, enumNo);
                volumeDataSet[DicomTags.RecognizableVisualFeatures].SetBoolean(0, recognizableVisualFeatures, enumYes, enumNo);
                volumeDataSet[DicomTags.LossyImageCompression].SetBoolean(0, lossyImageCompression, enumLossy, enumLossless);
                if (lossyImageCompressionRatio > 0)
                {
                    volumeDataSet[DicomTags.LossyImageCompressionRatio].SetFloat32(0, lossyImageCompressionRatio);
                }
                // TODO: there's a SourceImageSequence here that we should probably fill out

                // fill series-consistent values for the Image Plane Module
                volumeDataSet[DicomTags.PixelSpacing] = source[DicomTags.PixelSpacing].Copy();

                // fill series-consistent values for the Image Pixel Module
                volumeDataSet[DicomTags.SamplesPerPixel]           = source[DicomTags.SamplesPerPixel].Copy();
                volumeDataSet[DicomTags.PhotometricInterpretation] = source[DicomTags.PhotometricInterpretation].Copy();
                volumeDataSet[DicomTags.BitsAllocated].SetInt32(0, bitsAllocated);
                volumeDataSet[DicomTags.BitsStored].SetInt32(0, bitsStored);
                volumeDataSet[DicomTags.HighBit].SetInt32(0, bitsStored - 1);
                volumeDataSet[DicomTags.PixelRepresentation].SetInt32(0, isSigned ? 1 : 0);

                // fill series-consistent values for the SOP Common Module
                volumeDataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid);

                return(prototype);
            }
Пример #6
0
 internal static IDicomAttributeProvider TestCreateSopDataSourcePrototype(IList <IDicomAttributeProvider> sourceSops, int bitsAllocated = 16, int bitsStored = 16, bool isSigned = false)
 {
     return(VolumeSopDataSourcePrototype.Create(sourceSops, bitsAllocated, bitsStored, isSigned));
 }
Пример #7
0
		private Volume(short[] dataInt16, ushort[] dataUInt16, Size3D dimensions, Vector3D spacing, Vector3D originPatient, Matrix orientationPatient, VolumeSopDataSourcePrototype sopDataSourcePrototype, int paddingValue, string sourceSeriesInstanceUid, int minVolumeValue, int maxVolumeValue)
		{
			Platform.CheckTrue(dataInt16 != null ^ dataUInt16 != null, "Exactly one of dataInt16 and dataUInt16 must be non-null.");
			_volumeDataInt16 = dataInt16;
			_volumeDataUInt16 = dataUInt16;
			_sourceSeriesInstanceUid = sourceSeriesInstanceUid;
			_minVolumeValue = minVolumeValue;
			_maxVolumeValue = maxVolumeValue;
			_arrayDimensions = dimensions;
			_voxelSpacing = spacing;
			_originPatient = originPatient;
			_orientationPatientMatrix = orientationPatient;
			_modelDicom = sopDataSourcePrototype;
			_paddingValue = paddingValue;

			// Generate a descriptive name for the volume
			PersonName patientName = new PersonName(sopDataSourcePrototype[DicomTags.PatientsName].ToString());
			string patientId = sopDataSourcePrototype[DicomTags.PatientId].ToString();
			string seriesDescription = sopDataSourcePrototype[DicomTags.SeriesDescription].ToString();
			if (string.IsNullOrEmpty(seriesDescription))
				_description = string.Format(SR.FormatVolumeLabel, patientName.FormattedName, patientId, seriesDescription);
			else
				_description = string.Format(SR.FormatVolumeLabelWithSeries, patientName.FormattedName, patientId, seriesDescription);
		}
			public static VolumeSopDataSourcePrototype Create(IList<IDicomAttributeProvider> sourceSops, int bitsAllocated, int bitsStored, bool isSigned)
			{
				const string enumYes = "YES";
				const string enumNo = "NO";
				const string enumLossy = "01";
				const string enumLossless = "00";

				VolumeSopDataSourcePrototype prototype = new VolumeSopDataSourcePrototype();
				DicomAttributeCollection volumeDataSet = prototype._collection;
				IDicomAttributeProvider source = sourceSops[0];

				// perform exact copy on the Patient Module
				foreach (uint tag in PatientModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Clinical Trial Subject Module
				foreach (uint tag in ClinicalTrialSubjectModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the General Study Module
				foreach (uint tag in GeneralStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Patient Study Module
				foreach (uint tag in PatientStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Clinical Trial Study Module
				foreach (uint tag in ClinicalTrialStudyModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the General Series Module except for tags that will be overridden as part of reformatting
				foreach (uint tag in GeneralSeriesModuleIod.DefinedTags.Except(new[] {DicomTags.LargestPixelValueInSeries, DicomTags.SmallestPixelValueInSeries, DicomTags.SeriesInstanceUid}))
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the Clinical Trial Series Module
				foreach (uint tag in ClinicalTrialSeriesModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on additional modality specific modules in the series IE
				foreach (uint tag in ModalitySpecificSeriesModuleTags)
					volumeDataSet[tag] = source[tag].Copy();

				// perform exact copy on the General Equipment Module
				foreach (uint tag in GeneralEquipmentModuleIod.DefinedTags)
					volumeDataSet[tag] = source[tag].Copy();

				// generate values for SC Equipment Module
				var scEquipment = new ScEquipmentModuleIod(volumeDataSet);
				scEquipment.ConversionType = @"WSD";
				scEquipment.SecondaryCaptureDeviceManufacturer = @"ClearCanvas Inc.";
				scEquipment.SecondaryCaptureDeviceManufacturersModelName = ProductInformation.GetName(true, false);
				scEquipment.SecondaryCaptureDeviceSoftwareVersions = new[] {ProductInformation.GetVersion(true, true, true)};

				// fill series-consistent values for the Frame of Reference Module
				volumeDataSet[DicomTags.FrameOfReferenceUid] = source[DicomTags.FrameOfReferenceUid].Copy();

				// generate values for the General Image Module
				var burnedInAnnotationValues = sourceSops.Select(s => s[DicomTags.BurnedInAnnotation].GetBoolean(0, enumYes, enumNo)).ToList();
				var burnedInAnnotation = burnedInAnnotationValues.Any(v => v.GetValueOrDefault(false)) ? true : (burnedInAnnotationValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?) null);
				var recognizableVisualFeaturesValues = sourceSops.Select(s => s[DicomTags.RecognizableVisualFeatures].GetBoolean(0, enumYes, enumNo)).ToList();
				var recognizableVisualFeatures = recognizableVisualFeaturesValues.Any(v => v.GetValueOrDefault(false)) ? true : (recognizableVisualFeaturesValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?) null);
				var lossyImageCompressionValues = sourceSops.Select(s => s[DicomTags.LossyImageCompression].GetBoolean(0, enumLossy, enumLossless)).ToList();
				var lossyImageCompression = lossyImageCompressionValues.Any(v => v.GetValueOrDefault(false)) ? true : (lossyImageCompressionValues.All(v => !v.GetValueOrDefault(true)) ? false : (bool?) null);
				var lossyImageCompressionRatioValues = sourceSops.Select(s => s[DicomTags.LossyImageCompressionRatio].GetFloat32(0, 0)).ToList();
				var lossyImageCompressionRatio = lossyImageCompressionRatioValues.Max();
				volumeDataSet[DicomTags.ImageType].SetStringValue(@"DERIVED\SECONDARY");
				volumeDataSet[DicomTags.DerivationDescription].SetStringValue(@"Multiplanar Reformatting");
				volumeDataSet[DicomTags.DerivationCodeSequence].Values = new[] {new CodeSequenceMacro {CodingSchemeDesignator = "DCM", CodeValue = "113072", CodeMeaning = "Multiplanar reformatting"}.DicomSequenceItem};
				volumeDataSet[DicomTags.BurnedInAnnotation].SetBoolean(0, burnedInAnnotation, enumYes, enumNo);
				volumeDataSet[DicomTags.RecognizableVisualFeatures].SetBoolean(0, recognizableVisualFeatures, enumYes, enumNo);
				volumeDataSet[DicomTags.LossyImageCompression].SetBoolean(0, lossyImageCompression, enumLossy, enumLossless);
				if (lossyImageCompressionRatio > 0)
					volumeDataSet[DicomTags.LossyImageCompressionRatio].SetFloat32(0, lossyImageCompressionRatio);
				// TODO: there's a SourceImageSequence here that we should probably fill out

				// fill series-consistent values for the Image Plane Module
				volumeDataSet[DicomTags.PixelSpacing] = source[DicomTags.PixelSpacing].Copy();

				// fill series-consistent values for the Image Pixel Module
				volumeDataSet[DicomTags.SamplesPerPixel] = source[DicomTags.SamplesPerPixel].Copy();
				volumeDataSet[DicomTags.PhotometricInterpretation] = source[DicomTags.PhotometricInterpretation].Copy();
				volumeDataSet[DicomTags.BitsAllocated].SetInt32(0, bitsAllocated);
				volumeDataSet[DicomTags.BitsStored].SetInt32(0, bitsStored);
				volumeDataSet[DicomTags.HighBit].SetInt32(0, bitsStored - 1);
				volumeDataSet[DicomTags.PixelRepresentation].SetInt32(0, isSigned ? 1 : 0);

				// fill series-consistent values for the SOP Common Module
				volumeDataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid);

				return prototype;
			}
Пример #9
0
            public static VolumeSopDataSourcePrototype Create(IDicomAttributeProvider source, int bitsAllocated, int bitsStored, bool isSigned)
            {
                VolumeSopDataSourcePrototype prototype     = new VolumeSopDataSourcePrototype();
                DicomAttributeCollection     volumeDataSet = prototype._collection;

                // perform exact copy on the Patient Module
                foreach (uint tag in PatientModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Clinical Trial Subject Module
                foreach (uint tag in ClinicalTrialSubjectModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the General Study Module
                foreach (uint tag in GeneralStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Patient Study Module
                foreach (uint tag in PatientStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // perform exact copy on the Clinical Trial Study Module
                foreach (uint tag in ClinicalTrialStudyModuleIod.DefinedTags)
                {
                    volumeDataSet[tag] = source[tag].Copy();
                }

                // TODO JY: flesh out these other modules.

                // generate and cache Series Module attributes that are common among all slicings
                volumeDataSet[DicomTags.Modality] = source[DicomTags.Modality].Copy();
                volumeDataSet[DicomTags.SeriesNumber].SetStringValue("0");
                volumeDataSet[DicomTags.SeriesDescription] = source[DicomTags.SeriesDescription].Copy();

                // generate General Equipment Module
                // these is a ticket to properly implement the GenEq module in all created instances.
                // the ticket is specific to KO and PR, but it should equally apply to these MPR SCs

                // generate SC Equipment Module
                volumeDataSet[DicomTags.ConversionType].SetStringValue("WSD");

                // generate General Image Module
                volumeDataSet[DicomTags.ImageType].SetStringValue(@"DERIVED\SECONDARY");
                volumeDataSet[DicomTags.PixelSpacing]        = source[DicomTags.PixelSpacing].Copy();
                volumeDataSet[DicomTags.FrameOfReferenceUid] = source[DicomTags.FrameOfReferenceUid].Copy();

                // generate Image Pixel Module
                volumeDataSet[DicomTags.SamplesPerPixel]           = source[DicomTags.SamplesPerPixel].Copy();
                volumeDataSet[DicomTags.PhotometricInterpretation] = source[DicomTags.PhotometricInterpretation].Copy();
                volumeDataSet[DicomTags.BitsAllocated].SetInt32(0, bitsAllocated);
                volumeDataSet[DicomTags.BitsStored].SetInt32(0, bitsStored);
                volumeDataSet[DicomTags.HighBit].SetInt32(0, bitsStored - 1);
                volumeDataSet[DicomTags.PixelRepresentation].SetInt32(0, isSigned ? 1 : 0);

                // generate SOP Common Module
                volumeDataSet[DicomTags.SopClassUid].SetStringValue(SopClass.SecondaryCaptureImageStorageUid);

                return(prototype);
            }