diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b4783..7559bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +... + +## [1.0.2] - 2020-02-06 + +### Added + +- New option for DicomRepopulator to put images in root subfolders e.g. by PatientID + +### Changed + +- Improved GUI usability + ## [1.0.1] - 2019-12-09 ### Added @@ -18,7 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Initial version -[Unreleased]: https://github.com/HicServices/DicomTemplateBuilder/compare/v1.0.1...develop +[Unreleased]: https://github.com/HicServices/DicomTemplateBuilder/compare/v1.0.2...develop +[1.0.2]: https://github.com/HicServices/DicomTemplateBuilder/compare/v1.0.1...v1.0.2 [1.0.1]: https://github.com/HicServices/DicomTemplateBuilder/compare/v1.0.0...v1.0.1 [1.0.0]: https://github.com/HicServices/DicomTemplateBuilder/tree/v1.0.0 [DicomTypeTranslation]: https://github.com/HicServices/DicomTypeTranslation diff --git a/Repopulator/CsvToDicomColumn.cs b/Repopulator/CsvToDicomColumn.cs index d7c73ae..d9d05b7 100644 --- a/Repopulator/CsvToDicomColumn.cs +++ b/Repopulator/CsvToDicomColumn.cs @@ -5,20 +5,38 @@ namespace Repopulator { + + public enum ColumnRole + { + None = 0, + + /// + /// The column that contains the alleged location of dcm files on disk + /// + FilePath, + + /// + /// The column should be a top level subfolder under which to create files e.g. PatientID + /// + SubFolder, + } + public class CsvToDicomColumn { public string Name { get; } public int Index { get; } public HashSet TagsToPopulate { get; } - public bool IsFilePath { get; set; } - + + public ColumnRole Role { get; } - public CsvToDicomColumn(string colName, int index, bool isFileColumn,params DicomTag[] mappedTags) + public CsvToDicomColumn(string colName, int index, ColumnRole role,params DicomTag[] mappedTags) { - if (mappedTags != null && mappedTags.Any() && isFileColumn) + //cannot be DicomTag AND FilePath + if (mappedTags != null && mappedTags.Any() && role == ColumnRole.FilePath) throw new ArgumentException("Column has ambiguous role, it should either provide dicom tag substitutions or be the file path column not both"); - if ((mappedTags == null || !mappedTags.Any())&& !isFileColumn) + //if you don't have DicomTags you must have some other role + if ((mappedTags == null || !mappedTags.Any())&& role == ColumnRole.None) throw new ArgumentException("Column has no clear role, it should either provide dicom tag substitutions or be the file path column"); if (index < 0) @@ -35,7 +53,7 @@ public CsvToDicomColumn(string colName, int index, bool isFileColumn,params Dico Name = colName; Index = index; TagsToPopulate = new HashSet(mappedTags?? new DicomTag[0]); - IsFilePath = isFileColumn; + Role = role; } } } \ No newline at end of file diff --git a/Repopulator/CsvToDicomTagMapping.cs b/Repopulator/CsvToDicomTagMapping.cs index eb8e42f..c40a3ce 100644 --- a/Repopulator/CsvToDicomTagMapping.cs +++ b/Repopulator/CsvToDicomTagMapping.cs @@ -17,6 +17,12 @@ public class CsvToDicomTagMapping /// relatively (i.e. not absolute path names) /// public CsvToDicomColumn FilenameColumn; + + + /// + /// The column of the CSV which records. The column should be a top level subfolder under which to create files e.g. PatientID + /// + public CsvToDicomColumn SubFolderColumn; /// /// Columns which contain dicom tag values. This is not all the columns in the CSV. It does not include @@ -84,19 +90,28 @@ public bool BuildMap(DicomRepopulatorOptions options, out string log) if (match != null) { - if(match.IsFilePath) + if(match.Role == ColumnRole.FilePath) + { if (FilenameColumn != null) throw new Exception("There are 2+ FilenameColumn in the CSV"); else FilenameColumn = match; - else + } + + if(match.Role == ColumnRole.SubFolder) { - if(TagColumns.Any(c=>c.TagsToPopulate.Intersect(match.TagsToPopulate).Any())) - throw new Exception($"There are 2+ columns that both populate for one of the DicomTag(s) '{string.Join(",",match.TagsToPopulate)}'"); - - TagColumns.Add(match); + if (SubFolderColumn != null) + throw new Exception("There are 2+ SubFolderColumn in the CSV"); + else + SubFolderColumn = match; } + if(TagColumns.Any(c=>c.TagsToPopulate.Intersect(match.TagsToPopulate).Any())) + throw new Exception($"There are 2+ columns that both populate for one of the DicomTag(s) '{string.Join(",",match.TagsToPopulate)}'"); + + TagColumns.Add(match); + + sb.AppendLine($"Validated header '{header}'"); } else @@ -173,20 +188,23 @@ public CsvToDicomColumn GetKeyDicomTagAndColumnName(DicomRepopulatorOptions stat { CsvToDicomColumn toReturn = null; if(columnName.Equals(state.FileNameColumn,StringComparison.CurrentCultureIgnoreCase)) - toReturn = new CsvToDicomColumn(columnName,index,true); + toReturn = new CsvToDicomColumn(columnName,index,ColumnRole.FilePath); + if(columnName.Equals(state.SubFolderColumn, StringComparison.CurrentCultureIgnoreCase)) + toReturn = new CsvToDicomColumn(columnName,index,ColumnRole.SubFolder); + var found = DicomDictionary.Default.SingleOrDefault(entry => string.Equals(entry.Keyword ,columnName,StringComparison.CurrentCultureIgnoreCase)); if(found != null) if (toReturn == null) - toReturn = new CsvToDicomColumn(columnName,index,false,found.Tag); + toReturn = new CsvToDicomColumn(columnName,index,ColumnRole.None,found.Tag); else toReturn.TagsToPopulate.Add(found.Tag); //it's a file path AND a tag! ok... if (extraMappings != null && extraMappings.ContainsKey(columnName)) if(toReturn == null) - toReturn = new CsvToDicomColumn(columnName,index,false,extraMappings[columnName].ToArray()); + toReturn = new CsvToDicomColumn(columnName,index,ColumnRole.None,extraMappings[columnName].ToArray()); else toReturn.TagsToPopulate.UnionWith(extraMappings[columnName]); diff --git a/Repopulator/DicomRepopulator.cd b/Repopulator/DicomRepopulator.cd index 6de9266..64d9530 100644 --- a/Repopulator/DicomRepopulator.cd +++ b/Repopulator/DicomRepopulator.cd @@ -38,7 +38,7 @@ - AAAAAAAAAAAAAAAAAgAAAAQAAAAAAAAAAAEAABAAAAA= + AAAAAAAAAAAAAAAAEgAAAAQAAAAAAAAAAAEAAAAAAAA= CsvToDicomColumn.cs @@ -47,11 +47,13 @@ + + - AAACAAGAAAAAAAAAAAAAAABAAAAAAAAABAAAAARBAAA= + AAACAAGAAAQAAAAAAAAAAABAAAAAAAAABAAAAARBAAA= CsvToDicomTagMapping.cs @@ -67,7 +69,7 @@ - AAAAgQgABAAAAAAAQAECAAQQCAAAEAgEASAAAAACAAA= + AAAAgQgABAQAAAAAQAECAAQQCQAAEAgEASAAAAACAAA= DicomRepopulatorOptions.cs @@ -77,7 +79,7 @@ - AAhAAAAIACAAQQAAAgAAAIBAMAAABACAAAAQAAAAgAA= + AAhAAAAIACAAQQAAAgAAAIBAMgAABACAAAAQAAAAgAA= DicomRepopulatorProcessor.cs diff --git a/Repopulator/DicomRepopulatorOptions.cs b/Repopulator/DicomRepopulatorOptions.cs index 0e109ed..4f4e700 100644 --- a/Repopulator/DicomRepopulatorOptions.cs +++ b/Repopulator/DicomRepopulatorOptions.cs @@ -20,8 +20,12 @@ public class DicomRepopulatorOptions public string FileNameColumn = DefaultFileNameColumn; public bool Anonymise; public int ErrorThreshold = 100; + public string CultureName; + + [YamlIgnore] public CultureInfo Culture = CultureInfo.CurrentCulture; - + + public string SubFolderColumn; [YamlIgnore] public DirectoryInfo OutputDirectoryInfo => new DirectoryInfo(OutputFolder); @@ -34,6 +38,7 @@ public class DicomRepopulatorOptions [YamlIgnore] public FileInfo ExtraMappings => new FileInfo(InputExtraMappings); + } } \ No newline at end of file diff --git a/Repopulator/DicomRepopulatorProcessor.cs b/Repopulator/DicomRepopulatorProcessor.cs index bb3c931..8d060f5 100644 --- a/Repopulator/DicomRepopulatorProcessor.cs +++ b/Repopulator/DicomRepopulatorProcessor.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -7,15 +6,12 @@ using System.Threading; using System.Threading.Tasks; using Dicom; -using DicomTypeTranslation; using DicomTypeTranslation.Helpers; -using FAnsi.Discovery.QuerySyntax.Update; using NLog; using NLog.Config; using NLog.Targets; using Repopulator.Matchers; using Repopulator.TagUpdaters; -using TypeGuesser.Deciders; namespace Repopulator { @@ -66,7 +62,7 @@ public DicomRepopulatorProcessor(string currentDirectory = null) public int Process(DicomRepopulatorOptions options) { - _parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = options.NumThreads }; + _parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Math.Max(1,options.NumThreads) }; _tagUpdater = new ParseStringsUpdater(options.Culture); _anonymizer = options.Anonymise ? new DicomAnonymizer() : null; @@ -162,7 +158,10 @@ private void ProcessJob(RepopulatorJob job, DicomRepopulatorOptions options) _logger.Debug("Saving output file"); // Preserves any sub-directory structures - var outPath = Path.Combine(options.OutputDirectoryInfo.FullName, inputRelativePath); + var outPath = job.Map.SubFolderColumn != null + ? Path.Combine(options.OutputDirectoryInfo.FullName, job.Cells[job.Map.SubFolderColumn.Index],inputRelativePath) + : Path.Combine(options.OutputDirectoryInfo.FullName, inputRelativePath); + Directory.CreateDirectory(Path.GetDirectoryName(outPath)); job.File.Save(outPath); diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index 70fa76d..8c159a6 100644 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -7,6 +7,6 @@ [assembly: AssemblyCulture("")] // These should be replaced with correct values by the release process -[assembly: AssemblyVersion("1.0.1")] -[assembly: AssemblyFileVersion("1.0.1")] -[assembly: AssemblyInformationalVersion("1.0.1")] +[assembly: AssemblyVersion("1.0.2")] +[assembly: AssemblyFileVersion("1.0.2")] +[assembly: AssemblyInformationalVersion("1.0.2")] diff --git a/TemplateBuilder/Form1.Designer.cs b/TemplateBuilder/Form1.Designer.cs index ba2ee8b..a94aadd 100644 --- a/TemplateBuilder/Form1.Designer.cs +++ b/TemplateBuilder/Form1.Designer.cs @@ -35,26 +35,30 @@ private void InitializeComponent() this.olvName = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.tcDatagrids = new System.Windows.Forms.TabControl(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); - this.btnAddDicom = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.btnOpenTemplate = new System.Windows.Forms.ToolStripButton(); this.btnOnlineTemplates = new System.Windows.Forms.ToolStripButton(); - this.btnSave = new System.Windows.Forms.ToolStripButton(); - this.btnSaveAs = new System.Windows.Forms.ToolStripButton(); - this.btnNewTemplate = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); this.ddDatabaseType = new System.Windows.Forms.ToolStripComboBox(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton(); + this.dockPanel1 = new WeifenLuo.WinFormsUI.Docking.DockPanel(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.miNew = new System.Windows.Forms.ToolStripMenuItem(); + this.miNewTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.miOpen = new System.Windows.Forms.ToolStripMenuItem(); + this.miOpenTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.miOpenDicoms = new System.Windows.Forms.ToolStripMenuItem(); + this.miSaveTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.miSaveAsTemplate = new System.Windows.Forms.ToolStripMenuItem(); + this.windowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.miWindowYaml = new System.Windows.Forms.ToolStripMenuItem(); this.miWindowSql = new System.Windows.Forms.ToolStripMenuItem(); this.miWindowFiles = new System.Windows.Forms.ToolStripMenuItem(); this.miWindowTable = new System.Windows.Forms.ToolStripMenuItem(); - this.tagPopulatorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.dockPanel1 = new WeifenLuo.WinFormsUI.Docking.DockPanel(); + this.miRepopulator = new System.Windows.Forms.ToolStripMenuItem(); + this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.olvDicoms)).BeginInit(); this.toolStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); this.SuspendLayout(); // // olvDicoms @@ -97,49 +101,16 @@ private void InitializeComponent() // toolStrip1 // this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.btnAddDicom, - this.toolStripSeparator2, - this.btnOpenTemplate, this.btnOnlineTemplates, - this.btnSave, - this.btnSaveAs, - this.btnNewTemplate, this.toolStripSeparator1, this.toolStripLabel1, - this.ddDatabaseType, - this.toolStripSeparator3, - this.toolStripDropDownButton1}); - this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.ddDatabaseType}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); this.toolStrip1.Name = "toolStrip1"; this.toolStrip1.Size = new System.Drawing.Size(1205, 25); this.toolStrip1.TabIndex = 9; this.toolStrip1.Text = "toolStrip1"; // - // btnAddDicom - // - this.btnAddDicom.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.btnAddDicom.Image = ((System.Drawing.Image)(resources.GetObject("btnAddDicom.Image"))); - this.btnAddDicom.ImageTransparentColor = System.Drawing.Color.Magenta; - this.btnAddDicom.Name = "btnAddDicom"; - this.btnAddDicom.Size = new System.Drawing.Size(23, 22); - this.btnAddDicom.Text = "Open Dicom Files"; - this.btnAddDicom.Click += new System.EventHandler(this.btnAddDicom_Click); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); - // - // btnOpenTemplate - // - this.btnOpenTemplate.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.btnOpenTemplate.Image = ((System.Drawing.Image)(resources.GetObject("btnOpenTemplate.Image"))); - this.btnOpenTemplate.ImageTransparentColor = System.Drawing.Color.Magenta; - this.btnOpenTemplate.Name = "btnOpenTemplate"; - this.btnOpenTemplate.Size = new System.Drawing.Size(23, 22); - this.btnOpenTemplate.Text = "Open Template"; - this.btnOpenTemplate.Click += new System.EventHandler(this.openTemplate_Click); - // // btnOnlineTemplates // this.btnOnlineTemplates.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; @@ -150,36 +121,6 @@ private void InitializeComponent() this.btnOnlineTemplates.Text = "Go to online templates"; this.btnOnlineTemplates.Click += new System.EventHandler(this.btnOnlineTemplates_Click); // - // btnSave - // - this.btnSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.btnSave.Image = ((System.Drawing.Image)(resources.GetObject("btnSave.Image"))); - this.btnSave.ImageTransparentColor = System.Drawing.Color.Magenta; - this.btnSave.Name = "btnSave"; - this.btnSave.Size = new System.Drawing.Size(23, 22); - this.btnSave.Text = "Save"; - this.btnSave.Click += new System.EventHandler(this.btnSave_Click); - // - // btnSaveAs - // - this.btnSaveAs.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.btnSaveAs.Image = ((System.Drawing.Image)(resources.GetObject("btnSaveAs.Image"))); - this.btnSaveAs.ImageTransparentColor = System.Drawing.Color.Magenta; - this.btnSaveAs.Name = "btnSaveAs"; - this.btnSaveAs.Size = new System.Drawing.Size(23, 22); - this.btnSaveAs.Text = "Save As"; - this.btnSaveAs.Click += new System.EventHandler(this.btnSaveAs_Click); - // - // btnNewTemplate - // - this.btnNewTemplate.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.btnNewTemplate.Image = ((System.Drawing.Image)(resources.GetObject("btnNewTemplate.Image"))); - this.btnNewTemplate.ImageTransparentColor = System.Drawing.Color.Magenta; - this.btnNewTemplate.Name = "btnNewTemplate"; - this.btnNewTemplate.Size = new System.Drawing.Size(23, 22); - this.btnNewTemplate.Text = "New (empty) template"; - this.btnNewTemplate.Click += new System.EventHandler(this.toolStripButton1_Click); - // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; @@ -193,72 +134,150 @@ private void InitializeComponent() // // ddDatabaseType // - this.ddDatabaseType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.ddDatabaseType.Name = "ddDatabaseType"; - this.ddDatabaseType.Size = new System.Drawing.Size(121, 25); + this.ddDatabaseType.Size = new System.Drawing.Size(160, 25); this.ddDatabaseType.SelectedIndexChanged += new System.EventHandler(this.ddDatabaseType_SelectedIndexChanged); // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // dockPanel1 // - // toolStripDropDownButton1 + this.dockPanel1.Location = new System.Drawing.Point(636, 147); + this.dockPanel1.Name = "dockPanel1"; + this.dockPanel1.Size = new System.Drawing.Size(200, 100); + this.dockPanel1.TabIndex = 11; // - this.toolStripDropDownButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripDropDownButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.windowToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(1205, 24); + this.menuStrip1.TabIndex = 13; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miNew, + this.miOpen, + this.miSaveTemplate, + this.miSaveAsTemplate, + this.quitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "File"; + // + // miNew + // + this.miNew.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miNewTemplate}); + this.miNew.Name = "miNew"; + this.miNew.Size = new System.Drawing.Size(195, 22); + this.miNew.Text = "New"; + // + // miNewTemplate + // + this.miNewTemplate.Name = "miNewTemplate"; + this.miNewTemplate.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); + this.miNewTemplate.Size = new System.Drawing.Size(180, 22); + this.miNewTemplate.Text = "Template"; + this.miNewTemplate.Click += new System.EventHandler(this.miNewTemplate_Click); + // + // miOpen + // + this.miOpen.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miOpenTemplate, + this.miOpenDicoms}); + this.miOpen.Name = "miOpen"; + this.miOpen.Size = new System.Drawing.Size(195, 22); + this.miOpen.Text = "Open"; + // + // miOpenTemplate + // + this.miOpenTemplate.Name = "miOpenTemplate"; + this.miOpenTemplate.Size = new System.Drawing.Size(152, 22); + this.miOpenTemplate.Text = "Template.."; + this.miOpenTemplate.Click += new System.EventHandler(this.openTemplate_Click); + // + // miOpenDicoms + // + this.miOpenDicoms.Name = "miOpenDicoms"; + this.miOpenDicoms.Size = new System.Drawing.Size(152, 22); + this.miOpenDicoms.Text = "Dicom File(s)..."; + this.miOpenDicoms.Click += new System.EventHandler(this.btnAddDicom_Click); + // + // miSaveTemplate + // + this.miSaveTemplate.Image = ((System.Drawing.Image)(resources.GetObject("miSaveTemplate.Image"))); + this.miSaveTemplate.Name = "miSaveTemplate"; + this.miSaveTemplate.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.miSaveTemplate.Size = new System.Drawing.Size(195, 22); + this.miSaveTemplate.Text = "Save"; + this.miSaveTemplate.Click += new System.EventHandler(this.btnSave_Click); + // + // miSaveAsTemplate + // + this.miSaveAsTemplate.Name = "miSaveAsTemplate"; + this.miSaveAsTemplate.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.S))); + this.miSaveAsTemplate.Size = new System.Drawing.Size(195, 22); + this.miSaveAsTemplate.Text = "Save As..."; + this.miSaveAsTemplate.Click += new System.EventHandler(this.btnSaveAs_Click); + // + // windowToolStripMenuItem + // + this.windowToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.miWindowYaml, this.miWindowSql, this.miWindowFiles, this.miWindowTable, - this.tagPopulatorToolStripMenuItem}); - this.toolStripDropDownButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripDropDownButton1.Image"))); - this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripDropDownButton1.Name = "toolStripDropDownButton1"; - this.toolStripDropDownButton1.Size = new System.Drawing.Size(29, 22); - this.toolStripDropDownButton1.Text = "toolStripDropDownButton1"; + this.miRepopulator}); + this.windowToolStripMenuItem.Name = "windowToolStripMenuItem"; + this.windowToolStripMenuItem.Size = new System.Drawing.Size(63, 20); + this.windowToolStripMenuItem.Text = "Window"; // // miWindowYaml // this.miWindowYaml.Name = "miWindowYaml"; - this.miWindowYaml.Size = new System.Drawing.Size(180, 22); - this.miWindowYaml.Text = "Template (yaml)"; + this.miWindowYaml.Size = new System.Drawing.Size(152, 22); + this.miWindowYaml.Text = "Template Yaml"; this.miWindowYaml.Click += new System.EventHandler(this.WindowClicked); // // miWindowSql // this.miWindowSql.Name = "miWindowSql"; - this.miWindowSql.Size = new System.Drawing.Size(180, 22); - this.miWindowSql.Text = "Template (sql)"; + this.miWindowSql.Size = new System.Drawing.Size(152, 22); + this.miWindowSql.Text = "Template Sql"; this.miWindowSql.Click += new System.EventHandler(this.WindowClicked); // // miWindowFiles // this.miWindowFiles.Name = "miWindowFiles"; - this.miWindowFiles.Size = new System.Drawing.Size(180, 22); - this.miWindowFiles.Text = "Dicom File List"; + this.miWindowFiles.Size = new System.Drawing.Size(152, 22); + this.miWindowFiles.Text = "Dicom Files"; this.miWindowFiles.Click += new System.EventHandler(this.WindowClicked); // // miWindowTable // this.miWindowTable.Name = "miWindowTable"; - this.miWindowTable.Size = new System.Drawing.Size(180, 22); - this.miWindowTable.Text = "Table Viewer"; + this.miWindowTable.Size = new System.Drawing.Size(152, 22); + this.miWindowTable.Text = "Table View"; this.miWindowTable.Click += new System.EventHandler(this.WindowClicked); // - // tagPopulatorToolStripMenuItem + // miRepopulator // - this.tagPopulatorToolStripMenuItem.Name = "tagPopulatorToolStripMenuItem"; - this.tagPopulatorToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - this.tagPopulatorToolStripMenuItem.Text = "Tag Populator"; - this.tagPopulatorToolStripMenuItem.Click += new System.EventHandler(this.tagPopulatorToolStripMenuItem_Click); + this.miRepopulator.Name = "miRepopulator"; + this.miRepopulator.Size = new System.Drawing.Size(152, 22); + this.miRepopulator.Text = "Tag Populator"; + this.miRepopulator.Click += new System.EventHandler(this.miRepopulator_Click); // - // dockPanel1 + // quitToolStripMenuItem // - this.dockPanel1.Location = new System.Drawing.Point(12, 28); - this.dockPanel1.Name = "dockPanel1"; - this.dockPanel1.Size = new System.Drawing.Size(200, 100); - this.dockPanel1.TabIndex = 11; + this.quitToolStripMenuItem.Name = "quitToolStripMenuItem"; + this.quitToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.quitToolStripMenuItem.Text = "Quit"; + this.quitToolStripMenuItem.Click += new System.EventHandler(this.quitToolStripMenuItem_Click); // // Form1 // @@ -269,12 +288,16 @@ private void InitializeComponent() this.Controls.Add(this.olvDicoms); this.Controls.Add(this.tcDatagrids); this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; this.Name = "Form1"; this.Text = "Form1"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); ((System.ComponentModel.ISupportInitialize)(this.olvDicoms)).EndInit(); this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -286,24 +309,27 @@ private void InitializeComponent() private OLVColumn olvName; private System.Windows.Forms.TabControl tcDatagrids; private System.Windows.Forms.ToolStrip toolStrip1; - private System.Windows.Forms.ToolStripButton btnAddDicom; private System.Windows.Forms.ToolStripComboBox ddDatabaseType; - private System.Windows.Forms.ToolStripButton btnOpenTemplate; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripLabel toolStripLabel1; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; private System.Windows.Forms.ToolStripButton btnOnlineTemplates; - private System.Windows.Forms.ToolStripButton btnSave; - private System.Windows.Forms.ToolStripButton btnSaveAs; - private System.Windows.Forms.ToolStripButton btnNewTemplate; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1; + private WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel1; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem miOpen; + private System.Windows.Forms.ToolStripMenuItem miOpenTemplate; + private System.Windows.Forms.ToolStripMenuItem miOpenDicoms; + private System.Windows.Forms.ToolStripMenuItem miSaveTemplate; + private System.Windows.Forms.ToolStripMenuItem miSaveAsTemplate; + private System.Windows.Forms.ToolStripMenuItem windowToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem miNew; + private System.Windows.Forms.ToolStripMenuItem miNewTemplate; private System.Windows.Forms.ToolStripMenuItem miWindowYaml; private System.Windows.Forms.ToolStripMenuItem miWindowSql; private System.Windows.Forms.ToolStripMenuItem miWindowFiles; private System.Windows.Forms.ToolStripMenuItem miWindowTable; - private WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel1; - private System.Windows.Forms.ToolStripMenuItem tagPopulatorToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem miRepopulator; + private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem; } } diff --git a/TemplateBuilder/Form1.cs b/TemplateBuilder/Form1.cs index f05d0fc..c8ab4e3 100644 --- a/TemplateBuilder/Form1.cs +++ b/TemplateBuilder/Form1.cs @@ -19,6 +19,7 @@ using Dicom.Imaging; using FAnsi.Implementations.MySql; using FAnsi.Implementations.Oracle; +using FAnsi.Implementations.PostgreSql; using WeifenLuo.WinFormsUI.Docking; using DatabaseType = FAnsi.DatabaseType; @@ -30,11 +31,6 @@ public partial class Form1 : Form private Scintilla _scintillaTemplate; private Scintilla _scintillaSql; bool _setupFinished = false; - private ToolStripMenuItem miOpenDicoms; - private ToolStripMenuItem miOpenTemplate; - private ToolStripMenuItem miSaveTemplate; - private ToolStripMenuItem miSaveAsTemplate; - private ToolStripMenuItem miNewTemplate; DockContent dcDicoms = new DockContent(){HideOnClose = true}; @@ -56,6 +52,7 @@ public Form1() ImplementationManager.Load(); ImplementationManager.Load(); ImplementationManager.Load(); + ImplementationManager.Load(); ImageManager.SetImplementation(WinFormsImageManager.Instance); @@ -75,20 +72,7 @@ public Form1() ddDatabaseType.ComboBox.DataSource = Enum.GetValues(typeof(DatabaseType)); var menu = new ContextMenuStrip(); - miOpenDicoms = new ToolStripMenuItem("Open Dicom", null, (s, e) => OpenDicoms()) - {ShortcutKeys = Keys.Control | Keys.Shift | Keys.O}; - - miNewTemplate = new ToolStripMenuItem("New (empty) template",null,(s,e)=>NewTemplate()){ShortcutKeys = Keys.Control | Keys.N}; - miOpenTemplate = new ToolStripMenuItem("Open Template",null,(s,e)=>OpenTemplate()){ShortcutKeys = Keys.Control | Keys.O}; - miSaveTemplate = new ToolStripMenuItem("Save", null, (s, e) => Save()) {ShortcutKeys = Keys.Control | Keys.S}; - miSaveAsTemplate = new ToolStripMenuItem("Save As", null, (s, e) => SaveAs()){ShortcutKeys = Keys.Control | Keys.Shift | Keys.S}; - - menu.Items.Add(miOpenDicoms); - menu.Items.Add(miNewTemplate); - menu.Items.Add(miOpenTemplate); menu.Items.Add(new ToolStripMenuItem("Navigate To Templates (Online)", null, (s, e) => GoToOnlineTemplates())); - menu.Items.Add(miSaveTemplate); - menu.Items.Add(miSaveAsTemplate); ContextMenuStrip = menu; @@ -418,12 +402,7 @@ private void btnSaveAs_Click(object sender, EventArgs e) { SaveAs(); } - - private void toolStripButton1_Click(object sender, EventArgs e) - { - NewTemplate(); - } - + private void WindowClicked(object sender, EventArgs e) { DockContent dc = null; @@ -444,7 +423,7 @@ private void WindowClicked(object sender, EventArgs e) dc.Show(dockPanel1,DefaultDockLocations[dc]); } - private void tagPopulatorToolStripMenuItem_Click(object sender, EventArgs e) + private void miRepopulator_Click(object sender, EventArgs e) { var ui = new RepopulatorUI(); @@ -455,6 +434,16 @@ private void tagPopulatorToolStripMenuItem_Click(object sender, EventArgs e) dc.TabText = "Repopulator"; dc.Show(dockPanel1,DockState.Document); } + + private void miNewTemplate_Click(object sender, EventArgs e) + { + NewTemplate(); + } + + private void quitToolStripMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } } internal class TagValueNode diff --git a/TemplateBuilder/Form1.resx b/TemplateBuilder/Form1.resx index 388a4c7..f50e68a 100644 --- a/TemplateBuilder/Form1.resx +++ b/TemplateBuilder/Form1.resx @@ -121,128 +121,46 @@ 132, 17 - - - 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 - AABJRU5ErkJggg== - - - - - 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 gg== - + + 237, 17 + + - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG/SURBVDhPjZLdSypBGIfnP6ztorqIOlGJUVhrHE2FPikP - 1VGJoCyE2MR1IfuAoOxTbS686fTBieNuXwtdFFHQKbBBzLeZbURoo/YHz9y8+3veYVhU3SXX/F652PbF - NOxlSBp2zZ/in5G/2Bk5xs7wAXZQXGGM2bfoY4YXzzKh9RtsBUconeG1Sthmq7SNpzCvVcKuXCwWLdHs - 3zYLXJJqDNcyqja3oeUHlSsyEKfELkl/9Jz0L5xQDikHxDGdJe6ZtC6I8UZeZ4JTQxBc1l8iqTvyFaOJ - axJM3updgZ1LXkeoPZQ1BGzzd7ilI+KWVd3mT+m8jlC1GB+yT+zjXumY3N8/Uf5zHk085/OPhUJBb/En - K4Jy3POqzoare7mHscS/kk8+B2+MEtXAI+WA/hvQEzkB5+whdIf/gGcWg9CtdPA6E+QMwWjiAiaTt5aw - h/ZeeR2hzmDWELDNVrGNp4DXEaoS41O2QFr3Rs/Aalr8OxVBOZ4FlY/NKTHoUWIHzY+RzU8E9MG+SlnC - 0ji4bhZ0TmbfpxYiOBWzQBBlxR7YNx6o9dcuNI9sQdNwEhr61qDetwp1niWodSVAEBWKrLwB0o6Q0BOi - V9gAAAAASUVORK5CYII= + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m + dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKWSURBVDhPjZJbTxNBGIb7l4AunhJ/hdeGU4FSMICI + nDSaeKFGkGg0QhG0ECggimIBu4AGRShULBhMORTaIpQCPUN32bb7+s1UuSKEiyeTbud9vnd3RpNtGKsg + mgk7ESSUbIOoEsguSXOhdAyXro3jYpmI8wYxdLlcnBP0w1cAaJjAuOCOY8EtQU6okIj4UQrhwyR2wwoC + 0QT/LSkp7EUS2PDL6rhjP3H1gW1f0FvymcC5sBHHnT4/4gqFaWPBoxkEYwnsUiAaT3JxhFbv/hFWfTKs + jiBIAmoiM0HYQYLb5h2+icEE/oiC4EGCT2YNdqiNa0fG6raEuk4Pvi6FIOhHVCZQ7K5DEvj4JkZhow1+ + WmNyCjK1Ch0kqTqbLmF5S0KNyY3eSR+E4mGQQFRtawe41eODhyoyNgNHND3Jp8ekFLYCynHYuRXHzVfr + 6Jr4A23RRy7A9DIJurd5dR1NL2qyofTJHMoIffMsdPSc/fefqrYVdFg90BYOkYCOacoZRX3XJr0bQWt9 + lxf1nQwPak0emriB6o51VLW7UNm2iqqXa2i1uKDVvU8LJpei6TCRDhIkYeGa125e+UY7CSh43bhCLOPZ + 4AqyCt6lBROLYQp7/+E5ns7DNLm6w8XDlRSsaHGivOU3mvqXkJU/wARWiI4Q6kxeft5noez5LzzsWURm + Xj80dDUxOh/idSU6svtf8k6F3YmSpz9xr3Membl9JCgVMWwPUoO0YHLt86kwQXHzD9xtt5PADM05g1Ud + mg2QwH3mBrrGWTQYbcjI6VE1Qol1feD7Hgamdk9835NoaJ1B7YtpJgiwj/hY0H+yCPrRoFA8QtfTwm+Y + tvADsnSDdFRvkZn/hj5YH1XupZCZT87I6Y5k5Jq//QWbzBTt9kMQwwAAAABJRU5ErkJggg== \ No newline at end of file diff --git a/TemplateBuilder/RepopulatorUI.Designer.cs b/TemplateBuilder/RepopulatorUI.Designer.cs index b7f892e..327d85d 100644 --- a/TemplateBuilder/RepopulatorUI.Designer.cs +++ b/TemplateBuilder/RepopulatorUI.Designer.cs @@ -65,6 +65,8 @@ private void InitializeComponent() this.lblErrorThreshold = new System.Windows.Forms.Label(); this.lblCulture = new System.Windows.Forms.Label(); this.tbCulture = new System.Windows.Forms.TextBox(); + this.lblSubFolder = new System.Windows.Forms.Label(); + this.tbSubFolderColumn = new System.Windows.Forms.TextBox(); ((System.ComponentModel.ISupportInitialize)(this.nThreads)).BeginInit(); this.panel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nErrorThreshold)).BeginInit(); @@ -441,11 +443,30 @@ private void InitializeComponent() this.tbCulture.TabIndex = 23; this.tbCulture.TextChanged += new System.EventHandler(this.tbCulture_TextChanged); // + // lblSubFolder + // + this.lblSubFolder.AutoSize = true; + this.lblSubFolder.Location = new System.Drawing.Point(294, 165); + this.lblSubFolder.Name = "lblSubFolder"; + this.lblSubFolder.Size = new System.Drawing.Size(99, 13); + this.lblSubFolder.TabIndex = 24; + this.lblSubFolder.Text = "Subfolder (Column):"; + // + // tbSubFolderColumn + // + this.tbSubFolderColumn.Location = new System.Drawing.Point(399, 162); + this.tbSubFolderColumn.Name = "tbSubFolderColumn"; + this.tbSubFolderColumn.Size = new System.Drawing.Size(117, 20); + this.tbSubFolderColumn.TabIndex = 25; + this.tbSubFolderColumn.TextChanged += new System.EventHandler(this.tbSubFolderColumn_TextChanged); + // // RepopulatorUI // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScroll = true; + this.Controls.Add(this.tbSubFolderColumn); + this.Controls.Add(this.lblSubFolder); this.Controls.Add(this.tbCulture); this.Controls.Add(this.lblCulture); this.Controls.Add(this.nErrorThreshold); @@ -526,5 +547,7 @@ private void InitializeComponent() private System.Windows.Forms.Label lblErrorThreshold; private System.Windows.Forms.Label lblCulture; private System.Windows.Forms.TextBox tbCulture; + private System.Windows.Forms.Label lblSubFolder; + private System.Windows.Forms.TextBox tbSubFolderColumn; } } diff --git a/TemplateBuilder/RepopulatorUI.cs b/TemplateBuilder/RepopulatorUI.cs index 0e9a6f2..3e98d06 100644 --- a/TemplateBuilder/RepopulatorUI.cs +++ b/TemplateBuilder/RepopulatorUI.cs @@ -44,6 +44,9 @@ public partial class RepopulatorUI : UserControl public const string HelpCulture = "The culture to use for parsing string values into dicom types e.g. dates, numbers"; + public const string HelpSubFolderColumn + = "Optional, column in your CSV which provides the top level extraction folder under which all associated studies/series will go e.g. PatientID"; + public RepopulatorUI() { InitializeComponent(); @@ -67,10 +70,19 @@ public RepopulatorUI() tbFilePattern.Text = State.Pattern; tbFilenameColumn.Text = State.FileNameColumn; cbAnonymise.Checked = State.Anonymise; - tbCulture.Text = State.Culture.DisplayName; + + if (!string.IsNullOrWhiteSpace(State.CultureName)) + { + tbCulture.Text = State.CultureName; + State.Culture = new CultureInfo(State.CultureName); + } + else + tbCulture.Text = State.Culture.DisplayName; + + tbSubFolderColumn.Text = State.SubFolderColumn; } } - catch (Exception) + catch (Exception e) { } @@ -102,6 +114,8 @@ public RepopulatorUI() tt.SetToolTip(lblErrors,HelpErrors); tt.SetToolTip(lblCulture,HelpCulture); + + tt.SetToolTip(lblSubFolder,HelpSubFolderColumn); } @@ -226,6 +240,11 @@ private void nErrorThreshold_ValueChanged(object sender, EventArgs e) State.ErrorThreshold = (int) nErrorThreshold.Value; SaveState(); } + private void tbSubFolderColumn_TextChanged(object sender, EventArgs e) + { + State.SubFolderColumn = tbSubFolderColumn.Text; + SaveState(); + } private void btnValidateCsv_Click(object sender, EventArgs e) { @@ -310,6 +329,7 @@ private void tbCulture_TextChanged(object sender, EventArgs e) try { State.Culture = new CultureInfo(tbCulture.Text); + State.CultureName = tbCulture.Text; tbCulture.ForeColor = Color.Black; } catch (Exception) diff --git a/Tests/CsvToDicomColumnTests.cs b/Tests/CsvToDicomColumnTests.cs index 02e60c2..7fce859 100644 --- a/Tests/CsvToDicomColumnTests.cs +++ b/Tests/CsvToDicomColumnTests.cs @@ -11,28 +11,28 @@ public class CsvToDicomColumnTests [Test] public void NegativeIndex() { - var ex = Assert.Throws(() => new CsvToDicomColumn("fish", -1, true)); + var ex = Assert.Throws(() => new CsvToDicomColumn("fish", -1, ColumnRole.FilePath)); StringAssert.Contains(ex.Message,"index cannot be negative"); } [Test] public void NoClearRole() { - var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, false)); + var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, ColumnRole.None)); StringAssert.Contains("no clear role",ex.Message); } [Test] public void TooManyRoles() { - var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, true,DicomTag.ALineRate)); + var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, ColumnRole.FilePath,DicomTag.ALineRate)); StringAssert.Contains("has ambiguous role",ex.Message); } [Test] public void SequenceTags() { - var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, false,DicomTag.AbstractPriorCodeSequence)); + var ex = Assert.Throws(() => new CsvToDicomColumn("fish", 0, ColumnRole.None,DicomTag.AbstractPriorCodeSequence)); StringAssert.Contains("Sequence tags are not supported (AbstractPriorCodeSequence)",ex.Message); } } diff --git a/Tests/DicomRepopulatorTests.cs b/Tests/DicomRepopulatorTests.cs index 4323e3a..8adbb11 100644 --- a/Tests/DicomRepopulatorTests.cs +++ b/Tests/DicomRepopulatorTests.cs @@ -308,8 +308,9 @@ public void MultipleFilesSameSeriesTest() Assert.AreEqual("NewPatientID1", file.Dataset.GetValue(DicomTag.PatientID, 0)); } - [Test] - public void MultipleSeriesTest() + [TestCase(true)] + [TestCase(false)] + public void MultipleSeriesTest(bool useSubfolder) { string inputDirPath = Path.Combine(_seriesFilesBase, "TestInput"); const string testFileName1 = IM_0001_0013_NAME; @@ -323,16 +324,17 @@ public void MultipleSeriesTest() TestData.Create(new FileInfo(Path.Combine(inputDirPath, "Series2", testFileName2)), TestData.IMG_019,false); string outputDirPath = Path.Combine(_seriesFilesBase, "TestOutput"); - string expectedFile1 = Path.Combine(outputDirPath, "Series1", testFileName1); - string expectedFile2 = Path.Combine(outputDirPath, "Series1", testFileName2); - string expectedFile3 = Path.Combine(outputDirPath, "Series2", testFileName1); - string expectedFile4 = Path.Combine(outputDirPath, "Series2", testFileName2); + string expectedFile1 = Path.Combine(outputDirPath, useSubfolder? "NewPatientID1/Series1" : "Series1", testFileName1); + string expectedFile2 = Path.Combine(outputDirPath, useSubfolder? "NewPatientID1/Series1" : "Series1", testFileName2); + string expectedFile3 = Path.Combine(outputDirPath, useSubfolder? "NewPatientID2/Series2" : "Series2", testFileName1); + string expectedFile4 = Path.Combine(outputDirPath, useSubfolder? "NewPatientID2/Series2" : "Series2", testFileName2); var options = new DicomRepopulatorOptions { InputCsv = Path.Combine(TestContext.CurrentContext.TestDirectory, "TwoSeriesCsv.csv"), InputFolder = inputDirPath, OutputFolder = outputDirPath, + SubFolderColumn = useSubfolder ? "ID": null, InputExtraMappings = CreateExtraMappingsFile( "ID:PatientID" ).FullName, NumThreads = 4 };