Skip to content

Commit

Permalink
Update NUnit for 4.0 API, add analyzer package
Browse files Browse the repository at this point in the history
  • Loading branch information
jas88 committed Nov 27, 2023
1 parent 99550a2 commit 9543b79
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 105 deletions.
4 changes: 4 additions & 0 deletions BadDicom/BadDicom.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="HIC.DicomTypeTranslation" Version="4.0.3" />
<PackageReference Include="NUnit.Analyzers" Version="3.9.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Vecc.YamlDotNet.Analyzers.StaticGenerator" Version="13.7.0" />
<PackageReference Include="YamlDotNet" Version="13.7.1" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion BadDicom/Configuration/ExplicitUIDs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void Load()
private static IEnumerable<string> GetUIDsFrom(string? path)
{
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) return Enumerable.Empty<string>();

return File.ReadLines(path).Where(l => !string.IsNullOrWhiteSpace(l));
}
}
4 changes: 2 additions & 2 deletions BadDicom/Configuration/TargetDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ public class TargetDatabase
/// The ConnectionString containing the server name, credentials and other parameters for the connection
/// </summary>
public string? ConnectionString { get; set; }

/// <summary>
/// The name of database
/// </summary>
public string? DatabaseName { get; set; }

/// <summary>
/// The filename of a YAML template file to be used for this database
/// </summary>
Expand Down
32 changes: 16 additions & 16 deletions BadDicom/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private static void RunOptionsAndReturnExitCode(ProgramOptions opts)
}
catch (Exception e)
{

Console.WriteLine(e);
_returnCode = 3;
return;
Expand Down Expand Up @@ -144,7 +144,7 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
//if we are going into a database we definitely do not need pixels!
opts.NoPixels = true;


var swTotal = Stopwatch.StartNew();
const string neverDistinct = "SOPInstanceUID";

Expand All @@ -171,7 +171,7 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
ImplementationManager.Load<MicrosoftSQLImplementation>();

var server = new DiscoveredServer(configDatabase.ConnectionString, configDatabase.DatabaseType);

try
{
server.TestConnection();
Expand All @@ -183,7 +183,7 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
return -2;
}


var db = server.ExpectDatabase(configDatabase.DatabaseName);

if (!db.Exists())
Expand All @@ -198,14 +198,14 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
}

var creator = new ImagingTableCreation(db.Server.GetQuerySyntaxHelper());

Console.WriteLine($"Image template contained schemas for {template.Tables.Count} tables. Looking for existing tables..");

//setting up bulk inserters
var tables = new DiscoveredTable[template.Tables.Count];
var batches = new DataTable[batchSize][];

for (var i = 0; i < batches.Length; i++)
for (var i = 0; i < batches.Length; i++)
batches[i] = new DataTable[template.Tables.Count];

var uploaders= new IBulkCopy[batchSize][];
Expand Down Expand Up @@ -259,7 +259,7 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
create = false;
}
}

if(create)
{
Console.WriteLine($"About to create '{tbl.GetFullyQualifiedName()}'");
Expand All @@ -275,31 +275,31 @@ private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptio
var dt = tbl.GetDataTable();
dt.Rows.Clear();

batches[j][i] = dt;
batches[j][i] = dt;
uploaders[j][i] = tbl.BeginBulkInsert();
}
}
var identifiers = GetPeople(opts, out var r);

Parallel.For(0, batchSize, i => RunBatch(identifiers, opts, r, batches[i], uploaders[i]));

swTotal.Stop();

for (var i = 0; i < tables.Length; i++)
{
if(pks[i] == null)
continue;

Console.WriteLine( $"{DateTime.Now} Making table '{tables[i]}' distinct (this may take a long time)");
var tbl = tables[i];
tbl.MakeDistinct(500000000);

Console.WriteLine( $"{DateTime.Now} Creating primary key on '{tables[i]}' of '{pks[i]}'");
tbl.CreatePrimaryKey(500000000,tbl.DiscoverColumn(pks[i]));
}

Console.WriteLine("Final Row Counts:");

foreach (var t in tables)
Console.WriteLine($"{t.GetFullyQualifiedName()}: {t.GetRowCount():0,0}");

