Beispiel #1
0
        protected override int OnStart(StudyLoaderArgs studyLoaderArgs)
        {
            _sops = null;

            EventResult result = EventResult.Success;
            var loadedInstances = new AuditedInstances();
            try
            {
                using (var context = new DataAccessContext())
                {
                    IStudy study = context.GetStudyBroker().GetStudy(studyLoaderArgs.StudyInstanceUid);
                    if (study == null)
                    {
                        result = EventResult.MajorFailure;
                        loadedInstances.AddInstance(studyLoaderArgs.StudyInstanceUid);
                        throw new NotFoundLoadStudyException(studyLoaderArgs.StudyInstanceUid);
                    }
                    loadedInstances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                    _sops = study.GetSopInstances().GetEnumerator();
                    return study.NumberOfStudyRelatedInstances;
                }
            }
            finally
            {
                AuditHelper.LogOpenStudies(new[] { AuditHelper.LocalAETitle }, loadedInstances, EventSource.CurrentUser, result);
            }
        }
Beispiel #2
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 #3
0
        protected override int OnStart(StudyLoaderArgs studyLoaderArgs)
        {
            var ae = studyLoaderArgs.Server as IDicomServiceNode;
            _ae = ae;

            EventResult result = EventResult.Success;
            AuditedInstances loadedInstances = new AuditedInstances();
            try
            {
                ServerPartition partition = ServerPartitionMonitor.Instance.GetPartition(_ae.AETitle);
                if (!partition.Enabled)
                    throw new OfflineLoadStudyException(studyLoaderArgs.StudyInstanceUid);    

                FilesystemMonitor.Instance.GetReadableStudyStorageLocation(partition.Key,
                                                                           studyLoaderArgs.StudyInstanceUid,
                                                                           StudyRestore.False,
                                                                           StudyCache.True,
                                                                           out _location);

                StudyXml studyXml = _location.LoadStudyXml();

                _instances = GetInstances(studyXml).GetEnumerator();

                loadedInstances.AddInstance(studyXml.PatientId, studyXml.PatientsName, studyXml.StudyInstanceUid);

                return studyXml.NumberOfStudyRelatedInstances;

            }
            catch (StudyIsNearlineException e)
            {
                throw new NearlineLoadStudyException(studyLoaderArgs.StudyInstanceUid, e);
            }
            finally
            {
                AuditHelper.LogOpenStudies(new[] {ae.AETitle}, loadedInstances, EventSource.CurrentUser, result);
            }
        }
Beispiel #4
0
        public void RetrieveStudy(IDicomServiceNode remoteAEInfo, IStudyRootData study)
        {
            EventResult result = EventResult.Success;
            try
            {
                var request = new DicomRetrieveStudyRequest
                {
                    ServerName = remoteAEInfo.Name,
                    Study = new WorkItemStudy(study),
                    Patient = new WorkItemPatient(study)

                };

                // TODO (CR Jul 2012): The service itself has logic like this already, so this should probably be there, too.
                // Then, we could also get rid of this GetMatching... method.
                var data = GetMatchingActiveWorkItem(request);
                if (data != null)
                {
                    var existingRequest = data.Request as DicomRetrieveStudyRequest;
                    if (existingRequest != null && remoteAEInfo.Name == existingRequest.ServerName)
                    {
                        Request = data.Request;
                        return;
                    }
                }

                InsertRequest(request, new DicomRetrieveProgress());
            }
            catch (Exception ex)
            {
                result = EventResult.MajorFailure;
                Exception = ex;
                Platform.Log(LogLevel.Error, ex, Common.SR.MessageFailedToSendStudy);
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogBeginReceiveInstances(remoteAEInfo.AETitle, remoteAEInfo.ScpParameters.HostName,
                                                     instances, string.IsNullOrEmpty(Request.UserName)
                                                                    ? EventSource.CurrentProcess
                                                                    : EventSource.CurrentUser, result);
            }
        }
