public InstanceXml(XmlNode instanceNode, DicomAttributeCollection baseCollection) { InstanceXmlDicomAttributeCollection thisCollection = new InstanceXmlDicomAttributeCollection(); _collection = thisCollection; _collection.ValidateVrValues = false; _collection.ValidateVrLengths = false; if (baseCollection != null) { AddExcludedTagsFromBase(baseCollection); _baseCollectionEnumerator = baseCollection.GetEnumerator(); if (!_baseCollectionEnumerator.MoveNext()) { _baseCollectionEnumerator = null; } } if (!instanceNode.HasChildNodes) { return; } _instanceXmlEnumerator = instanceNode.ChildNodes.GetEnumerator(); if (!_instanceXmlEnumerator.MoveNext()) { _instanceXmlEnumerator = null; } if (instanceNode.Attributes["UID"] != null) { _sopInstanceUid = instanceNode.Attributes["UID"].Value; } if (instanceNode.Attributes["SopClassUID"] != null) { _sopClass = SopClass.GetSopClass(instanceNode.Attributes["SopClassUID"].Value); } _transferSyntax = instanceNode.Attributes["TransferSyntaxUID"] != null ? TransferSyntax.GetTransferSyntax(instanceNode.Attributes["TransferSyntaxUID"].Value) : TransferSyntax.ExplicitVrLittleEndian; if (instanceNode.Attributes["SourceFileName"] != null) { _sourceFileName = instanceNode.Attributes["SourceFileName"].Value; } if (instanceNode.Attributes["FileSize"] != null) { long.TryParse(instanceNode.Attributes["FileSize"].Value, out _fileSize); } // This should never happen if (_sopClass == null) { _sopClass = SopClass.GetSopClass(Collection[DicomTags.SopClassUid].GetString(0, String.Empty)); } }
/// <summary> /// Constructs a deserialization-only DICOM softcopy presentation state object. /// </summary> /// <param name="psSopClass">The SOP class of this type of softcopy presentation state.</param> /// <param name="dicomFile">The presentation state file.</param> protected DicomSoftcopyPresentationState(SopClass psSopClass, DicomFile dicomFile) { if (dicomFile.MediaStorageSopClassUid != psSopClass.Uid) { string message = string.Format("Expected: {0}; Found: {1}", psSopClass, SopClass.GetSopClass(dicomFile.MediaStorageSopClassUid)); throw new ArgumentException("The specified DICOM file is not of a compatible SOP Class. " + message, "dicomFile"); } _presentationSopClass = psSopClass; _dicomFile = dicomFile; _serialized = true; _sourceAETitle = _dicomFile.SourceApplicationEntityTitle; _stationName = _dicomFile.DataSet[DicomTags.StationName].ToString(); _institution = Institution.GetInstitution(_dicomFile); _manufacturer = _dicomFile.DataSet[DicomTags.Manufacturer].ToString(); _manufacturersModelName = _dicomFile.DataSet[DicomTags.ManufacturersModelName].ToString(); _deviceSerialNumber = _dicomFile.DataSet[DicomTags.DeviceSerialNumber].ToString(); _softwareVersions = _dicomFile.DataSet[DicomTags.SoftwareVersions].ToString(); _presentationInstanceNumber = _dicomFile.DataSet[DicomTags.InstanceNumber].GetInt32(0, 0); _presentationSopInstanceUid = _dicomFile.DataSet[DicomTags.SopInstanceUid].ToString(); _presentationSeriesDateTime = DateTimeParser.ParseDateAndTime(_dicomFile.DataSet, 0, DicomTags.SeriesDate, DicomTags.SeriesTime); _presentationSeriesNumber = GetNullableInt32(_dicomFile.DataSet[DicomTags.SeriesNumber], 0); _presentationSeriesInstanceUid = _dicomFile.DataSet[DicomTags.SeriesInstanceUid].ToString(); _presentationLabel = _dicomFile.DataSet[DicomTags.ContentLabel].ToString(); }
public void TestCategories() { foreach (var sopClass in SopClass.GetRegisteredSopClasses()) { //In DICOM 2011: // a) all meta SOP class names contain "Meta" // b) all Image Storage SOP class names contain "Image Storage", except "Enhanced US Volume Storage" // c) all Storage SOP class names contain "Storage", excluding "Storage Commitment" if (sopClass.Name.ToLower().Contains("meta")) { Assert.IsTrue(sopClass.Meta); Assert.IsFalse(sopClass.IsStorage); Assert.IsFalse(sopClass.IsImage); } else if (sopClass.Name.ToLower().Contains("image storage") || sopClass.Name == "Enhanced US Volume Storage") { Assert.IsTrue(sopClass.IsImage); Assert.IsTrue(sopClass.IsStorage); Assert.IsFalse(sopClass.Meta); } else if (sopClass.Name.ToLower().Contains("storage") && !sopClass.Name.ToLower().Contains("storage commitment")) { Assert.IsTrue(sopClass.IsStorage); Assert.IsFalse(sopClass.IsImage); Assert.IsFalse(sopClass.Meta); } else { Assert.IsFalse(sopClass.IsImage); Assert.IsFalse(sopClass.IsStorage); Assert.IsFalse(sopClass.Meta); } } }
public void TestGet() { var uid = "1.2.3"; var retrieved = SopClass.GetSopClass(uid); Assert.AreEqual(uid, retrieved.Uid); }
public void TestRegister() { const string uid = "1.2.3"; var sopClass = new SopClass("Bleeding Edge Image", uid, SopClassCategory.Image); var registered = SopClass.RegisterSopClass(sopClass); Assert.AreEqual(uid, registered.Uid); var retrieved = SopClass.GetSopClass(uid); Assert.AreEqual(uid, retrieved.Uid); var reregistered = new SopClass("Bleeding Edge Image", uid, SopClassCategory.Image); Assert.IsTrue(SopClass.GetRegisteredSopClasses().Contains(reregistered)); reregistered = SopClass.RegisterSopClass(reregistered); Assert.IsTrue(ReferenceEquals(registered, reregistered)); var unregistered = SopClass.UnregisterSopClass(registered); Assert.IsTrue(ReferenceEquals(registered, unregistered)); Assert.IsFalse(SopClass.GetRegisteredSopClasses().Contains(registered)); unregistered = SopClass.UnregisterSopClass(registered); Assert.IsNull(unregistered); }
/// <summary> /// Load enough information from the file to allow negotiation of the association. /// </summary> public void LoadInfo() { if (_infoLoaded) { return; } DicomFile theFile = new DicomFile(_filename); theFile.Load(DicomTags.RelatedGeneralSopClassUid, DicomReadOptions.Default); string sopClassInFile = theFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(theFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", theFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = theFile.SopClass; } } else { _sopClass = theFile.SopClass; } _syntax = theFile.TransferSyntax; SopInstanceUid = theFile.MediaStorageSopInstanceUid; MetaInfoFileLength = theFile.MetaInfoFileLength; _infoLoaded = true; }
/// <summary> /// Returns a list of the services supported by this plugin. /// </summary> /// <returns></returns> public override IList <SupportedSop> GetSupportedSopClasses() { if (_list == null) { _list = new List <SupportedSop>(); // Get the SOP Classes using (IReadContext read = _store.OpenReadContext()) { // Set the input parameters for query PartitionSopClassQueryParameters inputParms = new PartitionSopClassQueryParameters(); inputParms.ServerPartitionKey = Partition.GetKey(); IQueryServerPartitionSopClasses broker = read.GetBroker <IQueryServerPartitionSopClasses>(); IList <PartitionSopClass> sopClasses = broker.Find(inputParms); // Now process the SOP Class List foreach (PartitionSopClass partitionSopClass in sopClasses) { if (partitionSopClass.Enabled && !partitionSopClass.NonImage) { SupportedSop sop = new SupportedSop(); sop.SopClass = SopClass.GetSopClass(partitionSopClass.SopClassUid); sop.SyntaxList.Add(TransferSyntax.ExplicitVrLittleEndian); sop.SyntaxList.Add(TransferSyntax.ImplicitVrLittleEndian); _list.Add(sop); } } } } return(_list); }
public IList <SupportedSop> GetStroageSupportedSopClasses() { var list = new List <SupportedSop>(); var storageAbstractSyntaxList = new List <SopClass>(); using (var ctx = new PacsContext()) { storageAbstractSyntaxList.AddRange( ctx.SupportedSopClasses.ToList().Select( sopClass => SopClass.GetSopClass(sopClass.SopClassUid))); } foreach (var abstractSyntax in storageAbstractSyntaxList) { var supportedSop = new SupportedSop { SopClass = abstractSyntax }; supportedSop.AddSyntax(TransferSyntax.ExplicitVrLittleEndian); supportedSop.AddSyntax(TransferSyntax.ImplicitVrLittleEndian); list.Add(supportedSop); } return(list); }
/// <summary> /// Constructor. /// </summary> /// <param name="dicomFile"></param> public StorageInstance(DicomFile dicomFile) { _dicomFile = dicomFile; string sopClassInFile = _dicomFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(_dicomFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", _dicomFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = _dicomFile.SopClass; } } else { _sopClass = _dicomFile.SopClass; } _syntax = _dicomFile.TransferSyntax; SopInstanceUid = _dicomFile.MediaStorageSopInstanceUid; _filename = dicomFile.Filename; StudyInstanceUid = _dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = _dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); PatientsName = _dicomFile.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = _dicomFile.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
/// <summary> /// Load a list of preferred SOP Classes and Transfer Syntaxes for a Device. /// </summary> /// <param name="read">A read context to read from the database.</param> public void LoadPreferredSyntaxes(IPersistenceContext read) { var select = read.GetBroker <IDevicePreferredTransferSyntaxEntityBroker>(); // Setup the select parameters. var criteria = new DevicePreferredTransferSyntaxSelectCriteria(); criteria.DeviceKey.EqualTo(_remoteDevice.GetKey()); IList <DevicePreferredTransferSyntax> list = select.Find(criteria); // Translate the list returned into the database into a list that is supported by the Storage SCU Component var sopList = new List <SupportedSop>(); foreach (DevicePreferredTransferSyntax preferred in list) { var sop = new SupportedSop { SopClass = SopClass.GetSopClass(preferred.GetServerSopClass().SopClassUid) }; sop.AddSyntax(TransferSyntax.GetTransferSyntax(preferred.GetServerTransferSyntax().Uid)); sopList.Add(sop); } SetPreferredSyntaxList(sopList); }
/// <summary> /// Constructor for primary usage with the <see cref="StorageCommitScu"/> class. /// </summary> /// <param name="sopClass">The SOP Class for a DICOM instance</param> /// <param name="sopInstanceUid">The SOP Instance UID of a DICOM instance</param> public StorageInstance(SopClass sopClass, string sopInstanceUid) { _sopClass = sopClass; SopInstanceUid = sopInstanceUid; StudyInstanceUid = string.Empty; SeriesInstanceUid = string.Empty; _filename = String.Empty; }
public void TestGetSopClass() { const string uid = "1.2.3"; var retrieved = SopClass.GetSopClass(uid); Assert.AreEqual(uid, retrieved.Uid); Assert.IsTrue(!SopClass.GetRegisteredSopClasses().Contains(retrieved)); }
/// <summary> /// Constructor. /// </summary> /// <param name="collection"></param> protected DicomPixelData(DicomDataset collection) { collection.LoadDicomFields(this); SopClass = SopClass.GetSopClass(collection[DicomTags.SopClassUid].GetString(0, string.Empty)); if (collection.Contains(DicomTags.NumberOfFrames)) { NumberOfFrames = collection[DicomTags.NumberOfFrames].GetInt32(0, 1); } if (collection.Contains(DicomTags.PlanarConfiguration)) { PlanarConfiguration = collection[DicomTags.PlanarConfiguration].GetUInt16(0, 1); } if (collection.Contains(DicomTags.LossyImageCompression)) { LossyImageCompression = collection[DicomTags.LossyImageCompression].GetString(0, string.Empty); } if (collection.Contains(DicomTags.LossyImageCompressionRatio)) { LossyImageCompressionRatio = collection[DicomTags.LossyImageCompressionRatio].GetFloat32(0, 1.0f); } if (collection.Contains(DicomTags.LossyImageCompressionMethod)) { LossyImageCompressionMethod = collection[DicomTags.LossyImageCompressionMethod].GetString(0, string.Empty); } if (collection.Contains(DicomTags.DerivationDescription)) { DerivationDescription = collection[DicomTags.DerivationDescription].GetString(0, string.Empty); } if (collection.Contains(DicomTags.RescaleSlope)) { RescaleSlope = collection[DicomTags.RescaleSlope].ToString(); } if (collection.Contains(DicomTags.RescaleIntercept)) { RescaleIntercept = collection[DicomTags.RescaleIntercept].ToString(); } if (collection.Contains(DicomTags.ModalityLutSequence)) { DicomElement attrib = collection[DicomTags.ModalityLutSequence]; _hasDataModalityLut = !attrib.IsEmpty && !attrib.IsNull; } _linearVoiLuts = Window.GetWindowCenterAndWidth(collection); if (collection.Contains(DicomTags.VoiLutSequence)) { DicomElement attrib = collection[DicomTags.VoiLutSequence]; _hasDataVoiLuts = !attrib.IsEmpty && !attrib.IsNull; } if (PhotometricInterpretation.Equals(Iod.PhotometricInterpretation.PaletteColor.Code) && collection.Contains(DicomTags.RedPaletteColorLookupTableDescriptor)) { _paletteColorLut = PaletteColorLut.Create(collection); _hasPaletteColorLut = true; } }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// The constructor creates a dictionary of each presentation context negotiated for the /// association, and the plugin that will handle it. This is used later when incoming request /// messages are processed. /// </remarks> /// <param name="server">The server.</param> /// <param name="parameters">Association parameters for the negotiated association.</param> /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param> /// <param name="verifier">Delegate to call to verify an association before its accepted.</param> /// <param name="complete">Delegate to call when the association is closed/complete. Can be null.</param> public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete) { _context = userParms; _verifier = verifier; _complete = complete; var ep = new DicomScpExtensionPoint <TContext>(); object[] scps = ep.CreateExtensions(); // First set the user parms for each of the extensions before we do anything with them. foreach (object obj in scps) { var scp = obj as IDicomScp <TContext>; if (scp != null) { scp.SetContext(_context); } } // Now, create a dictionary with the extension to be used for each presentation context. foreach (byte pcid in parameters.GetPresentationContextIDs()) { if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept) { SopClass acceptedSop = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID); TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid); foreach (object obj in scps) { var scp = obj as IDicomScp <TContext>; if (scp == null) { continue; } IList <SupportedSop> sops = scp.GetSupportedSopClasses(); foreach (SupportedSop sop in sops) { if (sop.SopClass.Equals(acceptedSop)) { if (sop.SyntaxList.Contains(acceptedSyntax)) { if (!_extensionList.ContainsKey(pcid)) { _extensionList.Add(pcid, scp); break; } Platform.Log(LogLevel.Error, "SOP Class {0} supported by more than one extension", sop.SopClass.Name); } } } } } } _statsRecorder = new AssociationStatisticsRecorder(server); }
public DicomPresContext(byte pcid, SopClass abstractSyntax) { _pcid = pcid; _result = DicomPresContextResult.Proposed; _roles = DicomRoleSelection.Disabled; _abstract = abstractSyntax; if (abstractSyntax.Uid.Length == 0) throw new DicomException("Invalid abstract syntax for presentation context, UID is zero length."); _transfers = new List<TransferSyntax>(); }
private static ISopDataSource CreateMockDataset(string modality, SopClass sopClass, SizeF?imagerPixelSpacing, SizeF?pixelSpacing, string pixelSpacingCalibrationType, string pixelSpacingCalibrationDescription, double?estimatedRadiographicMagnification) { var dicomFile = new DicomFile(); var dataset = dicomFile.DataSet; dataset[DicomTags.PatientId].SetStringValue("PATIENT"); dataset[DicomTags.PatientsName].SetStringValue("YOSHI"); dataset[DicomTags.StudyId].SetStringValue("STUDY"); dataset[DicomTags.SeriesDescription].SetStringValue("SERIES"); dataset[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dataset[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dataset[DicomTags.Modality].SetStringValue(modality); dataset[DicomTags.SopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dataset[DicomTags.SopClassUid].SetStringValue(sopClass.Uid); dataset[DicomTags.FrameOfReferenceUid].SetStringValue(DicomUid.GenerateUid().UID); dataset[DicomTags.PhotometricInterpretation].SetStringValue("MONOCHROME2"); dataset[DicomTags.BitsStored].SetInt32(0, 16); dataset[DicomTags.BitsAllocated].SetInt32(0, 16); dataset[DicomTags.HighBit].SetInt32(0, 15); dataset[DicomTags.PixelRepresentation].SetInt32(0, 0); dataset[DicomTags.Rows].SetInt32(0, 100); dataset[DicomTags.Columns].SetInt32(0, 100); dataset[DicomTags.WindowCenter].SetInt32(0, 32768); dataset[DicomTags.WindowWidth].SetInt32(0, 65536); dataset[DicomTags.WindowCenterWidthExplanation].SetString(0, "Full Window"); if (imagerPixelSpacing.HasValue) { dataset[DicomTags.ImagerPixelSpacing].SetFloat32(0, imagerPixelSpacing.Value.Height); dataset[DicomTags.ImagerPixelSpacing].SetFloat32(1, imagerPixelSpacing.Value.Width); } if (pixelSpacing.HasValue) { dataset[DicomTags.PixelSpacing].SetFloat32(0, pixelSpacing.Value.Height); dataset[DicomTags.PixelSpacing].SetFloat32(1, pixelSpacing.Value.Width); } if (!string.IsNullOrEmpty(pixelSpacingCalibrationType)) { dataset[DicomTags.PixelSpacingCalibrationType].SetStringValue(pixelSpacingCalibrationType); } if (!string.IsNullOrEmpty(pixelSpacingCalibrationDescription)) { dataset[DicomTags.PixelSpacingCalibrationDescription].SetStringValue(pixelSpacingCalibrationDescription); } if (estimatedRadiographicMagnification.HasValue) { dataset[DicomTags.EstimatedRadiographicMagnificationFactor].SetFloat64(0, estimatedRadiographicMagnification.Value); } return(new TestDataSource(dicomFile)); }
public InstanceXml(DicomAttributeCollection collection, SopClass sopClass, TransferSyntax syntax) { _sopInstanceUid = collection[DicomTags.SopInstanceUid]; _collection = collection; _sopClass = sopClass; _transferSyntax = syntax; _collection.ValidateVrValues = false; _collection.ValidateVrLengths = false; }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax. If it can't find it, throws an <see cref="DicomException"/>. /// It is useful to throw an exception for for a Scu, so we don't have to keep checking for a valid pcid. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <returns>Presentation Context ID</returns> /// <exception cref="DicomException"/> public byte FindAbstractSyntaxOrThrowException(SopClass abstractSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid) { return(ctx.ID); } } throw new DicomException("Cannot find abstract syntax in presentation context: " + abstractSyntax.ToString()); }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax and Transfer Syntax. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <param name="transferSyntax">Transfer Syntax</param> /// <returns>Presentation Context ID</returns> public byte FindAbstractSyntaxWithTransferSyntax(SopClass abstractSyntax, TransferSyntax transferSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid && ctx.HasTransfer(transferSyntax)) { return(ctx.ID); } } return(0); }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax, or 0 if it can't find it. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <returns>Presentation Context ID, or 0 if it can't find it.</returns> public byte FindAbstractSyntax(SopClass abstractSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid) { return(ctx.ID); } } return(0); }
public DicomPresContext(byte pcid, SopClass abstractSyntax) { _pcid = pcid; _result = DicomPresContextResult.Proposed; _roles = DicomRoleSelection.Disabled; _abstract = abstractSyntax; if (abstractSyntax.Uid.Length == 0) { throw new DicomException("Invalid abstract syntax for presentation context, UID is zero length."); } _transfers = new List <TransferSyntax>(); }
public void ListAmbiguousTagsBySopClass() { foreach (var uid in _multiframeSopClassUids) { const string msg = "SOP Class: {0}"; Console.WriteLine(msg, SopClass.GetSopClass(uid).Name); ListTagsByParentSequence(FunctionalGroupDescriptor.GetApplicableFunctionalGroups(uid).Select(f => f.Create()), true); Console.WriteLine(new string('=', 32)); Console.WriteLine(); } }
public StorageInstance(DicomMessage msg) { _sopClass = msg.SopClass; _syntax = msg.TransferSyntax; _sopInstanceUid = msg.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty); _studyInstanceUid = msg.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); _patientsName = msg.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); _patientId = msg.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
public void TestTagMappingBySopClass() { foreach (var uid in _multiframeSopClassUids) { var sopClass = SopClass.GetSopClass(uid).Name; var functionalGroups = FunctionalGroupDescriptor.GetApplicableFunctionalGroups(uid).ToList(); var tagGroups = functionalGroups.Select(f => f.Create()) .SelectMany(f => f.NestedTags.Select(t => new { TagValue = t, FunctionalGroup = f })) .GroupBy(u => u.TagValue).OrderBy(u => u.Key).ToList(); foreach (var group in tagGroups) { var dcmTag = DicomTagDictionary.GetDicomTag(group.Key); // asserts that any tag defined in 'singleton' functional groups (those whose sequence can have at most 1 item) should have at least some mapping var fgType = FunctionalGroupDescriptor.GetFunctionalGroupByTag(uid, group.Key); if (fgType == null) { foreach (var entry in group) { Assert.IsTrue(entry.FunctionalGroup.CanHaveMultipleItems, "At least one singleton functional group defines tag {0} for SOP class {1}", dcmTag, sopClass); } } // explicitly assert the mapping for any tag defined by multiple 'singleton' functional groups - so that if new tags are introduced later, we would explicitly consider what is the correct mapping if (group.Count(g => !g.FunctionalGroup.CanHaveMultipleItems) > 1) { const string wrongMapMsg = "SOP Class {0} maps tag {1} to the wrong functional group"; if (uid == SopClass.EnhancedXaImageStorageUid) { switch (group.Key) { case DicomTags.TableHorizontalRotationAngle: case DicomTags.TableHeadTiltAngle: case DicomTags.TableCradleTiltAngle: Assert.AreEqual(new FunctionalGroupDescriptor(typeof(XRayTablePositionFunctionalGroup)), fgType, wrongMapMsg, sopClass, dcmTag); break; default: Assert.Fail("SOP Class {0} shouldn't have an ambiguous mapping for tag {1} - if new tags were added, please explicitly update the expected mapping in this unit test", sopClass, dcmTag); break; } } else { Assert.Fail("SOP Class {0} shouldn't have any ambiguous mappings - if new tags were added, please explicitly update the expected mapping in this unit test", sopClass); } } } } }
public PlaceholderPresentationImage(Sop sop) : base(new GrayscaleImageGraphic(1, 1)) { _sopReference = sop.CreateTransientReference(); var sopClass = SopClass.GetSopClass(sop.SopClassUid); var sopClassDescription = sopClass != null ? sopClass.Name : SR.LabelUnknown; CompositeImageGraphic.Graphics.Add(new ErrorMessageGraphic { Text = string.Format(SR.MessageUnsupportedImageType, sopClassDescription), Color = Color.WhiteSmoke }); Platform.Log(LogLevel.Warn, "Unsupported SOP Class \"{0} ({1})\" (SOP Instance {2})", sopClassDescription, sop.SopClassUid, sop.SopInstanceUid); }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// The constructor creates a dictionary of each presentation context negotiated for the /// association, and the plugin that will handle it. This is used later when incoming request /// messages are processed. /// </remarks> /// <param name="server">The server.</param> /// <param name="parameters">Association parameters for the negotiated association.</param> /// <param name="userParms">User parameters to be passed to the plugins called by the class.</param> /// <param name="verifier">Delegate to call to verify an association before its accepted.</param> /// <param name="complete">Delegate to call when the association is closed/complete. Can be null.</param> public DicomScpHandler(DicomServer server, ServerAssociationParameters parameters, TContext userParms, DicomScp <TContext> .AssociationVerifyCallback verifier, DicomScp <TContext> .AssociationComplete complete) { _context = userParms; _verifier = verifier; _complete = complete; List <IDicomScp <TContext> > scps = Platform.Instance.CompositionContainer.GetExportedValues <IDicomScp <TContext> >().Select(scp => scp). ToList(); // First set the user parms for each of the extensions before we do anything with them. foreach (object obj in scps) { IDicomScp <TContext> scp = obj as IDicomScp <TContext>; scp.SetContext(_context); } // Now, create a dictionary with the extension to be used for each presentation context. foreach (byte pcid in parameters.GetPresentationContextIDs()) { if (parameters.GetPresentationContextResult(pcid) == DicomPresContextResult.Accept) { SopClass acceptedSop = SopClass.GetSopClass(parameters.GetAbstractSyntax(pcid).UID); TransferSyntax acceptedSyntax = parameters.GetAcceptedTransferSyntax(pcid); foreach (object obj in scps) { IDicomScp <TContext> scp = obj as IDicomScp <TContext>; IList <SupportedSop> sops = scp.GetSupportedSopClasses(); foreach (SupportedSop sop in sops) { if (sop.SopClass.Equals(acceptedSop)) { if (sop.SyntaxList.Contains(acceptedSyntax)) { if (!_extensionList.ContainsKey(pcid)) { _extensionList.Add(pcid, scp); break; } else { LogAdapter.Logger.ErrorWithFormat("SOP Class {0} supported by more than one extension", sop.SopClass.Name); } } } } } } } }
protected static IEnumerable <SopClass> GetSopClasses(IEnumerable <string> sopClassUids) { foreach (var sopClassUid in sopClassUids) { if (!String.IsNullOrEmpty(sopClassUid)) { SopClass sopClass = SopClass.GetSopClass(sopClassUid); if (sopClass != null) { yield return(sopClass); } } } }
public void TestRegister() { var uid = "1.2.3"; var sopClass = new SopClass("Bleeding Edge Image", uid, SopClassCategory.Image); var registered = SopClass.RegisterSopClass(sopClass); Assert.AreEqual(uid, registered.Uid); var retrieved = SopClass.GetSopClass(uid); Assert.AreEqual(uid, retrieved.Uid); var reregistered = new SopClass("Bleeding Edge Image", uid, SopClassCategory.Image); reregistered = SopClass.RegisterSopClass(reregistered); Assert.IsTrue(ReferenceEquals(registered, reregistered)); }
/// <summary> /// Adds a Presentation Context to the DICOM Associate. /// </summary> /// <remarks> /// <para> /// Note, this method will create a new presentation context for the /// <see cref="SopClass"/> even if one already exists for the /// <see cref="SopClass"/>. /// </para> /// </remarks> public byte AddPresentationContext(SopClass abstractSyntax) { byte pcid = 1; foreach (byte id in _presContexts.Keys) { //if (_presContexts[id].AbstractSyntax == abstractSyntax) // return id; if (id >= pcid) { pcid = (byte)(id + 2); } } AddPresentationContext(pcid, abstractSyntax); return(pcid); }
/// <summary> /// Serialize to a JSON object /// </summary> public new void SerializeJson(Utf8JsonWriter writer, JsonSerializerOptions options, bool includeStartObject = true) { if (includeStartObject) { writer.WriteStartObject(); } ((Fhir.R4.Models.BackboneElement) this).SerializeJson(writer, options, false); if (!string.IsNullOrEmpty(Uid)) { writer.WriteString("uid", (string)Uid !); } if (_Uid != null) { writer.WritePropertyName("_uid"); _Uid.SerializeJson(writer, options); } if (SopClass != null) { writer.WritePropertyName("sopClass"); SopClass.SerializeJson(writer, options); } if (Number != null) { writer.WriteNumber("number", (uint)Number !); } if (!string.IsNullOrEmpty(Title)) { writer.WriteString("title", (string)Title !); } if (_Title != null) { writer.WritePropertyName("_title"); _Title.SerializeJson(writer, options); } if (includeStartObject) { writer.WriteEndObject(); } }
private static IEnumerable <ISopDataSource> CreateSopSeries(int sopCount, string patientId, string patientName, string studyId, string studyInstanceUid, string seriesDesc, int seriesNumber, string seriesInstanceUid, string frameOfReferenceUid, string modality, SopClass sopClass, DicomDataSetInitializer initializer) { for (int n = 0; n < sopCount; n++) { var dicomFile = new DicomFile(); var dataset = dicomFile.DataSet; if (initializer != null) { initializer.Invoke(dataset); } dataset[DicomTags.PatientId].SetStringValue(patientId); dataset[DicomTags.PatientsName].SetStringValue(patientName); dataset[DicomTags.StudyId].SetStringValue(studyId); dataset[DicomTags.StudyInstanceUid].SetStringValue(studyInstanceUid); dataset[DicomTags.SeriesDescription].SetStringValue(seriesDesc); dataset[DicomTags.SeriesNumber].SetInt32(0, seriesNumber); dataset[DicomTags.SeriesInstanceUid].SetStringValue(seriesInstanceUid); dataset[DicomTags.SopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID); dataset[DicomTags.SopClassUid].SetStringValue(sopClass.Uid); dataset[DicomTags.Modality].SetStringValue(modality.ToString()); dataset[DicomTags.FrameOfReferenceUid].SetStringValue(frameOfReferenceUid); dataset[DicomTags.ImageOrientationPatient].SetStringValue(string.Format(@"{0}\{1}\{2}\{3}\{4}\{5}", 1, 0, 0, 0, 1, 0)); dataset[DicomTags.ImagePositionPatient].SetStringValue(string.Format(@"{0}\{1}\{2}", 0, 0, n)); dataset[DicomTags.PixelSpacing].SetStringValue(string.Format(@"{0}\{1}", 0.5, 0.5)); dataset[DicomTags.PhotometricInterpretation].SetStringValue("MONOCHROME2"); dataset[DicomTags.SamplesPerPixel].SetInt32(0, 1); dataset[DicomTags.BitsStored].SetInt32(0, 16); dataset[DicomTags.BitsAllocated].SetInt32(0, 16); dataset[DicomTags.HighBit].SetInt32(0, 15); dataset[DicomTags.PixelRepresentation].SetInt32(0, 1); dataset[DicomTags.Rows].SetInt32(0, 100); dataset[DicomTags.Columns].SetInt32(0, 100); dataset[DicomTags.WindowCenter].SetInt32(0, 0); dataset[DicomTags.WindowWidth].SetInt32(0, 65536); dataset[DicomTags.WindowCenterWidthExplanation].SetString(0, "Full Window"); dataset[DicomTags.PixelData].Values = new byte[2 * 100 * 100]; dicomFile.MediaStorageSopClassUid = dataset[DicomTags.SopClassUid]; dicomFile.MediaStorageSopInstanceUid = dataset[DicomTags.SopInstanceUid]; yield return(new XSopDataSource(dicomFile)); } }
/// <summary> /// Returns a list of the DICOM services supported by this plugin. /// </summary> /// <returns></returns> public override IList <SupportedSop> GetSupportedSopClasses() { if (!Context.AllowStorage) { return(new List <SupportedSop>()); } // Note: this method is called on startup to set the server's presentation contexts and then on every association. // If the settings change between those calls, the server may either throw an exception (if the sop is removed) or // does not behave as expected unless the server is restarted. if (_list == null) { // Load from the database the non-image sops that are current configured for this server partition. _list = new List <SupportedSop>(); var partitionSopClassConfig = new PartitionSopClassConfiguration(); var sopClasses = partitionSopClassConfig.GetAllPartitionSopClasses(Partition); if (sopClasses != null) { // Now process the SOP Class list foreach (PartitionSopClass partitionSopClass in sopClasses) { if (partitionSopClass.Enabled && partitionSopClass.NonImage) { var sop = new SupportedSop { SopClass = SopClass.GetSopClass(partitionSopClass.SopClassUid) }; if (!partitionSopClass.ImplicitOnly) { sop.SyntaxList.Add(TransferSyntax.ExplicitVrLittleEndian); } sop.SyntaxList.Add(TransferSyntax.ImplicitVrLittleEndian); _list.Add(sop); } } } } return(_list); }
/// <summary> /// Load enough information from the file to allow negotiation of the association. /// </summary> public void LoadInfo() { if (_infoLoaded) return; var theFile = new DicomFile(); const uint stopTag = DicomTags.StudyId; theFile.Load(StreamOpener, DicomTagDictionary.GetDicomTag(stopTag), DicomReadOptions.Default); string sopClassInFile = theFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(theFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", theFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = theFile.SopClass; } } else _sopClass = theFile.SopClass; _syntax = theFile.TransferSyntax; // these fields must be loaded for auditing purposes, and LoadFile() may not get called StudyInstanceUid = theFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = theFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); SopInstanceUid = theFile.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty); PatientsName = theFile.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = theFile.DataSet[DicomTags.PatientId].GetString(0, string.Empty); MetaInfoFileLength = theFile.MetaInfoFileLength; _infoLoaded = true; }
/// <summary> /// Constructor for primary usage with the <see cref="StorageCommitScu"/> class. /// </summary> /// <param name="sopClass">The SOP Class for a DICOM instance</param> /// <param name="sopInstanceUid">The SOP Instance UID of a DICOM instance</param> public StorageInstance(SopClass sopClass, string sopInstanceUid) { _sopClass = sopClass; _sopInstanceUid = sopInstanceUid; _filename = String.Empty; }
public void TestEquality() { // ReSharper disable ExpressionIsAlwaysNull var sop0 = (SopClass) null; var sopA = new SopClass("a", "1.2.3", SopClassCategory.Image); var sopA2 = new SopClass("a2", "1.2.3", SopClassCategory.Meta); var sopA3 = sopA; var sopB = new SopClass("b", "1.2.3.4", SopClassCategory.Image); Assert.IsTrue(null == sop0); Assert.IsTrue(sop0 == null); Assert.IsTrue(Equals(null, sop0)); Assert.IsTrue(Equals(sop0, null)); Assert.IsTrue(sopA == sopA2); Assert.IsTrue(sopA2 == sopA); Assert.IsTrue(Equals(sopA, sopA2)); Assert.IsTrue(Equals(sopA2, sopA)); Assert.IsTrue(sopA == sopA3); Assert.IsTrue(sopA3 == sopA); Assert.IsTrue(Equals(sopA, sopA3)); Assert.IsTrue(Equals(sopA3, sopA)); Assert.IsFalse(sop0 == sopA); Assert.IsFalse(sopA == sop0); Assert.IsFalse(Equals(sop0, sopA)); Assert.IsFalse(Equals(sopA, sop0)); Assert.IsFalse(sopA == sopB); Assert.IsFalse(sopB == sopA); Assert.IsFalse(Equals(sopA, sopB)); Assert.IsFalse(Equals(sopB, sopA)); // ReSharper restore ExpressionIsAlwaysNull }
public void Read(RawPDU raw) { uint l = raw.Length; raw.ReadUInt16("Version"); raw.SkipBytes("Reserved", 2); _assoc.CalledAE = raw.ReadString("Called AE", 16); _assoc.CallingAE = raw.ReadString("Calling AE", 16); raw.SkipBytes("Reserved", 32); l -= 2 + 2 + 16 + 16 + 32; while (l > 0) { byte type = raw.ReadByte("Item-Type"); raw.SkipBytes("Reserved", 1); ushort il = raw.ReadUInt16("Item-Length"); l -= 4 + (uint)il; if (type == 0x10) { // Application Context raw.SkipBytes("Application Context", il); } else if (type == 0x20) { // Presentation Context byte id = raw.ReadByte("Presentation Context ID"); raw.SkipBytes("Reserved", 3); il -= 4; while (il > 0) { byte pt = raw.ReadByte("Presentation Context Item-Type"); raw.SkipBytes("Reserved", 1); ushort pl = raw.ReadUInt16("Presentation Context Item-Length"); string sx = raw.ReadString("Presentation Context Syntax UID", pl); if (pt == 0x30) { SopClass sopClass = SopClass.GetSopClass(sx); if (sopClass == null) sopClass = new SopClass("Private SOP Class", sx, false); _assoc.AddPresentationContext(id, sopClass); } else if (pt == 0x40) { TransferSyntax transferSyntax = TransferSyntax.GetTransferSyntax(sx); if (transferSyntax == null) transferSyntax = new TransferSyntax("Private Syntax", sx, true, false, true, false, false, false); _assoc.AddTransferSyntax(id, transferSyntax); } il -= (ushort)(4 + pl); } } else if (type == 0x50) { // User Information while (il > 0) { byte ut = raw.ReadByte("User Information Item-Type"); raw.SkipBytes("Reserved", 1); ushort ul = raw.ReadUInt16("User Information Item-Length"); il -= (ushort)(4 + ul); if (ut == 0x51) { _assoc.RemoteMaximumPduLength = raw.ReadUInt32("Max PDU Length"); } else if (ut == 0x52) { _assoc.ImplementationClass = new DicomUid(raw.ReadString("Implementation Class UID", ul), "Implementation Class UID", UidType.Unknown); } else if (ut == 0x53) { _assoc.RemoteMaxOperationsInvoked = raw.ReadUInt16("Max Operations Invoked"); _assoc.RemoteMaxOperationsPerformed = raw.ReadUInt16("Max Operations Performed"); } else if (ut == 0x55) { _assoc.ImplementationVersion = raw.ReadString("Implementation Version", ul); } else if (ut == 0x54) { raw.SkipBytes("SCU/SCP Role Selection", ul); /* ushort rsul = raw.ReadUInt16(); if ((rsul + 4) != ul) { throw new DicomNetworkException("SCU/SCP role selection length (" + ul + " bytes) does not match uid length (" + rsul + " + 4 bytes)"); } raw.ReadChars(rsul); // Abstract Syntax raw.ReadByte(); // SCU role raw.ReadByte(); // SCP role */ } else { Platform.Log(LogLevel.Error, "Unhandled user item: 0x{0:x2} ({1} + 4 bytes)", ut, ul); raw.SkipBytes("Unhandled User Item", ul); } } } } }
/// <summary> /// Load enough information from the file to allow negotiation of the association. /// </summary> public void LoadInfo() { if (_infoLoaded) return; DicomFile theFile = new DicomFile(_filename); theFile.Load(DicomTags.RelatedGeneralSopClassUid, DicomReadOptions.Default); string sopClassInFile = theFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(theFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", theFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn,"Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = theFile.SopClass; } } else _sopClass = theFile.SopClass; _syntax = theFile.TransferSyntax; SopInstanceUid = theFile.MediaStorageSopInstanceUid; MetaInfoFileLength = theFile.MetaInfoFileLength; _infoLoaded = true; }
/// <summary> /// Constructor. /// </summary> /// <param name="dicomFile"></param> public StorageInstance(DicomFile dicomFile) { _dicomFile = dicomFile; string sopClassInFile = _dicomFile.DataSet[DicomTags.SopClassUid].ToString(); if (!sopClassInFile.Equals(_dicomFile.SopClass.Uid)) { Platform.Log(LogLevel.Warn, "SOP Class in Meta Info ({0}) does not match SOP Class in DataSet ({1})", _dicomFile.SopClass.Uid, sopClassInFile); _sopClass = SopClass.GetSopClass(sopClassInFile); if (_sopClass == null) { Platform.Log(LogLevel.Warn, "Unknown SOP Class in dataset, reverting to meta info: {0}", sopClassInFile); _sopClass = _dicomFile.SopClass; } } else _sopClass = _dicomFile.SopClass; _syntax = _dicomFile.TransferSyntax; SopInstanceUid = _dicomFile.MediaStorageSopInstanceUid; _filename = dicomFile.Filename; StudyInstanceUid = _dicomFile.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = _dicomFile.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); PatientsName = _dicomFile.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = _dicomFile.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
public StorageInstance(DicomMessage msg) { _sopClass = msg.SopClass; _syntax = msg.TransferSyntax; SopInstanceUid = msg.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty); StudyInstanceUid = msg.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty); SeriesInstanceUid = msg.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty); PatientsName = msg.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); PatientId = msg.DataSet[DicomTags.PatientId].GetString(0, string.Empty); _infoLoaded = true; }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax and Transfer Syntax. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <param name="transferSyntax">Transfer Syntax</param> /// <returns>Presentation Context ID</returns> public byte FindAbstractSyntaxWithTransferSyntax(SopClass abstractSyntax, TransferSyntax transferSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid && ctx.HasTransfer(transferSyntax)) return ctx.ID; } return 0; }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax. If it can't find it, throws an <see cref="DicomException"/>. /// It is useful to throw an exception for for a Scu, so we don't have to keep checking for a valid pcid. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <returns>Presentation Context ID</returns> /// <exception cref="DicomException"/> public byte FindAbstractSyntaxOrThrowException(SopClass abstractSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid) return ctx.ID; } throw new DicomException("Cannot find abstract syntax in presentation context: " + abstractSyntax.ToString()); }
/// <summary> /// Finds the Presentation Context with the specified Abstract Syntax, or 0 if it can't find it. /// </summary> /// <param name="abstractSyntax">Abstract Syntax</param> /// <returns>Presentation Context ID, or 0 if it can't find it.</returns> public byte FindAbstractSyntax(SopClass abstractSyntax) { foreach (DicomPresContext ctx in _presContexts.Values) { if (ctx.AbstractSyntax.Uid == abstractSyntax.Uid) return ctx.ID; } return 0; }
/// <summary> /// Adds a Presentation Context to the DICOM Associate. /// </summary> /// <remarks> /// <para> /// Note, this method will create a new presentation context for the /// <see cref="SopClass"/> even if one already exists for the /// <see cref="SopClass"/>. /// </para> /// </remarks> public byte AddPresentationContext(SopClass abstractSyntax) { byte pcid = 1; foreach (byte id in _presContexts.Keys) { //if (_presContexts[id].AbstractSyntax == abstractSyntax) // return id; if (id >= pcid) pcid = (byte)(id + 2); } AddPresentationContext(pcid, abstractSyntax); return pcid; }
/// <summary> /// Adds a Presentation Context to the DICOM Associate. /// </summary> public void AddPresentationContext(byte pcid, SopClass abstractSyntax) { _presContexts.Add(pcid, new DicomPresContext(pcid, abstractSyntax)); }
public InstanceXml(XmlNode instanceNode, DicomAttributeCollection baseCollection) { InstanceXmlDicomAttributeCollection thisCollection = new InstanceXmlDicomAttributeCollection(); _collection = thisCollection; _collection.ValidateVrValues = false; _collection.ValidateVrLengths = false; if (baseCollection != null) { AddExcludedTagsFromBase(baseCollection); _baseCollectionEnumerator = baseCollection.GetEnumerator(); if (!_baseCollectionEnumerator.MoveNext()) _baseCollectionEnumerator = null; } if (!instanceNode.HasChildNodes) return; _instanceXmlEnumerator = instanceNode.ChildNodes.GetEnumerator(); if (!_instanceXmlEnumerator.MoveNext()) _instanceXmlEnumerator = null; if (instanceNode.Attributes["UID"] != null) { _sopInstanceUid = instanceNode.Attributes["UID"].Value; } if (instanceNode.Attributes["SopClassUID"] != null) { _sopClass = SopClass.GetSopClass(instanceNode.Attributes["SopClassUID"].Value); } _transferSyntax = instanceNode.Attributes["TransferSyntaxUID"] != null ? TransferSyntax.GetTransferSyntax(instanceNode.Attributes["TransferSyntaxUID"].Value) : TransferSyntax.ExplicitVrLittleEndian; if (instanceNode.Attributes["SourceFileName"] != null) { _sourceFileName = instanceNode.Attributes["SourceFileName"].Value; } if (instanceNode.Attributes["FileSize"] != null) { long.TryParse(instanceNode.Attributes["FileSize"].Value, out _fileSize); } // This should never happen if (_sopClass == null) { _sopClass = SopClass.GetSopClass(Collection[DicomTags.SopClassUid].GetString(0, String.Empty)); } }