Expand All @@ -322,14 +322,14 @@ private static void RunBatch(IPersonCollection identifiers, ProgramOptions opts,

var p = identifiers.People[r.Next(identifiers.People.Length)];
var ds = dicomGenerator.GenerateStudyImages(p,out _);

swGeneration.Stop();

foreach (var dataset in ds)
{
var rows = new DataRow[batches.Length];

for (var j = 0; j < batches.Length; j++)
for (var j = 0; j < batches.Length; j++)
rows[j] = batches[j].NewRow();

swReading.Start();
Expand Down Expand Up @@ -371,7 +371,7 @@ private static void RunBatch(IPersonCollection identifiers, ProgramOptions opts,
batches[i].Dispose();
}
}

Console.WriteLine($"Total time Generating Dicoms:{swGeneration.Elapsed}");
Console.WriteLine($"Total time Reading Dicoms:{swReading.Elapsed}");
Console.WriteLine($"Total time Uploading Records:{swUploading.Elapsed}");
Expand Down
6 changes: 3 additions & 3 deletions BadDicom/ProgramOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class ProgramOptions

[Value(3, HelpText = "Comma separated list of modalities to generate from", Default = "CT")]
public string Modalities { get; set; } = "CT";

[Option("NoPixels",HelpText= "Generate dicom files without pixel data (only tags). This results in much smaller file sizes")]
public bool NoPixels{get;set;}

Expand All @@ -42,13 +42,13 @@ public static IEnumerable<Example> Examples
{
get
{
yield return
yield return
new Example("Generate test data",
new ProgramOptions { OutputDirectory = @"c:/temp" });

yield return
new Example("Generate a custom amount of data", new ProgramOptions { OutputDirectory = @"c:/temp",NumberOfPatients = 5000, NumberOfStudies = 20000});

}
}

Expand Down
3 changes: 3 additions & 0 deletions BadMedicine.Dicom.Tests/BadMedicine.Dicom.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="4.0.0" />
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
83 changes: 47 additions & 36 deletions BadMedicine.Dicom.Tests/DicomDataGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,50 @@ public void Test_CreatingOnDisk_OneFile()

//generates a study but because of maximum images 1 we should only get 1 image being generated
var studyUid = (string)generator.GenerateTestDataRow(person)[0];

//should be a directory named after the Study UID
Assert.IsTrue(Directory.Exists(Path.Combine(TestContext.CurrentContext.WorkDirectory, studyUid)));
Assert.That(Directory.Exists(Path.Combine(TestContext.CurrentContext.WorkDirectory, studyUid)));

//should be a single file
var f = new FileInfo(Directory.GetFiles(Path.Combine(TestContext.CurrentContext.WorkDirectory, studyUid)).Single());
Assert.IsTrue(f.Exists);
Assert.That(f.Exists);

var datasetCreated = DicomFile.Open(f.FullName);

Assert.AreEqual(studyUid,
datasetCreated.Dataset.GetValues<DicomUID>(DicomTag.StudyInstanceUID)[0].UID,
"UID in the dicom file generated did not match the one output into the CSV inventory file"
);

Assert.IsNotEmpty(datasetCreated.Dataset.GetSingleValue<string>(DicomTag.AccessionNumber));
Assert.Multiple(() =>
{
Assert.That(datasetCreated.Dataset.GetValues<DicomUID>(DicomTag.StudyInstanceUID)[0].UID, Is.EqualTo(studyUid),
"UID in the dicom file generated did not match the one output into the CSV inventory file"
);
Assert.That(datasetCreated.Dataset.GetSingleValue<string>(DicomTag.AccessionNumber), Is.Not.Empty);
});
}