Beispiel #5
0
        public void PublishFiles(IDicomServiceNode remoteAEInfo, IStudyRootData study, DeletionBehaviour behaviour, List<string> files)
        {
            EventResult result = EventResult.Success;
            try
            {
                var request = new PublishFilesRequest
                                  {
                                      DestinationServerName = remoteAEInfo.Name,
                                      Priority = WorkItemPriorityEnum.High,
                                      DeletionBehaviour = behaviour,
                                      Study = new WorkItemStudy(study),
                                      Patient = new WorkItemPatient(study),
                                      FilePaths = files
                                  };
                InsertRequest(request, new DicomSendProgress());
            }
            catch (Exception ex)
            {
                result = EventResult.MajorFailure;
                Exception = ex;
                Platform.Log(LogLevel.Error, ex, Common.SR.MessageFailedToSendSops);
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogBeginSendInstances(remoteAEInfo.AETitle, remoteAEInfo.ScpParameters.HostName,
                                                  instances,
                                                  string.IsNullOrEmpty(Request.UserName)
                                                      ? EventSource.CurrentProcess
                                                      : EventSource.CurrentUser, result);
            }
        }
Beispiel #6
0
        public void SendSops(IDicomServiceNode remoteAEInfo, IStudyRootData study, string seriesInstanceUid, string[] sopInstanceUids, WorkItemPriorityEnum priority)
        {
            EventResult result = EventResult.Success;
            try
            {
                var request = new DicomSendSopRequest
                                  {
                                      DestinationServerName = remoteAEInfo.Name,
                                      SeriesInstanceUid = seriesInstanceUid,
                                      SopInstanceUids = new List<string>(),
                                      Priority = priority,
                                      Study = new WorkItemStudy(study),
                                      Patient = new WorkItemPatient(study)
                                  };
                request.SopInstanceUids.AddRange(sopInstanceUids);
                InsertRequest(request, new DicomSendProgress());
            }
            catch (Exception ex)
            {
                result = EventResult.MajorFailure;
                Exception = ex;
                Platform.Log(LogLevel.Error, ex, Common.SR.MessageFailedToSendSops);
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogBeginSendInstances(remoteAEInfo.AETitle, remoteAEInfo.ScpParameters.HostName,
                                                  instances,
                                                  string.IsNullOrEmpty(Request.UserName)
                                                      ? EventSource.CurrentProcess
                                                      : EventSource.CurrentUser, result);
            }
        }
Beispiel #7
0
        public void DeleteSeries(IStudyRootData study, List<string> seriesInstanceUids)
        {
            EventResult result = EventResult.Success;
            try
            {
                var request = new DeleteSeriesRequest
                {
                    Study = new WorkItemStudy(study),
                    Patient = new WorkItemPatient(study),
                    SeriesInstanceUids = seriesInstanceUids
                };

                InsertRequest(request, new DeleteProgress());
            }
            catch (Exception ex)
            {
                result = EventResult.MajorFailure;
                Exception = ex;
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogDeleteSeries(new List<string> {AuditHelper.LocalAETitle}, instances, EventSource.CurrentUser, result);
            }
        }
