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 AnonymizeStudyOutput AnonymizeStudy(AnonymizeStudyInput input)
		{
			// load study to anonymize
			IDataStoreReader reader = DataAccessLayer.GetIDataStoreReader();
			IStudy study = reader.GetStudy(input.StudyInstanceUID);
			List<ISopInstance> sops = new List<ISopInstance>(study.GetSopInstances());

			// ensure there is a valid output location
			if(string.IsNullOrEmpty(input.OutputDirectory))
			{
				// create temp dir
			}

			string fullPath = Path.GetFullPath(input.OutputDirectory);
			if (!Directory.Exists(fullPath))
			{
				Directory.CreateDirectory(fullPath);
			}

			// set up anonymization data
			StudyData studyData = new StudyData();
			studyData.PatientId = input.PatientId;
			studyData.PatientsNameRaw = input.PatientsName;
			studyData.PatientsBirthDate = input.PatientsBirthDate;
			studyData.PatientsSex = input.PatientsSex;
			studyData.AccessionNumber = input.AccessionNumber;
			studyData.StudyDescription = input.StudyDescription;
			studyData.StudyDate = input.StudyDate;

			DicomAnonymizer anonymizer = new DicomAnonymizer();
			anonymizer.StudyDataPrototype = studyData;

			//The default anonymizer removes the series data, so we just clone the original.
			anonymizer.AnonymizeSeriesDataDelegate =
				delegate(SeriesData original) { return original.Clone(); };

			// anonymize each image in the study
			for (int i = 0; i < sops.Count; ++i)
			{
				ISopInstance sop = sops[i];
				DicomFile file = new DicomFile(sop.GetLocationUri().LocalDiskPath);

				anonymizer.Anonymize(file);

				file.Save(string.Format("{0}\\{1}.dcm", fullPath, i));
			}

			return new AnonymizeStudyOutput(sops.Count);
		}
Beispiel #3
0
		private bool Initialize()
		{
			_synchronizationContext = SynchronizationContext.Current;

			_exportedInstances = new AuditedInstances();
			_canceled = false;
			_overwrite = false;

			if (Anonymize)
			{
				ExportComponent component = new ExportComponent();
				component.OutputPath = OutputPath;

				if (DialogBoxAction.Ok != DesktopWindow.ShowDialogBox(component, SR.Export))
					return false;

				OutputPath = component.OutputPath;

				StudyData studyData = new StudyData
				{
					PatientId = component.PatientId,
					PatientsNameRaw = component.PatientsName,
					PatientsBirthDate = component.PatientsDateOfBirth,
					StudyId = component.StudyId,
					StudyDescription = component.StudyDescription,
					AccessionNumber = component.AccessionNumber,
					StudyDate = component.StudyDate
				};

				_anonymizer = new DicomAnonymizer();
				_anonymizer.ValidationOptions = ValidationOptions.RelaxAllChecks;
				_anonymizer.StudyDataPrototype = studyData;
			}
			else
			{
				SelectFolderDialogCreationArgs args = new SelectFolderDialogCreationArgs();
				args.Prompt = SR.MessageSelectOutputLocation;
				args.Path = OutputPath;

				FileDialogResult result = DesktopWindow.ShowSelectFolderDialogBox(args);
				if (result.Action != DialogBoxAction.Ok)
					return false;

				OutputPath = result.FileName;
			}

			return true;
		}
Beispiel #4
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;
		}