[Test]
public void ExampleUsage()
{
{
//create a test person
var r = new Random(23);
var person = new Person(r);

//create a generator
//create a generator
using var generator = new DicomDataGenerator(r, null, "CT");
//create a dataset in memory
var dataset = generator.GenerateTestDataset(person, r);

//values should match the patient details
Assert.AreEqual(person.CHI,dataset.GetValue<string>(DicomTag.PatientID,0));
Assert.GreaterOrEqual(dataset.GetValue<DateTime>(DicomTag.StudyDate,0),person.DateOfBirth);

//should have a study description
Assert.IsNotNull(dataset.GetValue<string>(DicomTag.StudyDescription,0));
//should have a study description
Assert.IsNotNull(dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay);
Assert.Multiple(() =>
{
//values should match the patient details
Assert.That(dataset.GetValue<string>(DicomTag.PatientID, 0), Is.EqualTo(person.CHI));
Assert.That(dataset.GetValue<DateTime>(DicomTag.StudyDate, 0), Is.GreaterThanOrEqualTo(person.DateOfBirth));
//should have a study description
Assert.That(dataset.GetValue<string>(DicomTag.StudyDescription, 0), Is.Not.Null);
//should have a study time
Assert.That(dataset.Contains(DicomTag.StudyTime));
});
}

[Test]
Expand All @@ -68,13 +73,13 @@ public void Test_CreatingInMemory_ModalityCT()
var r = new Random(23);
var person = new Person(r);
using var generator = new DicomDataGenerator(r,new string(TestContext.CurrentContext.WorkDirectory),"CT") {NoPixels = true};

//generate 100 images
for(var i = 0 ; i < 100 ; i++)
{
//all should be CT because we said CT only
var ds = generator.GenerateTestDataset(person, r);
Assert.AreEqual("CT",ds.GetSingleValue<string>(DicomTag.Modality));
Assert.That(ds.GetSingleValue<string>(DicomTag.Modality), Is.EqualTo("CT"));
}
}

Expand All @@ -85,21 +90,27 @@ public void Test_Anonymise()
var person = new Person(r);

using var generator = new DicomDataGenerator(r,new string(TestContext.CurrentContext.WorkDirectory),"CT");

// without anonymisation (default) we get the normal patient ID
var ds = generator.GenerateTestDataset(person, r);

Assert.IsTrue(ds.Contains(DicomTag.PatientID));
Assert.AreEqual(person.CHI,ds.GetValue<string>(DicomTag.PatientID,0));


Assert.Multiple(() =>
{
Assert.That(ds.Contains(DicomTag.PatientID));
Assert.That(ds.GetValue<string>(DicomTag.PatientID, 0), Is.EqualTo(person.CHI));
});

// with anonymisation
generator.Anonymise = true;

var ds2 = generator.GenerateTestDataset(person, r);

// we get a blank patient ID
Assert.IsTrue(ds2.Contains(DicomTag.PatientID));
Assert.AreEqual(string.Empty,ds2.GetString(DicomTag.PatientID));
Assert.Multiple(() =>
{
// we get a blank patient ID
Assert.That(ds2.Contains(DicomTag.PatientID));
Assert.That(ds2.GetString(DicomTag.PatientID), Is.EqualTo(string.Empty));
});
}
[Test]
public void Test_CreatingInMemory_Modality_CTAndMR()
Expand All @@ -108,15 +119,15 @@ public void Test_CreatingInMemory_Modality_CTAndMR()
var person = new Person(r);

using var generator = new DicomDataGenerator(r,new string(TestContext.CurrentContext.WorkDirectory),"CT","MR");

//generate 100 images
for(var i = 0 ; i < 100 ; i++)
{
//all should be CT because we said CT only
var ds = generator.GenerateTestDataset(person, r);
var modality = ds.GetSingleValue<string>(DicomTag.Modality);

Assert.IsTrue(modality is "CT" or "MR","Unexpected modality {0}",modality);
Assert.That(modality is "CT" or "MR","Unexpected modality {0}",modality);
}
}

Expand Down Expand Up @@ -151,7 +162,7 @@ public void Test_CsvOption()
}

//3 csv files + index.csv (the default one
Assert.AreEqual(4,outputDir.GetFiles().Length);
Assert.That(outputDir.GetFiles(), Has.Length.EqualTo(4));

foreach (var f in outputDir.GetFiles())
{
Expand All @@ -164,7 +175,7 @@ public void Test_CsvOption()

//should be 1 row per image + 1 for header
if(f.Name == DicomDataGenerator.ImageCsvFilename)
Assert.AreEqual(501,rowcount);
Assert.That(rowcount, Is.EqualTo(501));
}
}
}
Loading

0 comments on commit 9543b79

Please sign in to comment.