Beispiel #8
0
 /// <summary>
 /// Generates a "Dicom Instances Accessed" update event in the audit log (with ActionCode of Delete), according to DICOM Supplement 95.
 /// </summary>
 /// <remarks>
 /// This method automatically separates different patients into separately logged events, as required by DICOM.
 ///
 /// We chose to impleemnt the DicomInstancesAccessed audit log, as opposed to the DicomStudyDeleted audit message because the whole
 /// study isn't being deleted, just a series.
 /// </remarks>
 /// <param name="aeTitles">The application entities from which the instances were accessed.</param>
 /// <param name="instances">The studies that the series belong that are being deleted.</param>
 /// <param name="eventSource">The source user or application entity which invoked the operation.</param>
 /// <param name="eventResult">The result of the operation.</param>
 public static void LogDeleteSeries(IEnumerable <string> aeTitles, AuditedInstances instances, EventSource eventSource, EventResult eventResult)
 {
     AuditLogHelper.LogDeleteSeries(aeTitles, instances, eventSource, eventResult);
 }
		protected void LoadImportContext(ServerAssociationParameters association)
		{
			_importContext = new DicomReceiveImportContext(association.CallingAE, GetRemoteHostName(association), StudyStore.GetConfiguration(), EventSource.CurrentProcess);

			// Publish new WorkItems as they're added to the context
			lock (_importContext.StudyWorkItemsSyncLock)
			{
				_importContext.StudyWorkItems.ItemAdded += delegate(object sender, DictionaryEventArgs<string, WorkItem> args)
					{
						Platform.GetService(
							(IWorkItemActivityMonitorService service) =>
							service.Publish(new WorkItemPublishRequest
								{
									Item = WorkItemDataHelper.FromWorkItem(args.Item)
								}));


						var auditedInstances = new AuditedInstances();
						var request = args.Item.Request as DicomReceiveRequest;
						if (request != null)
						{
							auditedInstances.AddInstance(request.Patient.PatientId, request.Patient.PatientsName,
							                             request.Study.StudyInstanceUid);
						}

						AuditHelper.LogReceivedInstances(
							association.CallingAE, GetRemoteHostName(association),
							auditedInstances, EventSource.CurrentProcess,
							EventResult.Success, EventReceiptAction.ActionUnknown);
					};

				_importContext.StudyWorkItems.ItemChanged += (sender, args) => Platform.GetService(
					(IWorkItemActivityMonitorService service) =>
					service.Publish(new WorkItemPublishRequest { Item = WorkItemDataHelper.FromWorkItem(args.Item) }));
			}
		}
		protected void LoadImportContext(ServerAssociationParameters association)
		{
			_importContext = new DicomReceiveImportContext(association.CallingAE, GetRemoteHostName(association), StudyStore.GetConfiguration(), EventSource.CurrentProcess);

			// Publish new WorkItems as they're added to the context
			lock (_importContext.StudyWorkItemsSyncLock)
			{
				_importContext.StudyWorkItems.ItemAdded += (sender, args) =>
				                                           {
					                                           _importContext.PublishWorkItemActivity(WorkItemDataHelper.FromWorkItem(args.Item));

					                                           var auditedInstances = new AuditedInstances();
					                                           var request = args.Item.Request as DicomReceiveRequest;
					                                           if (request != null)
						                                           auditedInstances.AddInstance(request.Patient.PatientId, request.Patient.PatientsName, request.Study.StudyInstanceUid);

					                                           AuditHelper.LogReceivedInstances(
						                                           association.CallingAE, GetRemoteHostName(association),
						                                           auditedInstances, EventSource.CurrentProcess,
						                                           EventResult.Success, EventReceiptAction.ActionUnknown);
				                                           };

				_importContext.StudyWorkItems.ItemChanged += (sender, args) =>
					_importContext.PublishWorkItemActivity(WorkItemDataHelper.FromWorkItem(args.Item));
			}
		}
Beispiel #11
0
 /// <summary>
 /// Generates a "DICOM Instances Transferred" received event in the audit log, according to DICOM Supplement 95.
 /// </summary>
 /// <remarks>
 /// This method automatically separates different patients into separately logged events, as required by DICOM.
 /// </remarks>
 /// <param name="remoteAETitle">The application entity from which the transfer was completed.</param>
 /// <param name="remoteHostName">The hostname of the application entity from which the transfer was completed.</param>
 /// <param name="instances">The studies that were transferred.</param>
 /// <param name="eventSource">The source user or application entity which invoked the operation.</param>
 /// <param name="eventResult">The result of the operation.</param>
 /// <param name="action">The action taken on the studies that were transferred.</param>
 public static void LogReceivedInstances(string remoteAETitle, string remoteHostName, AuditedInstances instances, EventSource eventSource, EventResult eventResult, EventReceiptAction action)
 {
     AuditLogHelper.LogReceivedInstances(LocalAETitle, remoteAETitle, remoteHostName, instances, eventSource, eventResult, action);
 }
