Beispiel #1
0
        public void TestValidatePatientsNameAllowEmpty()
        {
            Initialize();

            _file.DataSet[DicomTags.PatientsName].SetStringValue("Patient^Anonymous^Mr");
            StudyData studyPrototype = CreateStudyPrototype();

            studyPrototype.PatientsNameRaw = "";

            DicomAnonymizer anonymizer = new DicomAnonymizer();

            anonymizer.ValidationOptions  = ValidationOptions.AllowEmptyPatientName;
            anonymizer.StudyDataPrototype = studyPrototype;
            anonymizer.Anonymize(_file);
        }
        public void TestFileMetaInformation()
        {
            Initialize();

            string oldUid = _file.DataSet[DicomTags.SopInstanceUid].ToString();

            StudyData studyPrototype = CreateStudyPrototype();

            DicomAnonymizer anonymizer = new DicomAnonymizer();

            anonymizer.StudyDataPrototype = studyPrototype;
            anonymizer.Anonymize(_file);

            Assert.AreNotEqual(oldUid, _file.DataSet[DicomTags.SopInstanceUid].ToString(), "Patient Confidentiality Issue - SOP Instance Uid is not anonymized.");
            Assert.AreNotEqual(oldUid, _file.MetaInfo[DicomTags.MediaStorageSopInstanceUid].ToString(), "Patient Confidentiality Issue - Media Storage SOP Instance Uid is not anonymized.");
            Assert.AreNotEqual(oldUid, _file.MediaStorageSopInstanceUid, "Patient Confidentiality Issue - Media Storage SOP Instance Uid is not anonymized.");
            Assert.AreEqual(_file.DataSet[DicomTags.SopInstanceUid].ToString(), _file.MetaInfo[DicomTags.MediaStorageSopInstanceUid].ToString(), "MetaInfo Media Storage SOP Instance doesn't match DataSet SOP Instance.");
            Assert.AreEqual(_file.DataSet[DicomTags.SopClassUid].ToString(), _file.MetaInfo[DicomTags.MediaStorageSopClassUid].ToString(), "MetaInfo Media Storage SOP Class doesn't match DataSet SOP Class.");
        }
        public void Anonymize_UsePredefinedPatientNameAndId_ShouldBeSetInAnonymizedDataset()
        {
            const string fileName     = "CT1_J2KI";
            var          dataset      = DicomFile.Open($"./Test Data/{fileName}").Dataset;
            const string expectedName = "fo-dicom";
            const string expectedId   = "GH-575";

            var anonymizer = new DicomAnonymizer();

            anonymizer.Profile.PatientName = expectedName;
            anonymizer.Profile.PatientID   = expectedId;

            var newDataset = anonymizer.Anonymize(dataset);

            var actualName = newDataset.GetSingleValue <string>(DicomTag.PatientName);
            var actualId   = newDataset.GetSingleValue <string>(DicomTag.PatientID);

            Assert.Equal(expectedName, actualName);
            Assert.Equal(expectedId, actualId);
        }
        public void Anonymize_PatientName_ShouldUseOriginalDicomEncoding()
        {
            const string fileName = "GH064.dcm";

            var originalDicom = DicomFile.Open($"./Test Data/{fileName}");

            var securityProfile = DicomAnonymizer.SecurityProfile.LoadProfile(null, DicomAnonymizer.SecurityProfileOptions.BasicProfile);

            securityProfile.PatientName = "kökö";

            var dicomAnonymizer = new DicomAnonymizer(securityProfile);
            var anonymizedDicom = dicomAnonymizer.Anonymize(originalDicom);

            // Ensure that we are using valid input data for test.
            Assert.Equal(Encoding.ASCII, DicomEncoding.Default);
            Assert.NotEqual(DicomEncoding.GetEncoding(originalDicom.Dataset.GetString(DicomTag.SpecificCharacterSet)), DicomEncoding.Default);

            // Ensure DICOM encoding same as original.
            Assert.Equal(originalDicom.Dataset.GetString(DicomTag.SpecificCharacterSet), anonymizedDicom.Dataset.GetString(DicomTag.SpecificCharacterSet));
            Assert.Equal("kökö", anonymizedDicom.Dataset.GetString(DicomTag.PatientName));
        }
