Skip to content

Commit

Permalink
add new pipeline component
Browse files Browse the repository at this point in the history
  • Loading branch information
JFriel committed Jan 29, 2025
1 parent 52e9e79 commit 6e19014
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
2 changes: 1 addition & 1 deletion RDMP
Submodule RDMP updated 125 files
115 changes: 115 additions & 0 deletions Rdmp.Dicom/Extraction/DicomTagToCSV.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using Amazon.SSOOIDC.Internal;
using CsvHelper;
using FellowOakDicom;
using NPOI.HPSF;
using Org.BouncyCastle.Tls;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.DataFlowPipeline;
using Rdmp.Core.ReusableLibraryCode.Checks;
using Rdmp.Core.ReusableLibraryCode.Progress;
using Rdmp.Dicom.Extraction.FoDicomBased;
using Rdmp.Dicom.Extraction.FoDicomBased.DirectoryDecisions;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rdmp.Dicom.Extraction
{
public class DicomTagToCSV : IPluginDataFlowComponent<DataTable>
{
[DemandsInitialization("If the path filename contains relative file uris to images then this is the root directory")]
public string ArchiveRootIfAny { get; set; }

[DemandsInitialization("The column name in the extracted dataset which contains the location of the dicom files", Mandatory = true)]
public string RelativeArchiveColumnName { get; set; }

[DemandsInitialization("How many tries to allow for fetching the file. This setting may be useful on network drives or oversubscribed resources", DefaultValue = 0)]
public int FileFetchRetryLimit { get; set; }

[DemandsInitialization("How long to wait between file fetch retries in milliseconds.", DefaultValue = 100)]
public int FileFetchRetryTimeout { get; set; }

[DemandsInitialization("The number of errors (e.g. failed to find/anonymise file) to allow before abandoning the extraction", DefaultValue = 100)]
public int ErrorThreshold { get; set; }

private int _errors = 0;
private IPutDicomFilesInExtractionDirectories _putter;


public void Abort(IDataLoadEventListener listener)
{
//throw new NotImplementedException();
}

public void Check(ICheckNotifier notifier)
{
//throw new NotImplementedException();
}

public void Dispose(IDataLoadEventListener listener, Exception pipelineFailureExceptionIfAny)
{
//throw new NotImplementedException();
}

public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken)
{

var fileRows = new Dictionary<string, DataRow>();
var releaseIDs = new Dictionary<string, string>();
var dicomFiles = new List<(string, string)>();
foreach (DataRow processRow in toProcess.Rows)
{
var file = (string)processRow[RelativeArchiveColumnName];
fileRows.Add(file, processRow);
dicomFiles.Add((file, file));
}

var dicomFilePaths = new AmbiguousFilePath(ArchiveRootIfAny, dicomFiles).GetDataset(FileFetchRetryLimit, FileFetchRetryTimeout, listener);
foreach (var dcm in dicomFilePaths)
{
var filepath = Path.Combine("C:\\temp\\csvtest", dcm.Item1);
var sw = new StreamWriter(filepath);
using var w = new CsvWriter(sw, System.Globalization.CultureInfo.InvariantCulture);
w.WriteRecord(
dcm.Item2.Dataset.SelectMany(t => Entry.ProcessTag(dcm.Item1, t))
);
}

return toProcess;
}
}

internal class Entry
{
public string Id { get; }
public string Name { get; }
public string Value { get; }

public Entry(string id, string name, string value)
{
Id = id;
Name = name;
Value = value;
}

public static IEnumerable<Entry> ProcessTag(string id, DicomItem item)
{
return item switch
{
DicomAttributeTag aTag => aTag.Values.Select(v => new Entry(id, aTag.Tag.DictionaryEntry.Name, v.DictionaryEntry.Name)),
DicomStringElement s => StringEntries(id, s.Tag.DictionaryEntry.Name, s),
DicomSequence seq => seq.Items.SelectMany(ds => ds.SelectMany(i => ProcessTag(id, i))),
_ => new[] { new Entry(id, item.Tag.DictionaryEntry.Name, item.ToString()) }
};
}
private static IEnumerable<Entry> StringEntries(string id, string tag, DicomStringElement e)
{
for (int i = 0; i < e.Count; i++)
yield return new Entry(id, tag, e.Get<string>(i));
}
}
}

0 comments on commit 6e19014

Please sign in to comment.