Beispiel #12
0
 /// <summary>
 /// Generates a "Begin Transferring DICOM Instances" receive event in the audit log, according to DICOM Supplement 95.
 /// </summary>
 /// <remarks>
 /// This method automatically separates different patients into separately logged events, as required by DICOM.
 /// </remarks>
 /// <param name="remoteAETitle">The application entity from which the transfer was started.</param>
 /// <param name="remoteHostName">The hostname of the application entity from which the transfer was started.</param>
 /// <param name="instances">The studies that were requested for transfer.</param>
 /// <param name="eventSource">The source user or application entity which invoked the operation.</param>
 /// <param name="eventResult">The result of the operation.</param>
 public static void LogBeginReceiveInstances(string remoteAETitle, string remoteHostName, AuditedInstances instances, EventSource eventSource, EventResult eventResult)
 {
     AuditLogHelper.LogBeginReceiveInstances(LocalAETitle, remoteAETitle, remoteHostName, instances, eventSource, eventResult);
 }
Beispiel #13
0
        protected override int OnStart(StudyLoaderArgs studyLoaderArgs)
        {
            var serverAe = studyLoaderArgs.Server;
            Platform.CheckForNullReference(serverAe, "Server");
            Platform.CheckMemberIsSet(serverAe.StreamingParameters, "StreamingParameters");
            _serverAe = serverAe;

            EventResult result = EventResult.Success;
            AuditedInstances loadedInstances = new AuditedInstances();
            try
            {

                StudyXml studyXml = RetrieveStudyXml(studyLoaderArgs);
                _instances = GetInstances(studyXml).GetEnumerator();

                loadedInstances.AddInstance(studyXml.PatientId, studyXml.PatientsName, studyXml.StudyInstanceUid);

                return studyXml.NumberOfStudyRelatedInstances;

            }
            finally
            {
                AuditHelper.LogOpenStudies(new string[] { _serverAe.AETitle }, loadedInstances, EventSource.CurrentUser, result);
            }
        }
Beispiel #14
0
 private void AuditSendOperation(bool noExceptions)
 {
     if (noExceptions)
     {
         var sentInstances = new AuditedInstances();
         var failedInstances = new AuditedInstances();
         foreach (StorageInstance instance in StorageInstanceList)
         {
             if (instance.SendStatus.Status == DicomState.Success)
                 sentInstances.AddInstance(instance.PatientId, instance.PatientsName, instance.StudyInstanceUid);
             else
                 failedInstances.AddInstance(instance.PatientId, instance.PatientsName, instance.StudyInstanceUid);
         }
         AuditHelper.LogSentInstances(RemoteAE, RemoteHost, sentInstances, EventSource.CurrentProcess,
                                      EventResult.Success);
         AuditHelper.LogSentInstances(RemoteAE, RemoteHost, failedInstances, EventSource.CurrentProcess,
                                      EventResult.MinorFailure);
     }
     else
     {
         var sentInstances = new AuditedInstances();
         foreach (StorageInstance instance in StorageInstanceList)
             sentInstances.AddInstance(instance.PatientId, instance.PatientsName, instance.StudyInstanceUid);
         AuditHelper.LogSentInstances(RemoteAE, RemoteHost, sentInstances, EventSource.CurrentProcess,
                                      EventResult.MajorFailure);
     }
 }