Beispiel #5
0
        private void SaveFile(string filename)
        {
            if (_anonymizer != null)
            {
                DicomFile dicomFile = new DicomFile(filename);
                dicomFile.Load();

                _anonymizer.Anonymize(dicomFile);

                //anonymize first, then audit, since this is what gets exported.
                _exportedInstances.AddInstance(
                    dicomFile.DataSet[DicomTags.PatientId].ToString(),
                    dicomFile.DataSet[DicomTags.PatientsName].ToString(),
                    dicomFile.DataSet[DicomTags.StudyInstanceUid].ToString(),
                    filename);

                string fileName = System.IO.Path.Combine(OutputPath, dicomFile.MediaStorageSopInstanceUid);
                fileName += ".dcm";
                CheckFileExists(fileName);                 // this will never happen for anonymized images.
                if (_canceled)
                {
                    return;
                }

                dicomFile.Save(fileName);
            }
            else
            {
                _exportedInstances.AddPath(filename, false);

                string destination = Path.Combine(OutputPath, Path.GetFileName(filename));
                CheckFileExists(destination);
                if (_canceled)
                {
                    return;
                }

                File.Copy(filename, destination, true);
            }
        }
        public void TestStrict()
        {
            DicomFile       file       = CreateTestFile();
            DicomAnonymizer anonymizer = new DicomAnonymizer();

            anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;

            try
            {
                //this ought to work.
                anonymizer.Anonymize(file);
            }
            catch (Exception)
            {
                Assert.Fail("Not strict - no exception expected.");
            }

            anonymizer = new DicomAnonymizer();
            Assert.IsTrue(anonymizer.ValidationOptions == ValidationOptions.Default);             //strict by default

            //should throw.
            anonymizer.Anonymize(CreateTestFile());
        }
        private void OnClickAnonymize(object sender, EventArgs e)
        {
            var file = _anonymizer.Anonymize(_file);

            OpenFile(file);
        }
		public void TestValidatePatientsNameNotEqual()
		{
			Initialize();

			_file.DataSet[DicomTags.PatientsName].SetStringValue("Patient^Anonymous^Mr");
			StudyData studyPrototype = CreateStudyPrototype();
			studyPrototype.PatientsNameRaw = "PATIENT^ANONYMOUS";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
		}
		public void TestFileMetaInformation()
		{
			Initialize();

			string oldUid = _file.DataSet[DicomTags.SopInstanceUid].ToString();

			StudyData studyPrototype = CreateStudyPrototype();

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
			
			Assert.AreNotEqual(oldUid, _file.DataSet[DicomTags.SopInstanceUid].ToString(), "Patient Confidentiality Issue - SOP Instance Uid is not anonymized.");
			Assert.AreNotEqual(oldUid, _file.MetaInfo[DicomTags.MediaStorageSopInstanceUid].ToString(), "Patient Confidentiality Issue - Media Storage SOP Instance Uid is not anonymized.");
			Assert.AreNotEqual(oldUid, _file.MediaStorageSopInstanceUid, "Patient Confidentiality Issue - Media Storage SOP Instance Uid is not anonymized.");
			Assert.AreEqual(_file.DataSet[DicomTags.SopInstanceUid].ToString(), _file.MetaInfo[DicomTags.MediaStorageSopInstanceUid].ToString(), "MetaInfo Media Storage SOP Instance doesn't match DataSet SOP Instance.");
			Assert.AreEqual(_file.DataSet[DicomTags.SopClassUid].ToString(), _file.MetaInfo[DicomTags.MediaStorageSopClassUid].ToString(), "MetaInfo Media Storage SOP Class doesn't match DataSet SOP Class.");
		}
		public void TestRemappedReferencedSopUids()
		{
			// setup some files with unique "uids"
			DicomFile[] originals = new DicomFile[8];
			for (int n = 0; n < originals.Length; n++)
			{
				originals[n] = new DicomFile();
				originals[n].DataSet[DicomTags.StudyInstanceUid].SetStringValue((1000 + (n >> 2)).ToString());
				originals[n].DataSet[DicomTags.SeriesInstanceUid].SetStringValue((100 + (n >> 1)).ToString());
				originals[n].DataSet[DicomTags.SopInstanceUid].SetStringValue((10 + n).ToString());
				originals[n].DataSet[DicomTags.SopClassUid].SetStringValue((11111111111).ToString());
			}

			// setup up some cyclic and self references
			for (int n = 0; n < originals.Length; n++)
			{
				DicomSequenceItem sq;
				DicomFile n0File = originals[n];
				DicomFile n1File = originals[(n + 1)%originals.Length];
				DicomFile n2File = originals[(n + 2)%originals.Length];
				DicomFile n4File = originals[(n + 4)%originals.Length];

				n0File.DataSet[DicomTags.Uid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
				n0File.DataSet[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(DicomUid.GenerateUid().UID);
				sq[DicomTags.TextString].SetStringValue("UID of something not in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of self");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of next file study in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 2nd next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 2nd next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 2nd next file study in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 4th next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 4th next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("UID of 4th next file study in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
				sq[DicomTags.TextString].SetStringValue("Sop UID of something not in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Sop UID of self");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Sop UID of next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Sop UID of 2nd next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Sop UID of 4th next file in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
				sq[DicomTags.TextString].SetStringValue("Series UID of something not in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Series UID of self series");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Series UID of next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Series UID of 2nd next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Series UID of 4th next file series in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
				sq[DicomTags.TextString].SetStringValue("Study UID of something not in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.StudyInstanceUid].SetStringValue(n0File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Study UID of self study");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.StudyInstanceUid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Study UID of next file study in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.StudyInstanceUid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Study UID of 2nd next file study in data set");

				n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.StudyInstanceUid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.TextString].SetStringValue("Study UID of 4th next file study in data set");

				n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to self");
				sq[DicomTags.StudyInstanceUid].SetStringValue(n0File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());

				n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to next");
				sq[DicomTags.StudyInstanceUid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());

				n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to 2nd next");
				sq[DicomTags.StudyInstanceUid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());

				n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to 4th next");
				sq[DicomTags.StudyInstanceUid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
				sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.SeriesInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
				sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
				sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
			}

			// copy the originals and anonymize them
			DicomFile[] anonymized = new DicomFile[originals.Length];
			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;
			for (int n = 0; n < anonymized.Length; n++)
			{
				anonymized[n] = new DicomFile(string.Empty, originals[n].MetaInfo.Copy(true, true, true), originals[n].DataSet.Copy(true, true, true));
				anonymizer.Anonymize(anonymized[n]);
			}

			// generate validation dump strings - unique uids are mapped to sequential numbers
			string originalDumpValidationString = GenerateHierarchicalUidValidationDumpString(originals);
			string anonymizedDumpValidationString = GenerateHierarchicalUidValidationDumpString(anonymized);

			// if the hierarchical structure and pattern of uids is the same, then the relationships have been preserved.
			Assert.AreEqual(originalDumpValidationString, anonymizedDumpValidationString, "Relationships of anonymized data set differ compared to those of original data set.");
		}
Beispiel #11
0
        public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request)
        {
            Console.WriteLine("received cstore request " + request.ToString());

            if (File.Exists("singleImage.txt"))
            {
                Console.WriteLine("now save on ./images/file.jpg");

                File.Delete("./images/file.dcm");
                var dicomFile = new DicomFile(request.File.Dataset);
                //  dicomFile.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1);
                dicomFile.Save("./images/file.dcm");
                var image = new DicomImage("./images/file.dcm");
                File.Delete("./images/file.jpg");
                image.RenderImage().AsClonedBitmap().Save("./images/file.jpg");
            }
            else // else save image to database
            {
                Console.WriteLine("now save in database" + Environment.NewLine);
                try
                {
                    // get parameters
                    string dateString = "";
                    request.Dataset.TryGetSingleValue(DicomTag.StudyDate, out dateString);
                    DateTime date             = DateTime.ParseExact(dateString, "yyyyMMdd", CultureInfo.InvariantCulture);
                    string   StudyInstanceUID = "";
                    request.Dataset.TryGetSingleValue(DicomTag.StudyInstanceUID, out StudyInstanceUID);
                    string SeriesInstanceUID = "";
                    request.Dataset.TryGetSingleValue(DicomTag.SeriesInstanceUID, out SeriesInstanceUID);
                    string SOPInstanceUID = "";
                    request.Dataset.TryGetSingleValue(DicomTag.SOPInstanceUID, out SOPInstanceUID);

                    // save in database folder
                    var pathInDatabase = Path.GetFullPath("./databaseFolder");
                    // take last two numbers, for examples seriesinstanceuid ends with .150.0
                    var    seriesUIDs = SeriesInstanceUID.Split('.');
                    string seriesUID  = seriesUIDs[seriesUIDs.Length - 2] + "." + seriesUIDs[seriesUIDs.Length - 1];
                    var    sopUIDs    = SOPInstanceUID.Split('.');
                    string sopUID     = sopUIDs[sopUIDs.Length - 2] + "." + sopUIDs[sopUIDs.Length - 1];

                    pathInDatabase = Path.Combine(pathInDatabase, date.Year.ToString(), date.Month.ToString(), date.Day.ToString(),
                                                  StudyInstanceUID, seriesUID);
                    if (!Directory.Exists(pathInDatabase))
                    {
                        Directory.CreateDirectory(pathInDatabase);
                    }
                    string imagePath = Path.Combine(pathInDatabase,
                                                    sopUID + ".dcm");
                    if (!File.Exists(imagePath))
                    {
                        request.File.Save(imagePath);
                        Console.WriteLine("received and saved a file in database");
                    }
                    else
                    {
                        Console.WriteLine("File already present in database");
                    }

                    //DicomAnonymizer.SecurityProfileOptions.
                    var profile = new DicomAnonymizer.SecurityProfile();
                    profile.PatientName = "random";
                    DicomAnonymizer anonymizer        = new DicomAnonymizer(profile);
                    DicomDataset    anonymizedDataset = anonymizer.Anonymize(request.Dataset);

                    // DICOMANONYMYZER + DICOMDIR DATABASE
                    DicomDirectoryTest s = new DicomDirectoryTest();

                    //

                    // get more data
                    string PatientName = "";
                    anonymizedDataset.TryGetSingleValue(DicomTag.PatientName, out PatientName);
                    Console.WriteLine("patient name " + PatientName);
                    string PatientID = "";
                    anonymizedDataset.TryGetSingleValue(DicomTag.PatientID, out PatientID);


                    // add entry in database
                    var study = new StudyQueryOut
                    {
                        StudyInstanceUID = StudyInstanceUID,
                        PatientID        = PatientID,
                        PatientName      = PatientName,
                        StudyDate        = date
                    };
                    using (var db = new LiteDatabase("./databaseFolder/database.db"))
                    {
                        var studies = db.GetCollection <StudyQueryOut>("studies");
                        if (studies.FindById(StudyInstanceUID) == null)
                        {
                            studies.Insert(study);
                        }
                    }
                }
                catch (Exception ec) { Console.WriteLine(ec.Message + "   " + ec.ToString()); }
            }
            return(new DicomCStoreResponse(request, DicomStatus.Success));
        }
		public void TestValidateStudyIdNotEqual()
		{
			Initialize();

			_file.DataSet[DicomTags.StudyId].SetStringValue("123");
			StudyData studyPrototype = CreateStudyPrototype();
			studyPrototype.StudyId = "123";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
		}
Beispiel #13
0
        private List <SopInstanceNode> DoBuildTree()
        {
            bool doAnonymize = _anonymize;
            Dictionary <string, string> uidMap = new Dictionary <string, string>();
            List <SopInstanceNode>      sops   = new List <SopInstanceNode>();

            // TODO: perform some performance tests to adjust these weights
            float aweight = doAnonymize ? 0.45f : 0;         // portion of the work to anonymize the instances
            float pweight = (1 - aweight) * 0.75f;           // portion of the work to reassign uids
            float mweight = 1 - pweight - aweight;           // portion of the work to remap related uids
            int   count   = _patients.Count;
            int   now     = 0;

            this.Progress = 0;

            // traverse the tree assign new instance uids
            foreach (PatientNode patient in _patients)
            {
                if (patient.Parent != _rootNode)
                {
                    throw new NullReferenceException("Unsynchronized parent-child relationship");
                }

                now++;

                foreach (StudyNode study in patient.Studies)
                {
                    if (study.Parent != patient)
                    {
                        throw new NullReferenceException("Unsynchronized parent-child relationship");
                    }

                    string studyUid = NewUid();
                    uidMap.Add(study.InstanceUid, studyUid);
                    study.InstanceUid = studyUid;

                    foreach (SeriesNode series in study.Series)
                    {
                        if (series.Parent != study)
                        {
                            throw new NullReferenceException("Unsynchronized parent-child relationship");
                        }

                        string seriesUid = NewUid();
                        uidMap.Add(series.InstanceUid, seriesUid);
                        series.InstanceUid = seriesUid;

                        foreach (SopInstanceNode sop in series.Images)
                        {
                            if (sop.Parent != series)
                            {
                                throw new NullReferenceException("Unsynchronized parent-child relationship");
                            }

                            string sopUid = NewUid();
                            uidMap.Add(sop.InstanceUid, sopUid);
                            sop.InstanceUid = sopUid;

                            patient.Update(sop.DicomData);
                            study.Update(sop.DicomData, true);
                            series.Update(sop.DicomData, true);
                            sop.Update(sop.DicomData, true);

                            sops.Add(sop);
                        }
                    }
                }

                this.Progress = mweight * now / count;
            }

            // map any uids that point to an instance that was just reassigned
            count = sops.Count;
            now   = 0;
            foreach (SopInstanceNode sop in sops)
            {
                MapKnownUids(sop.DicomData, uidMap);

                now++;
                this.Progress = mweight * now / count;
            }

            // run the anonymizer if required
            if (doAnonymize)
            {
                DicomAnonymizer anonymizer = new DicomAnonymizer();
                anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;

                count = sops.Count;
                now   = 0;

                foreach (SopInstanceNode sop in sops)
                {
                    anonymizer.Anonymize(sop.DicomFile);

                    SeriesNode  series  = sop.Parent;
                    StudyNode   study   = series.Parent;
                    PatientNode patient = study.Parent;

                    // overwrite the anonymized data with any edited properties
                    // anonymizer writes in new anonymized uids based on the new structure, so don't overwrite them!
                    // instead, get the new uids and put them back into the node
                    patient.Update(sop.DicomData);

                    study.Update(sop.DicomData, false);
                    study.InstanceUid = sop.DicomData[DicomTags.StudyInstanceUid].GetString(0, "");

                    series.Update(sop.DicomData, false);
                    series.InstanceUid = sop.DicomData[DicomTags.SeriesInstanceUid].GetString(0, "");

                    sop.Update(sop.DicomData, false);
                    sop.InstanceUid = sop.DicomData[DicomTags.SopInstanceUid].GetString(0, "");

                    now++;
                    this.Progress = mweight * now / count;
                }
            }

            return(sops);
        }
Beispiel #14
0
        string WorkerFunc(Tuple <string, Tuple <int, int, int, int>, List <string> > param, BackgroundWorker worker, DoWorkEventArgs e)
        {
            List <string> lFailed            = new List <string>();
            string        strPath            = param.Item1;
            Tuple <int, int, int, int> lCrop = param.Item2;
            List <string> files = param.Item3;

            bool bCrop = lCrop.Item1 + lCrop.Item2 + lCrop.Item3 + lCrop.Item4 > 0 ? true : false;

            DicomUIDGenerator uidGen = new DicomUIDGenerator();
            List <Tuple <string, string, string, string> > listDCM = new List <Tuple <string, string, string, string> >();

            int i = 0, k = 0;

            // Randomize input list
            Random rand = new Random();

            // For each spot in the array, pick
            // a random item to swap into that spot.
            for (k = 0; k < files.Count - 1; k++)
            {
                int    j    = rand.Next(k, files.Count);
                string temp = files[k];
                files[k] = files[j];
                files[j] = temp;
            }

            DateTime dt = DateTime.Now;


            int nSuccess = 0;

            foreach (string strFile in files)
            {
                i++;
                DicomFile file;
                try
                {
                    file = DicomFile.Open(strFile);
                }
                catch (Exception ex)
                {
                    // Transmit message back with worker?
                    lFailed.Add(strFile);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    continue;
                }

                string strOriginalPatientID = "";

                try
                {
                    strOriginalPatientID = file.Dataset.GetValue <string>(DicomTag.PatientID, 0);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }

                DicomAnonymizer anon = new DicomAnonymizer();
                DicomFile       fileAnon;
                try
                {
                    fileAnon = anon.Anonymize(file);
                }
                catch (Exception ex)
                {
                    // Transmit message back with worker?
                    lFailed.Add(strFile);
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    continue;
                }


                DicomTag[] tagsToRemove = { DicomTag.StudyDate, DicomTag.StudyTime, DicomTag.PatientID, DicomTag.StudyID, DicomTag.StudyInstanceUID };

                foreach (DicomTag d in tagsToRemove)
                {
                    try
                    {
                        fileAnon.Dataset.Remove(d);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine("Error removing element: " + ex.ToString());
                    }
                }


                fileAnon.Dataset.Add(DicomTag.StudyInstanceUID, DicomUID.Generate());
                fileAnon.Dataset.Add(DicomTag.StudyDate, dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00"));
                fileAnon.Dataset.Add(DicomTag.StudyTime, dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00"));
                fileAnon.Dataset.Add(DicomTag.PatientID, i.ToString());
                fileAnon.Dataset.Add(DicomTag.StudyID, i.ToString());

                string strStudyID = fileAnon.Dataset.GetValue <string>(DicomTag.StudyInstanceUID, 0);



                try
                {
                    var header    = DicomPixelData.Create(fileAnon.Dataset);
                    var pixelData = PixelDataFactory.Create(header, header.NumberOfFrames - 1);

                    int rows    = header.Height;
                    int columns = header.Width;

                    Array  a;
                    byte[] result;

                    bool b16bit = false;

                    if (pixelData is GrayscalePixelDataU16)
                    {
                        ushort[] pixels = ((GrayscalePixelDataU16)pixelData).Data;
                        a      = pixels;
                        b16bit = true;
                    }
                    else if (pixelData is GrayscalePixelDataS16)
                    {
                        short[] pixels = ((GrayscalePixelDataS16)pixelData).Data;
                        a      = pixels;
                        b16bit = true;
                    }
                    else if (pixelData is GrayscalePixelDataU32)
                    {
                        uint[] pixels = ((GrayscalePixelDataU32)pixelData).Data;
                        a = pixels;
                    }
                    else if (pixelData is GrayscalePixelDataS32)
                    {
                        int[] pixels = ((GrayscalePixelDataS32)pixelData).Data;
                        a = pixels;
                    }
                    else if (pixelData is GrayscalePixelDataU8)
                    {
                        byte[] pixels = ((GrayscalePixelDataU8)pixelData).Data;
                        a = pixels;
                    }
                    else
                    {
                        throw new Exception("DICOM image format not supported (this program only supports greyscale).");
                    }

                    // Can't seem to figure out the byte formatting between 16-bit greyscale DCM versus C#'s 16-bit greyscale.
                    //b16bit = false;

                    if (bCrop)
                    {
                        // Top
                        if (lCrop.Item1 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item1));
                            Array.Copy(a, columns * lCrop.Item1, cropped, 0, cropped.Length);
                            a     = cropped;
                            rows -= lCrop.Item1;
                        }

                        // Right
                        if (lCrop.Item2 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item2));

                            for (k = 0; k < rows; k++)
                            {
                                Array.Copy(a, k * columns, cropped, k * (columns - lCrop.Item2), columns - lCrop.Item2);
                            }

                            a        = cropped;
                            columns -= lCrop.Item2;
                        }

                        // Bottom
                        if (lCrop.Item3 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item3));
                            Array.Copy(a, 0, cropped, 0, cropped.Length);
                            a     = cropped;
                            rows -= lCrop.Item3;
                        }

                        // Left
                        if (lCrop.Item4 > 0)
                        {
                            Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item4));

                            for (k = 0; k < rows; k++)
                            {
                                Array.Copy(a, k * columns + lCrop.Item4, cropped, k * (columns - lCrop.Item4), columns - lCrop.Item4);
                            }

                            a        = cropped;
                            columns -= lCrop.Item4;
                        }

                        // Now we need to copy the Array "a" into a byte array.
                        // But first!  Should we make sure that it's actually a 16-bit array?
                        int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0));
                        result = new byte[nBytes];
                        Buffer.BlockCopy(a, 0, result, 0, nBytes);

                        Dicom.IO.Buffer.MemoryByteBuffer buffer = new Dicom.IO.Buffer.MemoryByteBuffer(result);
                        DicomDataset dataset = new DicomDataset();

                        dataset = fileAnon.Dataset.Clone();

                        dataset.AddOrUpdate(DicomTag.Rows, (ushort)rows);
                        dataset.AddOrUpdate(DicomTag.Columns, (ushort)columns);

                        DicomPixelData newPixelData = DicomPixelData.Create(dataset, true);
                        newPixelData.BitsStored                = header.BitsStored;
                        newPixelData.SamplesPerPixel           = header.SamplesPerPixel;
                        newPixelData.HighBit                   = header.HighBit;
                        newPixelData.PhotometricInterpretation = header.PhotometricInterpretation;
                        newPixelData.PixelRepresentation       = header.PixelRepresentation;
                        newPixelData.PlanarConfiguration       = header.PlanarConfiguration;
                        newPixelData.Height = (ushort)rows;
                        newPixelData.Width  = (ushort)columns;
                        newPixelData.AddFrame(buffer);

                        fileAnon = new DicomFile(dataset);
                    }

                    // Only do this if it's a 16bit file that we want a 16bit png for
                    if (b16bit)
                    {
                        int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0));
                        result = new byte[nBytes];

                        // If we're using a format that's "16bit" but actually less, scale the values?
                        if (header.BitsStored < header.BitsAllocated)
                        {
                            int nShift = header.BitsAllocated - header.BitsStored;
                            int nFlag  = (0x1 << header.BitsStored) - 1;
                            for (k = 0; k < a.Length; k++)
                            {
                                a.SetValue((ushort)(((nFlag - ((ushort)a.GetValue(k) & nFlag)) << nShift) & 0xFFFF), k);
                            }
                        }

                        Buffer.BlockCopy(a, 0, result, 0, nBytes);

                        unsafe
                        {
                            fixed(byte *ptr = result)
                            {
                                using (Bitmap img16 = new Bitmap(columns, rows, 4 * ((2 * columns + 3) / 4), System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, new IntPtr(ptr)))
                                {
                                    SaveBmp(img16, strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.tif");
                                    //img16.Save(strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.png");
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("Failed to crop image");
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }


                fileAnon.Save(strPath + "/Anonymised/" + strStudyID + ".dcm");

                listDCM.Add(new Tuple <string, string, string, string>(i.ToString(), strStudyID, strFile, strOriginalPatientID));

                var img = new DicomImage(strPath + "/Anonymised/" + strStudyID + ".dcm");

                // Convert DCM to a 32-bit per pixel (8-bit per each color RGB + 8-bit unused) PNG file
                try
                {
                    Dicom.IO.PinnedIntArray px = img.RenderImage().Pixels;
                    int[] pxi = px.Data;

                    byte[] result = new byte[px.ByteSize];
                    Buffer.BlockCopy(pxi, 0, result, 0, result.Length);

                    unsafe
                    {
                        fixed(byte *ptr = result)
                        {
                            using (Bitmap image = new Bitmap(img.Width, img.Height, img.Width * 4,
                                                             System.Drawing.Imaging.PixelFormat.Format32bppRgb, new IntPtr(ptr)))
                            {
                                image.Save(strPath + "/Anonymised/" + strStudyID + ".png");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }


                worker.ReportProgress(i * 100 / files.Count);
                nSuccess++;

                //Console.WriteLine("Anonymized image " + i + " (of " + nFrames + " frame" + (nFrames == 1 ? "" : "s") + "): " + strFile);
            }

            // Create a map file

            using (System.IO.StreamWriter file =
                       new System.IO.StreamWriter(new FileStream(strPath + "/Anonymised/Map.csv", FileMode.Create, FileAccess.ReadWrite), Encoding.UTF8))
            {
                file.WriteLine("NewPatientID,NewStudyInstanceUID,OriginalFile,OriginalPatientID");
                foreach (Tuple <string, string, string, string> line in listDCM)
                {
                    file.WriteLine(line.Item1 + "," + line.Item2 + "," + line.Item3 + "," + line.Item4);
                }
            }

            string strRet = nSuccess.ToString() + " images successfully anonymised, Map.csv created.\nOutput at:\n" + strPath + "\\Anonymised";

            if (lFailed.Count > 0)
            {
                strRet += "\nThese files failed to anonymise:";
                foreach (string sf in lFailed)
                {
                    strRet += "\n" + sf;
                }
            }
            return(strRet);
        }
		public void TestStrict()
		{
			DicomFile file = CreateTestFile();
			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;

			try
			{
				//this ought to work.
				anonymizer.Anonymize(file);
			}
			catch(Exception)
			{
				Assert.Fail("Not strict - no exception expected.");
			}

			anonymizer = new DicomAnonymizer();
			Assert.IsTrue(anonymizer.ValidationOptions == ValidationOptions.Default); //strict by default

			//should throw.
			anonymizer.Anonymize(CreateTestFile());
		}
		public void TestPrototypes()
		{
			Initialize();

			StudyData studyPrototype = new StudyData();
			studyPrototype.PatientId = "123";
			studyPrototype.PatientsBirthDateRaw = "19760810";
			studyPrototype.PatientsNameRaw = "Patient^Anonymous";
			studyPrototype.PatientsSex = "M";
			studyPrototype.StudyDateRaw = "20080220";
			studyPrototype.StudyDescription= "Test";
			studyPrototype.StudyId = "Test";

			SeriesData seriesPrototype = new SeriesData();
			seriesPrototype.SeriesDescription = "Series";
			seriesPrototype.ProtocolName = "Protocol";
			seriesPrototype.SeriesNumber = "1";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.SeriesDataPrototype = seriesPrototype;
			anonymizer.Anonymize(_file);

			AfterAnonymize(studyPrototype, seriesPrototype);

			//validate the adjusted dates.
			Assert.AreEqual("20080220", _anonymizedDateData.InstanceCreationDate, "Anonymized InstanceCreationDate doesn't match StudyDate");
			Assert.AreEqual("20080220", _anonymizedDateData.SeriesDate, "Anonymized SeriesDate doesn't match StudyDate");
			Assert.AreEqual("20080220", _anonymizedDateData.ContentDate, "Anonymized ContentDate doesn't match StudyDate");
			Assert.AreEqual("20080220100406", _anonymizedDateData.AcquisitionDatetime, "Anonymized AcquisitionDatetime doesn't match StudyDate/Time");
		}
		public void TestSimple()
		{
			Initialize();

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;
			anonymizer.Anonymize(_file);

			AfterAnonymize(new StudyData(), new SeriesData());

			ValidateNullDates(_anonymizedDateData);
		}
        public void TestRemappedReferencedSopUids()
        {
            // setup some files with unique "uids"
            DicomFile[] originals = new DicomFile[8];
            for (int n = 0; n < originals.Length; n++)
            {
                originals[n] = new DicomFile();
                originals[n].DataSet[DicomTags.StudyInstanceUid].SetStringValue((1000 + (n >> 2)).ToString());
                originals[n].DataSet[DicomTags.SeriesInstanceUid].SetStringValue((100 + (n >> 1)).ToString());
                originals[n].DataSet[DicomTags.SopInstanceUid].SetStringValue((10 + n).ToString());
                originals[n].DataSet[DicomTags.SopClassUid].SetStringValue((11111111111).ToString());
            }

            // setup up some cyclic and self references
            for (int n = 0; n < originals.Length; n++)
            {
                DicomSequenceItem sq;
                DicomFile         n0File = originals[n];
                DicomFile         n1File = originals[(n + 1) % originals.Length];
                DicomFile         n2File = originals[(n + 2) % originals.Length];
                DicomFile         n4File = originals[(n + 4) % originals.Length];

                n0File.DataSet[DicomTags.Uid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
                n0File.DataSet[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(DicomUid.GenerateUid().UID);
                sq[DicomTags.TextString].SetStringValue("UID of something not in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of self");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of next file study in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 2nd next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 2nd next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 2nd next file study in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 4th next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 4th next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.Uid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("UID of 4th next file study in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
                sq[DicomTags.TextString].SetStringValue("Sop UID of something not in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Sop UID of self");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Sop UID of next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Sop UID of 2nd next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Sop UID of 4th next file in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
                sq[DicomTags.TextString].SetStringValue("Series UID of something not in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Series UID of self series");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Series UID of next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Series UID of 2nd next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Series UID of 4th next file series in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.StudyInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
                sq[DicomTags.TextString].SetStringValue("Study UID of something not in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.StudyInstanceUid].SetStringValue(n0File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Study UID of self study");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.StudyInstanceUid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Study UID of next file study in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.StudyInstanceUid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Study UID of 2nd next file study in data set");

                n0File.DataSet[DicomTags.ContentSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.StudyInstanceUid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.TextString].SetStringValue("Study UID of 4th next file study in data set");

                n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to self");
                sq[DicomTags.StudyInstanceUid].SetStringValue(n0File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n0File.DataSet[DicomTags.SopInstanceUid].ToString());

                n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to next");
                sq[DicomTags.StudyInstanceUid].SetStringValue(n1File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n1File.DataSet[DicomTags.SopInstanceUid].ToString());

                n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to 2nd next");
                sq[DicomTags.StudyInstanceUid].SetStringValue(n2File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n2File.DataSet[DicomTags.SopInstanceUid].ToString());

                n0File.DataSet[DicomTags.ReferencedStudySequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.TextString].SetStringValue("A more typical hierarchical sop reference to 4th next");
                sq[DicomTags.StudyInstanceUid].SetStringValue(n4File.DataSet[DicomTags.StudyInstanceUid].ToString());
                sq[DicomTags.ReferencedSeriesSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.SeriesInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SeriesInstanceUid].ToString());
                sq[DicomTags.ReferencedSopSequence].AddSequenceItem(sq = new DicomSequenceItem());
                sq[DicomTags.ReferencedSopInstanceUid].SetStringValue(n4File.DataSet[DicomTags.SopInstanceUid].ToString());
            }

            // copy the originals and anonymize them
            DicomFile[]     anonymized = new DicomFile[originals.Length];
            DicomAnonymizer anonymizer = new DicomAnonymizer();

            anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;
            for (int n = 0; n < anonymized.Length; n++)
            {
                anonymized[n] = new DicomFile(string.Empty, originals[n].MetaInfo.Copy(true, true, true), originals[n].DataSet.Copy(true, true, true));
                anonymizer.Anonymize(anonymized[n]);
            }

            // generate validation dump strings - unique uids are mapped to sequential numbers
            string originalDumpValidationString   = GenerateHierarchicalUidValidationDumpString(originals);
            string anonymizedDumpValidationString = GenerateHierarchicalUidValidationDumpString(anonymized);

            // if the hierarchical structure and pattern of uids is the same, then the relationships have been preserved.
            Assert.AreEqual(originalDumpValidationString, anonymizedDumpValidationString, "Relationships of anonymized data set differ compared to those of original data set.");
        }
		public void TestValidatePatientsNameAllowEmpty() {
			Initialize();

			_file.DataSet[DicomTags.PatientsName].SetStringValue("Patient^Anonymous^Mr");
			StudyData studyPrototype = CreateStudyPrototype();
			studyPrototype.PatientsNameRaw = "";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.ValidationOptions = ValidationOptions.AllowEmptyPatientName;
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
		}
Beispiel #20
0
        public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken)
        {
            //Things we ignore, Lookups, SupportingSql etc
            if (_extractCommand == null)
            {
                listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Ignoring non dataset command "));
                return(toProcess);
            }

            //if it isn't a dicom dataset don't process it
            if (!toProcess.Columns.Contains(RelativeArchiveColumnName))
            {
                listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Dataset " + _extractCommand.DatasetBundle.DataSet + " did not contain field '" + RelativeArchiveColumnName + "' so we will not attempt to extract images"));
                return(toProcess);
            }

            if (_putter == null)
            {
                _putter = (IPutDicomFilesInExtractionDirectories)  new ObjectConstructor().Construct(PutterType);
            }

            var projectNumber = _extractCommand.Configuration.Project.ProjectNumber.Value;

            var mappingServer        = new MappingRepository(UIDMappingServer);
            var destinationDirectory = new DirectoryInfo(Path.Combine(_extractCommand.GetExtractionDirectory().FullName, "Images"));

            var releaseCol = _extractCommand.QueryBuilder.SelectColumns.Select(c => c.IColumn).Single(c => c.IsExtractionIdentifier);

            // See: ftp://medical.nema.org/medical/dicom/2011/11_15pu.pdf

            var flags = DicomAnonymizer.SecurityProfileOptions.BasicProfile |
                        DicomAnonymizer.SecurityProfileOptions.CleanStructdCont |
                        DicomAnonymizer.SecurityProfileOptions.CleanDesc |
                        DicomAnonymizer.SecurityProfileOptions.RetainUIDs;

            if (RetainDates)
            {
                flags |= DicomAnonymizer.SecurityProfileOptions.RetainLongFullDates;
            }

            var profile = DicomAnonymizer.SecurityProfile.LoadProfile(null, flags);

            var anonymiser = new DicomAnonymizer(profile);

            using (var pool = new ZipPool())
            {
                _sw.Start();

                foreach (DataRow row in toProcess.Rows)
                {
                    if (_errors > 0 && _errors > ErrorThreshold)
                    {
                        throw new Exception($"Number of errors reported ({_errors}) reached the threshold ({ErrorThreshold})");
                    }

                    cancellationToken.ThrowIfAbortRequested();

                    var path = new AmbiguousFilePath(ArchiveRootIfAny, (string)row[RelativeArchiveColumnName]);

                    DicomFile dicomFile;

                    try
                    {
                        dicomFile = path.GetDataset(pool);
                    }
                    catch (Exception e)
                    {
                        listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, $"Failed to get image at path '{path.FullPath}'", e));
                        _errors++;
                        continue;
                    }

                    //get the new patient ID
                    var releaseId = row[releaseCol.GetRuntimeName()].ToString();

                    DicomDataset ds;

                    try
                    {
                        ds = anonymiser.Anonymize(dicomFile.Dataset);
                    }
                    catch (Exception e)
                    {
                        listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, $"Failed to anonymize image at path '{path.FullPath}'", e));
                        _errors++;
                        continue;
                    }

                    //now we want to explicitly use our own release Id regardless of what FoDicom said
                    ds.AddOrUpdate(DicomTag.PatientID, releaseId);

                    //rewrite the UIDs
                    foreach (var kvp in UIDMapping.SupportedTags)
                    {
                        if (!ds.Contains(kvp.Key))
                        {
                            continue;
                        }

                        var value = ds.GetValue <string>(kvp.Key, 0);

                        //if it has a value for this UID
                        if (value == null)
                        {
                            continue;
                        }
                        var releaseValue = mappingServer.GetOrAllocateMapping(value, projectNumber, kvp.Value);

                        //change value in dataset
                        ds.AddOrUpdate(kvp.Key, releaseValue);

                        //and change value in DataTable
                        if (toProcess.Columns.Contains(kvp.Key.DictionaryEntry.Keyword))
                        {
                            row[kvp.Key.DictionaryEntry.Keyword] = releaseValue;
                        }
                    }

                    var newPath = _putter.WriteOutDataset(destinationDirectory, releaseId, ds);
                    row[RelativeArchiveColumnName] = newPath;

                    _anonymisedImagesCount++;

                    listener.OnProgress(this, new ProgressEventArgs("Writing ANO images", new ProgressMeasurement(_anonymisedImagesCount, ProgressType.Records), _sw.Elapsed));
                }

                _sw.Stop();
            }

            return(toProcess);
        }
		public void TestValidateAccessionNotEqual()
		{
			Initialize();

			_file.DataSet[DicomTags.AccessionNumber].SetStringValue("1234");
			StudyData studyPrototype = CreateStudyPrototype();
			studyPrototype.AccessionNumber = "1234";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
		}
Beispiel #22
0
        private void Anonymize(IBackgroundTaskContext context)
        {
            //TODO (Marmot) This probably should be its own WorkItem type and have it done in the background there.
            var study = (StudyTableItem)context.UserState;
            var anonymizedInstances = new AuditedInstances();

            try
            {
                context.ReportProgress(new BackgroundTaskProgress(0, SR.MessageAnonymizingStudy));

                var loader       = study.Server.GetService <IStudyLoader>();
                int numberOfSops = loader.Start(new StudyLoaderArgs(study.StudyInstanceUid, null));
                if (numberOfSops <= 0)
                {
                    return;
                }

                var anonymizer = new DicomAnonymizer {
                    StudyDataPrototype = _component.AnonymizedData
                };

                if (_component.PreserveSeriesData)
                {
                    //The default anonymizer removes the series data, so we just clone the original.
                    anonymizer.AnonymizeSeriesDataDelegate = original => original.Clone();
                }

                // Setup the ImportFilesUtility to perform the import
                var configuration = DicomServer.GetConfiguration();

                // setup auditing information
                var result = EventResult.Success;

                string patientsSex = null;

                for (int i = 0; i < numberOfSops; ++i)
                {
                    using (var sop = loader.LoadNextSop())
                    {
                        if (sop != null &&
                            (_component.KeepReportsAndAttachments || !IsReportOrAttachmentSopClass(sop.SopClassUid)))
                        {
                            //preserve the patient sex.
                            if (patientsSex == null)
                            {
                                anonymizer.StudyDataPrototype.PatientsSex = patientsSex = sop.PatientsSex ?? "";
                            }

                            var localSopDataSource = sop.DataSource as ILocalSopDataSource;
                            if (localSopDataSource != null)
                            {
                                string    filename = string.Format("{0}.dcm", i);
                                DicomFile file     = (localSopDataSource).File;

                                // make sure we anonymize a new instance, not the same instance that the Sop cache holds!!
                                file = new DicomFile(filename, file.MetaInfo.Copy(), file.DataSet.Copy());
                                anonymizer.Anonymize(file);

                                // TODO (CR Jun 2012): Importing each file separately?
                                Platform.GetService((IPublishFiles w) => w.PublishLocal(new List <DicomFile> {
                                    file
                                }));

                                string studyInstanceUid = file.DataSet[DicomTags.StudyInstanceUid].ToString();
                                string patientId        = file.DataSet[DicomTags.PatientId].ToString();
                                string patientsName     = file.DataSet[DicomTags.PatientsName].ToString();
                                anonymizedInstances.AddInstance(patientId, patientsName, studyInstanceUid);

                                var progressPercent = (int)Math.Floor((i + 1) / (float)numberOfSops * 100);
                                var progressMessage = String.Format(SR.MessageAnonymizingStudy, file.MediaStorageSopInstanceUid);
                                context.ReportProgress(new BackgroundTaskProgress(progressPercent, progressMessage));
                            }
                        }
                    }
                }

                AuditHelper.LogCreateInstances(new[] { configuration.AETitle }, anonymizedInstances, EventSource.CurrentUser, result);

                context.Complete();
            }
            catch (Exception e)
            {
                AuditHelper.LogCreateInstances(new[] { string.Empty }, anonymizedInstances, EventSource.CurrentUser, EventResult.MajorFailure);
                context.Error(e);
            }
        }
		public void TestValidatePatientsBirthDateAllowEqual() {
			Initialize();

			_file.DataSet[DicomTags.PatientsBirthDate].SetStringValue("19760810");
			StudyData studyPrototype = CreateStudyPrototype();
			studyPrototype.PatientsBirthDateRaw = "19760810";

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.ValidationOptions = ValidationOptions.AllowEqualBirthDate;
			anonymizer.StudyDataPrototype = studyPrototype;
			anonymizer.Anonymize(_file);
		}