private DicomRepopulatorProcessor GetProcessor(FileInfo inputCsv, FileInfo inputExtraMapping,
                                                   DirectoryInfo inputDicomDirectory, Action <DicomRepopulatorOptions> adjustOptions, string memberName,
                                                   out DicomRepopulatorOptions options,
                                                   out DirectoryInfo outputDirPath)
    {
        outputDirPath = new(Path.Combine(_outputFileBase, memberName));

        //delete old content
        if (Directory.Exists(outputDirPath.FullName))
        {
            Directory.Delete(outputDirPath.FullName, true);
        }

        Directory.CreateDirectory(outputDirPath.FullName);


        options = new()
        {
            InputCsv           = inputCsv?.FullName,
            InputFolder        = inputDicomDirectory?.FullName,
            InputExtraMappings = inputExtraMapping?.FullName,
            OutputFolder       = outputDirPath.FullName,
            NumThreads         = 4
        };

        adjustOptions?.Invoke(options);

        return(new());
    }
}
    public void SpacesInCsvHeaderTest()
    {
        string       inputDirPath = Path.Combine(_inputFileBase, "SpacesInCsvHeaderTest");
        const string testFileName = IM_0001_0013_NAME;

        Directory.CreateDirectory(inputDirPath);
        TestData.Create(new(Path.Combine(inputDirPath, testFileName)), TestData.IMG_013);

        string outputDirPath = Path.Combine(_outputFileBase, "SpacesInCsvHeaderTest");
        string expectedFile  = Path.Combine(outputDirPath, testFileName);

        var options = new DicomRepopulatorOptions
        {
            InputCsv           = Path.Combine(TestContext.CurrentContext.TestDirectory, "SpacesInCsvHeaderTest.csv"),
            InputFolder        = inputDirPath,
            OutputFolder       = outputDirPath,
            InputExtraMappings = CreateExtraMappingsFile("ID:PatientID").FullName,
            NumThreads         = 1
        };

        int result = new DicomRepopulatorProcessor().Process(options, CancellationToken.None);

        Assert.AreEqual(0, result);

        Assert.True(File.Exists(expectedFile), "Expected output file {0} to exist", expectedFile);

        DicomFile file = DicomFile.Open(expectedFile);

        Assert.AreEqual("NewPatientID1", file.Dataset.GetValue <string>(DicomTag.PatientID, 0));
    }