Beispiel #15
0
		public override bool OnReceiveRequest(ClearCanvas.Dicom.Network.DicomServer server, 
			ServerAssociationParameters association, byte presentationID, DicomMessage message)
		{
			string studyInstanceUid;
			string seriesInstanceUid;
			DicomUid sopInstanceUid;

			bool ok = message.DataSet[DicomTags.SopInstanceUid].TryGetUid(0, out sopInstanceUid);
			if (ok) ok = message.DataSet[DicomTags.SeriesInstanceUid].TryGetString(0, out seriesInstanceUid);
			if (ok) ok = message.DataSet[DicomTags.StudyInstanceUid].TryGetString(0, out studyInstanceUid);

			if (!ok)
			{
				Platform.Log(LogLevel.Error, "Unable to retrieve UIDs from request message, sending failure status.");

				server.SendCStoreResponse(presentationID, message.MessageId, sopInstanceUid.UID,
					DicomStatuses.ProcessingFailure);

				return true;
			}

            if (_importContext == null)
            {
                _importContext = new DicomReceiveImportContext(association.CallingAE, GetRemoteHostName(association), StudyStore.GetConfiguration(), EventSource.CurrentProcess);

                // Publish new WorkItems as they're added to the context
                lock (_importContext.StudyWorkItemsSyncLock)
                {
                    _importContext.StudyWorkItems.ItemAdded += delegate(object sender, DictionaryEventArgs<string,WorkItem> args)
                                                                   {
                                                                       Platform.GetService(
                                                                           (IWorkItemActivityMonitorService service) =>
                                                                           service.Publish(new WorkItemPublishRequest
                                                                                               {
                                                                                                   Item =
                                                                                                       WorkItemDataHelper
                                                                                                       .FromWorkItem(
                                                                                                           args.Item)
                                                                                               }));


                                                                       var auditedInstances = new AuditedInstances();
                                                                       var request =
                                                                           args.Item.Request as DicomReceiveRequest;
                                                                       if (request != null)
                                                                       {
                                                                           auditedInstances.AddInstance(request.Patient.PatientId, request.Patient.PatientsName,
                                                                                                        request.Study.StudyInstanceUid);
                                                                       }

                                                                       AuditHelper.LogReceivedInstances(
                                                                           association.CallingAE, GetRemoteHostName(association),
                                                                           auditedInstances, EventSource.CurrentProcess,
                                                                           EventResult.Success, EventReceiptAction.ActionUnknown);
                                                                   }
                ;

                    _importContext.StudyWorkItems.ItemChanged += (sender, args) => Platform.GetService(
                        (IWorkItemActivityMonitorService service) =>
                        service.Publish(new WorkItemPublishRequest {Item = WorkItemDataHelper.FromWorkItem(args.Item)}));
                }
            }

		    var importer = new ImportFilesUtility(_importContext);

		    var result = importer.Import(message,BadFileBehaviourEnum.Ignore, FileImportBehaviourEnum.Save);
            if (result.Successful)
            {
                if (!String.IsNullOrEmpty(result.AccessionNumber))
                    Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (A#:{3} StudyUid:{4})",
                                 result.SopInstanceUid, association.CallingAE, association.CalledAE, result.AccessionNumber,
                                 result.StudyInstanceUid);
                else
                    Platform.Log(LogLevel.Info, "Received SOP Instance {0} from {1} to {2} (StudyUid:{3})",
                                 result.SopInstanceUid, association.CallingAE, association.CalledAE,
                                 result.StudyInstanceUid);
                server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid, result.DicomStatus);
            }
            else
            {
                if (result.DicomStatus==DicomStatuses.ProcessingFailure)
                    Platform.Log(LogLevel.Error, "Failure importing sop: {0}", result.ErrorMessage);

                //OnReceiveError(message, result.ErrorMessage, association.CallingAE);
                server.SendCStoreResponse(presentationID, message.MessageId, message.AffectedSopInstanceUid,
                                          result.DicomStatus, result.ErrorMessage);
            }		    
               
			return true;
		}
Beispiel #16
0
        public void RetrieveSeries(IDicomServiceNode remoteAEInfo, IStudyRootData study, string[] seriesInstanceUids)
        {
            EventResult result = EventResult.Success;
            try
            {
                var request = new DicomRetrieveSeriesRequest
                {
                    ServerName = remoteAEInfo.Name,
                    SeriesInstanceUids = new List<string>(),
                    Study = new WorkItemStudy(study),
                    Patient = new WorkItemPatient(study)
                };

                request.SeriesInstanceUids.AddRange(seriesInstanceUids);
                InsertRequest(request, new DicomRetrieveProgress());
            }
            catch (Exception ex)
            {
                result = EventResult.MajorFailure;
                Exception = ex;
                throw;
            }
            finally
            {
                var instances = new AuditedInstances();
                instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                AuditHelper.LogBeginReceiveInstances(remoteAEInfo.AETitle, remoteAEInfo.ScpParameters.HostName,
                                       instances, string.IsNullOrEmpty(Request.UserName)
                                                      ? EventSource.CurrentProcess
                                                      : EventSource.CurrentUser, result);
            }
        }
