public void TestDecimalStringSerialization() { string[] testValues = { ".123", ".0", "5\0", " 0000012.", "00", "00.0", "-.123" }; string[] expectedValues = { "0.123", "0.0", "5", "12.0", "0", "0.0", "-0.123" }; var ds = new DicomDataset { new DicomDecimalString(DicomTag.PatientWeight, "") }; string json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.True(json.Equals("{\"00101030\":{\"vr\":\"DS\"}}")); string convType = _jsonDicomConverter.GetType().Name; for (var i = 0; i < testValues.Length; i++) { ds.AddOrUpdate(DicomTag.PatientWeight, testValues[i]); switch (convType) { case "SmiLazyJsonDicomConverter": json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); string expected = testValues[i].TrimEnd('\0'); Assert.AreEqual($"{{\"00101030\":{{\"vr\":\"DS\",\"val\":\"{expected}\"}}}}", json); break; case "SmiStrictJsonDicomConverter": json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.True(json.Equals("{\"00101030\":{\"vr\":\"DS\",\"Value\":[" + expectedValues[i] + "]}}")); break; case "JsonDicomConverter": if (i == 2 || i == 3) { Assert.Throws <ArgumentException>(() => DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter)); } else { json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.True(json.Equals("{\"00101030\":{\"vr\":\"DS\",\"Value\":[" + expectedValues[i] + "]}}")); } break; default: Assert.Fail($"No test case for {convType}"); break; } } if (_jsonDicomConverter.GetType().Name != "SmiLazyJsonDicomConverter") { return; } // Test all in a single element ds.AddOrUpdate(DicomTag.PatientWeight, testValues); VerifyJsonTripleTrip(ds); }
/// <summary> /// Serializes originalDataset to JSON, deserializes, and re-serializes. /// Verifies that both datasets are equal, and both json serializations are equal! /// </summary> private void VerifyJsonTripleTrip(DicomDataset originalDataset, bool expectFail = false) { string json = DicomTypeTranslater.SerializeDatasetToJson(originalDataset, _jsonDicomConverter); _logger.Debug($"Initial json:\n{json}"); DicomDataset recoDataset = DicomTypeTranslater.DeserializeJsonToDataset(json, _jsonDicomConverter); string json2 = DicomTypeTranslater.SerializeDatasetToJson(recoDataset, _jsonDicomConverter); _logger.Debug($"Final json:\n{json}"); if (expectFail) { Assert.AreNotEqual(json, json2); } else { Assert.AreEqual(json, json2); } // NOTE: Group length elements have been retired from the standard, and have never been included in any JSON conversion. // Remove them here to allow comparison between datasets. originalDataset.RemoveGroupLengths(); if (expectFail) { Assert.False(DicomDatasetHelpers.ValueEquals(originalDataset, recoDataset)); } else { Assert.True(DicomDatasetHelpers.ValueEquals(originalDataset, recoDataset)); } }
public void TestLargeDocumentSplitOk() { GlobalOptions options = MongoDbPopulatorTestHelper.GetNewMongoDbPopulatorOptions(); options.MongoDbPopulatorOptions.MongoDbFlushTime = int.MaxValue / 1000; var adapter = new MongoDbAdapter("ImageProcessor", options.MongoDatabases.ExtractionStoreOptions, "largeDocumentTest"); var processor = new ImageMessageProcessor(options.MongoDbPopulatorOptions, adapter, 2, null); var mockModel = Mock.Of <IModel>(); processor.Model = mockModel; var dataset = new DicomDataset { new DicomUnlimitedText(DicomTag.SelectorUTValue, new string('x', 15 * 1024 * 1024)) }; var largeMessage = new DicomFileMessage { SeriesInstanceUID = "", StudyInstanceUID = "", SOPInstanceUID = "", NationalPACSAccessionNumber = "", DicomFilePath = "", DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(dataset) }; processor.AddToWriteQueue(largeMessage, new MessageHeader(), 1); processor.AddToWriteQueue(largeMessage, new MessageHeader(), 2); }
private DicomFileMessage GetTestDicomFileMessage(Test testCase = Test.Normal, int numberOfRandomTagsPerDicom = 0) { var msg = new DicomFileMessage() { DicomFilePath = "Path/To/The/File.dcm", NationalPACSAccessionNumber = "1234", SOPInstanceUID = "1.2.3.4", SeriesInstanceUID = "1.2.3.4", StudyInstanceUID = "1.2.3.4", }; DicomDataset ds; Random r = new Random(123); using (var generator = new DicomDataGenerator(r, null, "CT")) ds = generator.GenerateTestDataset(new Person(r), r); ds.AddOrUpdate(DicomTag.AccessionNumber, "1234"); ds.AddOrUpdate(DicomTag.SOPInstanceUID, "1.2.3.4"); ds.AddOrUpdate(DicomTag.SeriesInstanceUID, "1.2.3.4"); ds.AddOrUpdate(DicomTag.StudyInstanceUID, "1.2.3.4"); switch (testCase) { case Test.Normal: ds.AddOrUpdate(DicomTag.PatientID, "010101"); break; case Test.NoPatientTag: ds.Remove(DicomTag.PatientID); break; case Test.EmptyInPatientTag: ds.AddOrUpdate(DicomTag.PatientID, string.Empty); break; case Test.ProperlyFormatedChi: ds.AddOrUpdate(DicomTag.PatientID, "0101010101"); break; default: throw new ArgumentOutOfRangeException("testCase"); } msg.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); return(msg); }
public void SetupSuite() { Globals = GetNewMongoDbPopulatorOptions(); _mongoTestClient = MongoClientHelpers.GetMongoClient(Globals.MongoDatabases.DicomStoreOptions, "MongoDbPopulatorTests"); _mongoTestClient.DropDatabase(TestDbName); TestDatabase = _mongoTestClient.GetDatabase(TestDbName); Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions = new ConsumerOptions() { QueueName = "TEST.SeriesQueue", QoSPrefetchCount = 5, AutoAck = false }; Globals.MongoDbPopulatorOptions.ImageQueueConsumerOptions = new ConsumerOptions() { QueueName = "TEST.MongoImageQueue", QoSPrefetchCount = 50, AutoAck = false }; var dataset = new DicomDataset { new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.4"), new DicomCodeString(DicomTag.Modality, "SR") }; string serialized = DicomTypeTranslater.SerializeDatasetToJson(dataset); TestImageMessage = new DicomFileMessage { DicomFilePath = "Path/To/File", NationalPACSAccessionNumber = "123", SeriesInstanceUID = "TestSeriesInstanceUID", StudyInstanceUID = "TestStudyInstanceUID", SOPInstanceUID = "TestSOPInstanceUID", DicomDataset = serialized }; TestSeriesMessage = new SeriesMessage { DirectoryPath = "Path/To/Series", ImagesInSeries = 123, NationalPACSAccessionNumber = "123", SeriesInstanceUID = "TestSeriesInstanceUID", StudyInstanceUID = "TestStudyInstanceUID", DicomDataset = serialized }; }
private DicomFileMessage GetFileMessageForDataset(DicomDataset dicomDataset) { var root = TestContext.CurrentContext.TestDirectory; var f = Path.GetRandomFileName(); var msg = new DicomFileMessage(root, Path.Combine(root, f + ".dcm")); msg.NationalPACSAccessionNumber = "ABC"; msg.SeriesInstanceUID = dicomDataset.GetString(DicomTag.SeriesInstanceUID); msg.StudyInstanceUID = dicomDataset.GetString(DicomTag.StudyInstanceUID); msg.SOPInstanceUID = dicomDataset.GetString(DicomTag.SOPInstanceUID); msg.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(dicomDataset); return(msg); }
public DicomFileMessage GetDicomFileMessage(DicomDataset ds, string fileSystemRoot, string file) { var toReturn = new DicomFileMessage(fileSystemRoot, file); toReturn.NationalPACSAccessionNumber = "999"; toReturn.StudyInstanceUID = "999"; toReturn.SeriesInstanceUID = "999"; toReturn.SOPInstanceUID = "999"; ds.Remove(DicomTag.PixelData); toReturn.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); return(toReturn); }
public void ProcessDocument(BsonDocument document) { string documentId = document["_id"].ToString(); var headerDoc = document["header"] as BsonDocument; if (headerDoc == null) { LogUnprocessedDocument(documentId, new ApplicationException("Document did not contain a header field")); return; } var message = new DicomFileMessage { NationalPACSAccessionNumber = AccNoOrNull(headerDoc["NationalPACSAccessionNumber"]), DicomFilePath = (string)headerDoc["DicomFilePath"], DicomFileSize = headerDoc.Contains("DicomFileSize") ? (long)headerDoc["DicomFileSize"] : -1 }; try { // Rebuild the dataset from the document, then serialize it to JSON to send DicomDataset ds = DicomTypeTranslaterWriter.BuildDicomDataset(document); message.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); // Add the header information message.StudyInstanceUID = ds.GetValue <string>(DicomTag.StudyInstanceUID, 0); message.SeriesInstanceUID = ds.GetValue <string>(DicomTag.SeriesInstanceUID, 0); message.SOPInstanceUID = ds.GetValue <string>(DicomTag.SOPInstanceUID, 0); } catch (Exception e) { LogUnprocessedDocument(documentId, e); return; } if (!message.VerifyPopulated()) { LogUnprocessedDocument(documentId, new ApplicationException("Message was not valid")); return; } IMessageHeader header = MongoDocumentHeaders.RebuildMessageHeader(headerDoc["MessageHeader"].AsBsonDocument); lock (_oBufferLock) _messageBuffer.Add(new Tuple <DicomFileMessage, IMessageHeader>(message, header)); }
public DicomFileMessage GetDicomFileMessage(string fileSystemRoot, FileInfo fi) { var toReturn = new DicomFileMessage(fileSystemRoot, fi); toReturn.NationalPACSAccessionNumber = "999"; toReturn.StudyInstanceUID = "999"; toReturn.SeriesInstanceUID = "999"; toReturn.SOPInstanceUID = "999"; toReturn.DicomFileSize = fi.Length; var ds = DicomFile.Open(fi.FullName).Dataset; ds.Remove(DicomTag.PixelData); toReturn.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); return(toReturn); }
public void TestBlankAndNullSerialization() { var dataset = new DicomDataset { new DicomDecimalString(DicomTag.SelectorDSValue, default(string)), new DicomIntegerString(DicomTag.SelectorISValue, ""), new DicomFloatingPointSingle(DicomTag.SelectorFLValue, default(float)), new DicomFloatingPointDouble(DicomTag.SelectorFDValue) }; string json = DicomTypeTranslater.SerializeDatasetToJson(dataset, _jsonDicomConverter); _logger.Debug(json); DicomDataset recoDataset = DicomTypeTranslater.DeserializeJsonToDataset(json, _jsonDicomConverter); Assert.True(DicomDatasetHelpers.ValueEquals(dataset, recoDataset)); }
public void TestLargeMessageNack() { GlobalOptions options = MongoDbPopulatorTestHelper.GetNewMongoDbPopulatorOptions(); options.MongoDbPopulatorOptions.MongoDbFlushTime = int.MaxValue / 1000; var adapter = new MongoDbAdapter("ImageProcessor", options.MongoDatabases.ExtractionStoreOptions, "largeDocumentTest"); var processor = new ImageMessageProcessor(options.MongoDbPopulatorOptions, adapter, 1, null); var mockModel = Mock.Of <IModel>(); processor.Model = mockModel; var dataset = new DicomDataset { new DicomUnlimitedText(DicomTag.SelectorUTValue, new string('x', 16 * 1024 * 1024)) }; string json = DicomTypeTranslater.SerializeDatasetToJson(dataset); var largeMessage = new DicomFileMessage { SeriesInstanceUID = "", StudyInstanceUID = "", SOPInstanceUID = "", NationalPACSAccessionNumber = "", DicomFilePath = "", DicomDataset = json }; Assert.Throws <ApplicationException>(() => processor.AddToWriteQueue(largeMessage, new MessageHeader(), 1)); dataset = new DicomDataset { // Should be ok, getting close to the threshold new DicomUnlimitedText(DicomTag.SelectorUTValue, new string('x', 15 * 1024 * 1024 + 512)) }; json = DicomTypeTranslater.SerializeDatasetToJson(dataset); largeMessage.DicomDataset = json; processor.AddToWriteQueue(largeMessage, new MessageHeader(), 2); Assert.True(processor.AckCount == 1); }
/// <summary> /// Creates a new <see cref="DicomFileMessage"/> by reading <paramref name="ds"/> tags /// </summary> /// <param name="ds"></param> /// <param name="dicomFilePath">The full path that <paramref name="ds"/> was read from</param> /// <param name="fileSize">File size if known otherwise null</param> /// <returns></returns> /// <exception cref="ApplicationException">If <paramref name="ds"/> is missing required UIDS or serializing the dataset went wrong</exception> protected DicomFileMessage DicomFileToMessage(DicomDataset ds, string dicomFilePath, long?fileSize) { var IDs = new string[3]; try { // Pre-fetch these to ensure they exist before we go further IDs[0] = ds.GetValue <string>(DicomTag.StudyInstanceUID, 0); IDs[1] = ds.GetValue <string>(DicomTag.SeriesInstanceUID, 0); IDs[2] = ds.GetValue <string>(DicomTag.SOPInstanceUID, 0); if (IDs.Any(string.IsNullOrWhiteSpace)) { throw new DicomDataException("A required ID tag existed but its value was invalid"); } } catch (DicomDataException dde) { throw new ApplicationException("File opened but had a missing ID", dde); } string serializedDataset; try { serializedDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); } catch (Exception e) { throw new ApplicationException("Failed to serialize dataset", e); } return(new DicomFileMessage(_filesystemRoot, dicomFilePath) { //TODO(Ruairidh 04/07) Where are these used? StudyInstanceUID = IDs[0], SeriesInstanceUID = IDs[1], SOPInstanceUID = IDs[2], DicomDataset = serializedDataset, DicomFileSize = fileSize ?? -1 }); }
public void ImageProcessor_FailInModalityBatch_AcksWrittenDocuments() { _testOptions.MongoDbPopulatorOptions.FailedWriteLimit = 1; _testOptions.MongoDbPopulatorOptions.MongoDbFlushTime = int.MaxValue / 1000; var testModalities = new[] { "MR", "MR", "MR", "SR", "SR" }; var testAdapter = new MongoTestAdapter(); var processor = new ImageMessageProcessor(_testOptions.MongoDbPopulatorOptions, testAdapter, testModalities.Length + 1, null); var mockModel = new Mock <IModel>(); mockModel.Setup(x => x.BasicAck(It.Is <ulong>(y => y == ulong.MaxValue), It.IsAny <bool>())) .Callback(() => throw new Exception("BasicAck called with delivery tag for CT message")); processor.Model = mockModel.Object; var ds = new DicomDataset(); var msg = new DicomFileMessage { DicomFilePath = "", NationalPACSAccessionNumber = "" }; for (var i = 0; i < testModalities.Length; ++i) { string modality = testModalities[i]; ds.AddOrUpdate(DicomTag.Modality, modality); msg.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); processor.AddToWriteQueue(msg, null, (ulong)i); } ds.AddOrUpdate(DicomTag.Modality, "CT"); msg.DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds); Assert.Throws <ApplicationException>(() => processor.AddToWriteQueue(msg, new MessageHeader(), ulong.MaxValue)); Assert.AreEqual(5, processor.AckCount); }
public void JsonSerialization_SerializeBinaryFalse_ContainsEmptyTags() { if (_jsonDicomConverter.GetType().Name != "SmiLazyJsonDicomConverter") { Assert.Pass("Only applicable for SmiLazyJsonDicomConverter"); } var ds = new DicomDataset { new DicomOtherByte(DicomTag.SelectorOBValue, byte.MinValue), new DicomOtherWord(DicomTag.SelectorOWValue, byte.MinValue), new DicomUnknown(DicomTag.SelectorUNValue, byte.MinValue) }; DicomTypeTranslater.SerializeBinaryData = false; string json = DicomTypeTranslater.SerializeDatasetToJson(ds); Assert.DoesNotThrow(() => JToken.Parse(json)); DicomDataset recoDs = DicomTypeTranslater.DeserializeJsonToDataset(json); Assert.AreEqual(ds.Count(), recoDs.Count()); AssertBlacklistedNulls(recoDs); }
public bool SwapIdentifier(DicomFileMessage msg, out string reason) { DicomDataset ds; try { ds = DicomTypeTranslater.DeserializeJsonToDataset(msg.DicomDataset); } catch (Exception e) { throw new ApplicationException("Failed to deserialize dataset", e); } if (!ds.Contains(DicomTag.PatientID)) { reason = "Dataset did not contain PatientID"; return(false); } var from = (string)DicomTypeTranslaterReader.GetCSharpValue(ds, DicomTag.PatientID); if (string.IsNullOrWhiteSpace(from)) { reason = "PatientID was blank"; return(false); } string to = _swapper.GetSubstitutionFor(from, out reason); if (to == null) { reason = "Swapper " + _swapper + " returned null"; return(false); } // Update the JSON deserialized dicom dataset ds.AddOrUpdate(DicomTag.PatientID, to); string updatedJson; try { updatedJson = DicomTypeTranslater.SerializeDatasetToJson(ds); } catch (Exception e) { throw new ApplicationException("Failed to serialize dataset", e); } // Unlikely, but should still check if (updatedJson == null) { reason = "Updated json string was null"; return(false); } // Override the message DicomDataset with the new serialized dataset msg.DicomDataset = updatedJson; return(true); }
public void TestPopulatorBasic(int nMessages) { // Arrange string currentCollectionName = MongoDbPopulatorTestHelper.GetCollectionNameForTest(string.Format("TestPopulatorBasic({0})", nMessages)); _helper.Globals.MongoDbPopulatorOptions.SeriesCollection = currentCollectionName; var tester = new MicroserviceTester(_helper.Globals.RabbitOptions, _helper.Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions, _helper.Globals.MongoDbPopulatorOptions.ImageQueueConsumerOptions); var host = new MongoDbPopulatorHost(_helper.Globals); host.Start(); using (var timeline = new TestTimeline(tester)) { var ds = new DicomDataset { new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.4") }; var message = new SeriesMessage { NationalPACSAccessionNumber = "NationalPACSAccessionNumber-test", DirectoryPath = "DirectoryPath-test", StudyInstanceUID = "StudyInstanceUID-test", SeriesInstanceUID = "SeriesInstanceUID-test", ImagesInSeries = 123, DicomDataset = DicomTypeTranslater.SerializeDatasetToJson(ds) }; // Act for (var i = 0; i < nMessages; i++) { timeline.SendMessage(_helper.Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions, message); } timeline.StartTimeline(); var timeout = 30000; const int stepSize = 500; if (Debugger.IsAttached) { timeout = int.MaxValue; } var nWritten = 0L; while (nWritten < nMessages && timeout > 0) { nWritten = _helper.TestDatabase.GetCollection <BsonDocument>(currentCollectionName).CountDocuments(new BsonDocument()); Thread.Sleep(stepSize); timeout -= stepSize; } // Assert if (timeout <= 0) { Assert.Fail("Failed to process expected number of messages within the timeout"); } host.Stop("Test end"); tester.Shutdown(); } }
public void TestLongIntegerStringSerialization() { var ds = new DicomDataset(); string[] testValues = { "123", // Normal value "-123", // Normal value "00000000", // Technically allowed "+123", // Strange, but allowed "00001234123412" // A value we can fix and parse }; // Values which will be 'fixed' by the SmiStrictJsonDicomConverter string[] expectedValues = { "123", "-123", "0", "123", "1234123412" }; string convType = _jsonDicomConverter.GetType().Name; for (var i = 0; i < testValues.Length; i++) { ds.AddOrUpdate(new DicomIntegerString(DicomTag.SelectorAttributePrivateCreator, testValues[i])); switch (convType) { case "SmiLazyJsonDicomConverter": string json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.AreEqual($"{{\"00720056\":{{\"vr\":\"IS\",\"val\":\"{testValues[i]}\"}}}}", json); break; case "SmiStrictJsonDicomConverter": case "JsonDicomConverter": json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.AreEqual(("{\"00720056\":{\"vr\":\"IS\",\"Value\":[" + expectedValues[i] + "]}}"), json); break; default: Assert.Fail($"No test case for {convType}"); break; } } // Value larger than an Int32 ds.AddOrUpdate(new DicomIntegerString(DicomTag.SelectorAttributePrivateCreator, "10001234123412")); switch (convType) { case "JsonDicomConverter": // Default converter will try and force it into an int -> OverflowException Assert.Throws <OverflowException>(() => DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter)); break; case "SmiStrictJsonDicomConverter": // Strict converter will try and 'fix' it, before throwing a FormatException Assert.Throws <FormatException>(() => DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter)); break; case "SmiLazyJsonDicomConverter": // Our converter doesn't enforce types, so this should pass string json = DicomTypeTranslater.SerializeDatasetToJson(ds, _jsonDicomConverter); Assert.AreEqual("{\"00720056\":{\"vr\":\"IS\",\"val\":\"10001234123412\"}}", json); break; default: Assert.Fail($"No test case for {convType}"); break; } }