Exemplo n.º 3
0
        public FilePathMatcher(CsvToDicomTagMapping map, DicomRepopulatorOptions options) : base(map, options)
        {
            if (map.FilenameColumn == null)
            {
                throw new ArgumentException("Map did not contain file name column");
            }

            Reader = new(map.CsvFile.OpenText(), new CsvConfiguration(System.Globalization.CultureInfo.CurrentCulture) with
            {
                TrimOptions = TrimOptions.Trim
            });
    public void MultipleSeriesTest(bool useSubfolder)
    {
        string       inputDirPath  = Path.Combine(_seriesFilesBase, "TestInput");
        const string testFileName1 = IM_0001_0013_NAME;
        const string testFileName2 = IM_0001_0019_NAME;

        Directory.CreateDirectory(Path.Combine(inputDirPath, "Series1"));
        Directory.CreateDirectory(Path.Combine(inputDirPath, "Series2"));
        TestData.Create(new(Path.Combine(inputDirPath, "Series1", testFileName1)), TestData.IMG_013, true);
        TestData.Create(new(Path.Combine(inputDirPath, "Series1", testFileName2)), TestData.IMG_013, false);
        TestData.Create(new(Path.Combine(inputDirPath, "Series2", testFileName1)), TestData.IMG_019, true);
        TestData.Create(new(Path.Combine(inputDirPath, "Series2", testFileName2)), TestData.IMG_019, false);

        string outputDirPath = Path.Combine(_seriesFilesBase, "TestOutput");
        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
        };

        int result = new DicomRepopulatorProcessor().Process(options, CancellationToken.None);

        Assert.AreEqual(0, result);

        Assert.True(File.Exists(expectedFile1), "Expected output file {0} to exist", expectedFile1);
        Assert.True(File.Exists(expectedFile2), "Expected output file {0} to exist", expectedFile2);
        Assert.True(File.Exists(expectedFile3), "Expected output file {0} to exist", expectedFile3);
        Assert.True(File.Exists(expectedFile4), "Expected output file {0} to exist", expectedFile4);

        DicomFile file = DicomFile.Open(expectedFile1);

        Assert.AreEqual("NewPatientID1", file.Dataset.GetValue <string>(DicomTag.PatientID, 0));

        file = DicomFile.Open(expectedFile2);
        Assert.AreEqual("NewPatientID1", file.Dataset.GetValue <string>(DicomTag.PatientID, 0));

        file = DicomFile.Open(expectedFile3);
        Assert.AreEqual("NewPatientID2", file.Dataset.GetValue <string>(DicomTag.PatientID, 0));

        file = DicomFile.Open(expectedFile4);
        Assert.AreEqual("NewPatientID2", file.Dataset.GetValue <string>(DicomTag.PatientID, 0));
    }
        public RepopulatorMatcher(CsvToDicomTagMapping map, DicomRepopulatorOptions options)
        {
            Options = options;
            Map     = map;

            if (!Map.IsBuilt)
            {
                throw new ArgumentException("Map has not been built yet");
            }

            if (string.IsNullOrWhiteSpace(options.InputFolder))
            {
                throw new ArgumentException("InputFolder has not been set");
            }
        }
        public IRepopulatorMatcher Create(CsvToDicomTagMapping map, DicomRepopulatorOptions options)
        {
            //We have a column that contains the exact location on disk of the image.  This is the best because it lets us stream the CSV
            if (map.FilenameColumn != null)
            {
                return(new FilePathMatcher(map, options));
            }

            //We have no file path column so must do matching based on 'key'.  This will require loading entire CSV into memory which may break
            //for very large datasets
            if (map.TagColumns.Any(c =>
                                   c.TagsToPopulate.Contains(DicomTag.SOPInstanceUID) ||
                                   c.TagsToPopulate.Contains(DicomTag.SeriesInstanceUID) ||
                                   c.TagsToPopulate.Contains(DicomTag.StudyInstanceUID)))
            {
                return(new TagMatcher(map, options));
            }

            return(null);
        }
    public RepopulatorUI()
    {
        InitializeComponent();

        State = new();

        try
        {
            if (File.Exists("RepopulatorUI.yaml"))
            {
                var des = new Deserializer();
                State = des.Deserialize <DicomRepopulatorOptions>(File.ReadAllText(StateFile));

                cbIncludeSubfolders.Checked = State.IncludeSubdirectories;
                tbInputFolder.Text          = State.InputFolder;
                tbInputCsv.Text             = State.InputCsv;
                tbExtraMappings.Text        = State.InputExtraMappings;
                tbOutputFolder.Text         = State.OutputFolder;
                nThreads.Value          = Math.Min(Math.Max(nThreads.Minimum, State.NumThreads), nThreads.Maximum);
                nErrorThreshold.Value   = Math.Min(Math.Max(nErrorThreshold.Minimum, State.ErrorThreshold), nErrorThreshold.Maximum);
                tbFilePattern.Text      = State.Pattern;
                tbFilenameColumn.Text   = State.FileNameColumn;
                cbAnonymise.Checked     = State.Anonymise;
                cbDeleteAsYouGo.Checked = State.DeleteAsYouGo;

                if (!string.IsNullOrWhiteSpace(State.CultureName))
                {
                    tbCulture.Text = State.CultureName;
                    State.Culture  = new(State.CultureName);
                }
                else
                {
                    tbCulture.Text = State.Culture.DisplayName;
                }

                tbSubFolderColumn.Text = State.SubFolderColumn;
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message, "Error in RepopulatorUI.yaml", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        tt = new() { InitialDelay = 0, AutoPopDelay = 32767, ShowAlways = true };
        tt.SetToolTip(btnInputFolder, HelpInputFolder);
        tt.SetToolTip(lblInputFolder, HelpInputFolder);

        tt.SetToolTip(btnInputCsv, HelpInputCsv);
        tt.SetToolTip(lblInputCsv, HelpInputCsv);

        tt.SetToolTip(btnExtraMappings, HelpExtraMappings);
        tt.SetToolTip(lblExtraMappings, HelpExtraMappings);

        tt.SetToolTip(cbIncludeSubfolders, HelpIncludeSubFolders);
        tt.SetToolTip(lblFileNameColumn, HelpFileNameColumn);
        tt.SetToolTip(lblFilePattern, HelpFilePattern);

        tt.SetToolTip(btnOutputFolder, HelpOutputFolder);
        tt.SetToolTip(lblOutputFolder, HelpOutputFolder);

        tt.SetToolTip(btnCopyToClipboard, HelpCopyToClipboard);

        tt.SetToolTip(lblErrorThreshold, HelpErrorThreshold);

        tt.SetToolTip(lblDone, HelpDone);
        tt.SetToolTip(lblErrors, HelpErrors);

        tt.SetToolTip(lblCulture, HelpCulture);

        tt.SetToolTip(lblSubFolder, HelpSubFolderColumn);
    }