Beispiel #17
0
 /// <summary>
 /// Generates a "Data Export" event in the audit log, according to DICOM Supplement 95.
 /// </summary>
 /// <remarks>
 /// One audit event is generated for each file system volume to which data is exported.
 /// If the audited instances are not on a file system, a single event is generated with an empty media identifier.
 /// </remarks>
 /// <param name="instances">The files that were exported.</param>
 /// <param name="eventSource">The source user or application entity which invoked the operation.</param>
 /// <param name="eventResult">The result of the operation.</param>
 public static void LogExportStudies(AuditedInstances instances, EventSource eventSource, EventResult eventResult)
 {
     AuditLogHelper.LogExportStudies(instances, eventSource, EventSource.GetCurrentDicomAE(), eventResult);
 }
Beispiel #18
0
 /// <summary>
 /// Generates a "Dicom Study Deleted" event in the audit log, according to DICOM Supplement 95.
 /// </summary>
 /// <remarks>
 /// This method automatically separates different patients into separately logged events, as required by DICOM.
 /// </remarks>
 /// <param name="aeTitle">The application entity from which the instances were deleted.</param>
 /// <param name="instances">The studies that were deleted.</param>
 /// <param name="eventSource">The source user or application entity which invoked the operation.</param>
 /// <param name="eventResult">The result of the operation.</param>
 public static void LogDeleteStudies(string aeTitle, AuditedInstances instances, EventSource eventSource, EventResult eventResult)
 {
     AuditLogHelper.LogDeleteStudies(aeTitle, instances, eventSource, eventResult);
 }
        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);
            }
        }
        protected override int OnStart(StudyLoaderArgs studyLoaderArgs)
        {
            _sops = null;

            EventResult result = EventResult.Success;
            var loadedInstances = new AuditedInstances();
            try
            {
                using (var context = new DataAccessContext())
                {
                    if (!studyLoaderArgs.Options.IgnoreInUse)
                    {
                        var activeUpdateItems =
                            context.GetWorkItemBroker().GetWorkItems(WorkItemConcurrency.StudyUpdate,
                                                                     WorkItemStatusFilter.Active,
                                                                     studyLoaderArgs.StudyInstanceUid);

                        var activeDeleteItems =
                            context.GetWorkItemBroker().GetWorkItems(WorkItemConcurrency.StudyDelete,
                                                                     WorkItemStatusFilter.Active,
                                                                     studyLoaderArgs.StudyInstanceUid);

                        if (activeUpdateItems.Any() || activeDeleteItems.Any())
                        {
                            var message = string.Format("There are work items actively modifying the study with UID '{0}'.", studyLoaderArgs.StudyInstanceUid);
                            throw new InUseLoadStudyException(studyLoaderArgs.StudyInstanceUid, message);
                        }
                    }

                    IStudy study = context.GetStudyBroker().GetStudy(studyLoaderArgs.StudyInstanceUid);
                    if (study == null)
                    {
                        result = EventResult.MajorFailure;
                        loadedInstances.AddInstance(studyLoaderArgs.StudyInstanceUid);
                        throw new NotFoundLoadStudyException(studyLoaderArgs.StudyInstanceUid);
                    }
                    loadedInstances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid);

                    _sops = study.GetSopInstances().GetEnumerator();
                    return study.NumberOfStudyRelatedInstances;
                }
            }
            finally
            {
                AuditHelper.LogOpenStudies(new[] { AuditHelper.LocalAETitle }, loadedInstances, EventSource.CurrentUser, result);
            }
        }