Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #59

Merged
merged 40 commits into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ae8d8c2
* Fix most LGTM warnings
jas88 Jul 6, 2020
be3ad9d
Merge branch 'develop' into feature/lgtm-fixes
jas88 Jul 16, 2020
6f142bc
Bump HIC.RDMP.Plugin from 4.1.4 to 4.1.5 (#43)
dependabot-preview[bot] Jul 16, 2020
daf50cd
Adjust LGTM fixes per TN feedback
jas88 Jul 16, 2020
1a0503c
fixed Exception Type
tznind Jul 16, 2020
5bfab8f
Fix XOR logic in DicomFileCollectionSource.cs
jas88 Jul 16, 2020
b1c5b62
Merge branch 'feature/lgtm-fixes' of github.com:HicServices/RdmpDicom…
jas88 Jul 16, 2020
4a56420
Merge pull request #46 from HicServices/feature/lgtm-fixes
jas88 Jul 16, 2020
e3fe865
Added source that calls a process
tznind Jul 22, 2020
df6f2ec
Fixed typo
tznind Jul 22, 2020
70dcc8d
Added tests and captured process output
tznind Jul 22, 2020
04f8a53
Added linux test case
tznind Jul 22, 2020
6077764
Updated changelog
tznind Jul 22, 2020
e307076
Moved into using block
tznind Jul 22, 2020
2958a39
Set dummy command for Linux unit testing
jas88 Jul 22, 2020
acb62dd
Merge pull request #47 from HicServices/feature/processbased-source
tznind Jul 22, 2020
c21ac26
Changed test to use fork for easier debugging
tznind Jul 24, 2020
514c20f
added dir to test
tznind Jul 24, 2020
964617c
Bump Google.Protobuf from 3.12.3 to 3.12.4
dependabot-preview[bot] Jul 28, 2020
c998510
Merge pull request #48 from HicServices/dependabot/nuget/develop/Goog…
jas88 Jul 29, 2020
5e9887d
Bump HIC.RDMP.Plugin.Test from 4.1.5 to 4.1.6 (#49)
dependabot-preview[bot] Aug 4, 2020
4bd6f39
Bump HIC.RDMP.Plugin.UI from 4.1.5 to 4.1.6 (#51)
dependabot-preview[bot] Aug 4, 2020
d5f843a
Bump HIC.RDMP.Plugin from 4.1.5 to 4.1.6 (#50)
dependabot-preview[bot] Aug 4, 2020
b06adcb
fix for #52
tznind Aug 5, 2020
7652297
Bump Microsoft.NET.Test.Sdk from 16.6.1 to 16.7.0
dependabot-preview[bot] Aug 7, 2020
0ac5c59
Merge pull request #53 from HicServices/dependabot/nuget/develop/Micr…
jas88 Aug 7, 2020
79c0899
Bump System.Data.SqlClient from 4.8.1 to 4.8.2
dependabot-preview[bot] Aug 11, 2020
4b845ba
Bump System.Data.SqlClient from 4.8.1 to 4.8.2
jas88 Aug 11, 2020
7acb15f
Allow the PACS to send us lossy-compressed images if it has them, rat…
jas88 Aug 14, 2020
424cdbf
Also allow video (MPEG, HEVC) formats in case the PACS gets really am…
jas88 Aug 14, 2020
1954484
Allow more file formats from PACS
jas88 Aug 14, 2020
905ab61
Bump HIC.RDMP.Plugin.UI from 4.1.6 to 4.1.7
dependabot-preview[bot] Aug 14, 2020
6308db2
Bump HIC.RDMP.Plugin.Test from 4.1.6 to 4.1.7
dependabot-preview[bot] Aug 14, 2020
ae8d46d
Merge pull request #58 from HicServices/dependabot/nuget/develop/HIC.…
jas88 Aug 14, 2020
a141308
Merge pull request #56 from HicServices/dependabot/nuget/develop/HIC.…
jas88 Aug 14, 2020
baa9b39
Bump HIC.RDMP.Plugin from 4.1.6 to 4.1.7 (#57)
dependabot-preview[bot] Aug 14, 2020
5089e24
Merge branch 'master' into develop
jas88 Aug 14, 2020
c313c8b
Update CHANGELOG, SharedAssemblyInfo for 2.1.7 release
jas88 Aug 17, 2020
7cd0969
Bump Google.Protobuf from 3.12.4 to 3.13.0
dependabot-preview[bot] Aug 17, 2020
132a01c
Merge pull request #60 from HicServices/dependabot/nuget/develop/Goog…
dependabot-preview[bot] Aug 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.1.7] 2020-08-17

### Fixed

- Allow the PACS to send us lossy compressed versions if it wants, otherwise we won't be able to receive anything it has in that format

### Added

- Accept video (MPEG/HEVC) content if the PACS offers it
- Added new cache source `ProcessBasedCacheSource` that calls out to a remote process

## [2.1.6] 2020-06-17

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion Packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
| Package | Source Code | Version | License | Purpose | Additional Risk Assessment |
| ------- | ------------| --------| ------- | ------- | -------------------------- |
| HIC.DicomTypeTranslation | [GitHub](https://github.com/HicServices/DicomTypeTranslation) | [2.3.0](https://www.nuget.org/packages/HIC.DicomTypeTranslation/2.3.0) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Translate dicom types into C# / database types | |
| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.4](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.4) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | |
| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.7](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.7) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | |
4 changes: 2 additions & 2 deletions Plugin/netcoreapp2.2/netcoreapp2.2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
<PackageReference Include="System.Net.Http" Version="4.*" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.12.3" />
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
<PackageReference Include="HIC.DicomTypeTranslation" Version="2.3.0" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.19.80" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.ComponentModel.Composition" Version="4.7.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Rdmp.Dicom.Library.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<copyright>Copyright 2018-2019</copyright>
<dependencies>
<dependency id="HIC.DicomTypeTranslation" version="2.3.0" />
<dependency id="HIC.RDMP.Plugin" version="4.1.4" />
<dependency id="HIC.RDMP.Plugin" version="4.1.7" />
</dependencies>
</metadata>
<files>
Expand Down
4 changes: 2 additions & 2 deletions Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="HIC.BadMedicine.Dicom" Version="0.0.6" />
<PackageReference Include="HIC.RDMP.Plugin.Test" Version="4.1.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="HIC.RDMP.Plugin.Test" Version="4.1.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="NunitXml.TestLogger" Version="2.1.62" />
Expand Down
80 changes: 80 additions & 0 deletions Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using MapsDirectlyToDatabaseTable;
using NUnit.Framework;
using Rdmp.Core.Caching.Requests;
using Rdmp.Core.Caching.Requests.FetchRequestProvider;
using Rdmp.Core.Curation;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.Curation.Data.Cache;
using Rdmp.Core.DataFlowPipeline;
using Rdmp.Core.Startup;
using Rdmp.Dicom.Cache.Pipeline;
using ReusableLibraryCode.Checks;
using ReusableLibraryCode.Progress;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Tests.Common;

namespace Rdmp.Dicom.Tests
{
class TestProcessBasedCacheSource : UnitTests
{
[Test]
public void TestWithEcho()
{
var source = new ProcessBasedCacheSource();

if(IsLinux)
{
source.Command = "/bin/echo";
source.Args = "Hey Thomas go get %s and store in %d";
}
else
{
source.Command = "cmd.exe";
source.Args = "/c echo Hey Thomas go get %s and store in %d";
}
source.TimeFormat = "dd/MM/yy";
source.ThrowOnNonZeroExitCode = true;

// What dates to load
var cp = WhenIHaveA<CacheProgress>();
cp.CacheFillProgress = new DateTime(2001,12,24);
cp.SaveToDatabase();

// Where to put files
var lmd = cp.LoadProgress.LoadMetadata;

var dir = new DirectoryInfo(TestContext.CurrentContext.WorkDirectory);
var loadDir = LoadDirectory.CreateDirectoryStructure(dir,"blah",true);

lmd.LocationOfFlatFiles = loadDir.RootPath.FullName;
lmd.SaveToDatabase();

source.PreInitialize(new CacheFetchRequestProvider(cp), new ThrowImmediatelyDataLoadEventListener());
source.PreInitialize(cp.CatalogueRepository,new ThrowImmediatelyDataLoadEventListener());
source.PreInitialize(new PermissionWindow(cp.CatalogueRepository),new ThrowImmediatelyDataLoadEventListener());

var toMem = new ToMemoryDataLoadEventListener(true);
var fork = new ForkDataLoadEventListener(toMem,new ThrowImmediatelyDataLoadEventListener(){WriteToConsole = true});

source.GetChunk(fork,new GracefulCancellationToken());

Assert.Contains($"Hey Thomas go get 24/12/01 and store in {Path.Combine(loadDir.Cache.FullName,"ALL")}",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray());



}

public static bool IsLinux
{
get
{
int p = (int) Environment.OSVersion.Platform;
return (p == 4) || (p == 6) || (p == 128);
}
}
}
}
55 changes: 30 additions & 25 deletions Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,26 @@ private bool CreateDatabaseIfNotExists(DiscoveredDatabase db)

private void btnCreateSuiteWithTemplate_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Imaging Template|*.it";
string filename;
using (OpenFileDialog ofd = new OpenFileDialog()
{
Filter = "Imaging Template|*.it"
})
{
if (ofd.ShowDialog() != DialogResult.OK)
return;
filename = ofd.FileName;
}

if (ofd.ShowDialog() == DialogResult.OK)
try
{
var yaml = File.ReadAllText(filename);
var template = ImageTableTemplateCollection.LoadFrom(yaml);
CreateSuite(template);
}
catch (Exception exception)
{
try
{
var yaml = File.ReadAllText(ofd.FileName);

var template = ImageTableTemplateCollection.LoadFrom(yaml);

CreateSuite(template);
}
catch (Exception exception)
{
ExceptionViewer.Show(exception);
}
ExceptionViewer.Show(exception);
}
}

Expand All @@ -78,17 +81,19 @@ private void CreateSuite(ImageTableTemplateCollection template)
if (!CreateDatabaseIfNotExists(db))
return;


FolderBrowserDialog dialog = new FolderBrowserDialog();
DirectoryInfo dir = null;
dialog.Description = "Select Project Directory (For Sql scripts/Executables etc)";

//if we are creating a load we need to know where to store load scripts etc
if(cbCreateLoad.Checked)
if (dialog.ShowDialog() == DialogResult.OK)
dir = new DirectoryInfo(dialog.SelectedPath);
else
return;
DirectoryInfo dir = null;
using (FolderBrowserDialog dialog = new FolderBrowserDialog() {
Description = "Select Project Directory (For Sql scripts/Executables etc)"
})
{
//if we are creating a load we need to know where to store load scripts etc
if (cbCreateLoad.Checked)
if (dialog.ShowDialog() == DialogResult.OK)
dir = new DirectoryInfo(dialog.SelectedPath);
else
return;
}

var cmd = new ExecuteCommandCreateNewImagingDatasetSuite(_activator.RepositoryLocator, db,dir);
cmd.DicomSourceType = rbJsonSources.Checked ? typeof(DicomDatasetCollectionSource) : typeof(DicomFileCollectionSource);
Expand Down
2 changes: 1 addition & 1 deletion Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<ProjectReference Include="..\Rdmp.Dicom\Rdmp.Dicom.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HIC.RDMP.Plugin.UI" Version="4.1.5" />
<PackageReference Include="HIC.RDMP.Plugin.UI" Version="4.1.7" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Rdmp.Dicom.UI/TagElevationXmlUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private void RunChecks()

try
{
var collection = new TagElevationRequestCollection(queryEditor.Text);
new TagElevationRequestCollection(queryEditor.Text);
RagSmiley1.OnCheckPerformed(new CheckEventArgs("Succesfully created elevator",CheckResult.Success));
}
catch(Exception ex)
Expand Down
4 changes: 0 additions & 4 deletions Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using FAnsi.Implementations.MySql;
using MySql.Data.MySqlClient;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.Curation.Data.DataLoad;
using Rdmp.Core.Curation.Data.Pipelines;
Expand Down Expand Up @@ -171,9 +170,6 @@ public IPipelineUseCase GetDesignTimePipelineUseCase(RequiredPropertyInfo proper
#region Process Results Of Pipeline Read
public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener listener,GracefulCancellationToken cancellationToken)
{

//todo: This really shouldn't be needed surely
MySqlConnection.ClearAllPools();
MySqlBulkCopy.BulkInsertBatchTimeoutInSeconds = int.MaxValue; //forever

_sw.Start();
Expand Down
17 changes: 17 additions & 0 deletions Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ public class CachingSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvi
DicomTransferSyntax.JPEGProcess14SV1,
DicomTransferSyntax.JPEGProcess14,
DicomTransferSyntax.RLELossless,

// Lossy - if that's all the PACS has, that's all it can give us
DicomTransferSyntax.JPEGLSNearLossless,
DicomTransferSyntax.JPEG2000Lossy,
DicomTransferSyntax.JPEGProcess1,
DicomTransferSyntax.JPEGProcess2_4,

// Also allow video files, just in case
DicomTransferSyntax.HEVCH265Main10ProfileLevel51,
DicomTransferSyntax.HEVCH265MainProfileLevel51,
DicomTransferSyntax.MPEG2,
DicomTransferSyntax.MPEG2MainProfileHighLevel,
DicomTransferSyntax.MPEG4AVCH264BDCompatibleHighProfileLevel41,
DicomTransferSyntax.MPEG4AVCH264HighProfileLevel41,
DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For2DVideo,
DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For3DVideo,
DicomTransferSyntax.MPEG4AVCH264StereoHighProfileLevel42,

// Uncompressed
DicomTransferSyntax.ExplicitVRLittleEndian,
Expand Down
2 changes: 1 addition & 1 deletion Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void ThrottleRequest(DicomClient client, CancellationToken cancellationTo
SendRequest(client,cancellationToken);
transferTimer.Stop();
//valuein mills
var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000 * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds);
var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000f * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds);
if (delay > 0)
{
_listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Requests sleeping for " + delay / 1000 + "seconds"));
Expand Down
5 changes: 1 addition & 4 deletions Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,7 @@ public int Total()
{
foreach (var series in study.Series.Values)
{
foreach (var image in series.Images.Values)
{
count++;
}
count += series.Images.Values.Count;
}
}
}
Expand Down
106 changes: 106 additions & 0 deletions Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using Rdmp.Core.Caching.Pipeline.Sources;
using Rdmp.Core.Caching.Requests;
using Rdmp.Core.Curation;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.DataFlowPipeline;
using ReusableLibraryCode.Checks;
using ReusableLibraryCode.Progress;
using System;
using System.Diagnostics;

namespace Rdmp.Dicom.Cache.Pipeline
{
public class ProcessBasedCacheSource : CacheSource<SMIDataChunk>
{
[DemandsInitialization(@"Process to start (path only)",Mandatory = true)]
public string Command {get;set;}

[DemandsInitialization(@"Arguments to provide to the Process. Template with
%s start time
%e end time time to fetch
%d directory to put files fetched
Example:. './GetImages.exe ""%s"" ""%e%""'")]
public string Args {get;set;}

[DemandsInitialization("The datetime format for %s and %e.",Mandatory = true,DefaultValue = "yyyy-MM-dd HH:mm:ss")]
public string TimeFormat {get;set;}

[DemandsInitialization("True to throw an Exception if the process run returns a nonzero exit code", DefaultValue = true)]
public bool ThrowOnNonZeroExitCode {get;set;}

public override void Abort(IDataLoadEventListener listener)
{

}

public override void Check(ICheckNotifier notifier)
{

}

public override void Dispose(IDataLoadEventListener listener, Exception pipelineFailureExceptionIfAny)
{

}

public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken)
{
listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,$"ProcessBasedCacheSource version is {typeof(ProcessBasedCacheSource).Assembly.GetName().Version}. Assembly is {typeof(ProcessBasedCacheSource).Assembly} " ));

// Where we are putting the files
var cacheDir = new LoadDirectory(Request.CacheProgress.LoadProgress.LoadMetadata.LocationOfFlatFiles).Cache;
var cacheLayout = new SMICacheLayout(cacheDir, new SMICachePathResolver("ALL"));

Chunk = new SMIDataChunk(Request)
{
FetchDate = Request.Start,
Modality = "ALL",
Layout = cacheLayout
};

var workingDirectory = cacheLayout.GetLoadCacheDirectory(listener);

listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Working directory is:" + workingDirectory));
listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch Start is:" + request.Start));
listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch End is:" + request.End));

listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Command is:" + Command));
listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args template is:" + Args));
listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Datetime format is:" + TimeFormat));


string args = Args
.Replace("%s",request.Start.ToString(TimeFormat))
.Replace("%e",request.End.ToString(TimeFormat))
.Replace("%d",workingDirectory.FullName);

listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args resolved is:" + args));

using(var p = new Process())
{
p.StartInfo.FileName = Command;
p.StartInfo.Arguments = args;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += (sender, a) => listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,a.Data));

p.Start();
p.BeginOutputReadLine();

p.WaitForExit();

listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode));

if(p.ExitCode != 0 && ThrowOnNonZeroExitCode)
throw new Exception("Process exited with code " + p.ExitCode);
}

return Chunk;
}

public override SMIDataChunk TryGetPreview()
{
return null;
}
}
}
Loading