Beispiel #1
0
        /// <summary>
        /// Create Duplicate SIQ Entry
        /// </summary>
        /// <param name="file"></param>
        /// <param name="location"></param>
        /// <param name="sourcePath"></param>
        /// <param name="queue"></param>
        /// <param name="uid"></param>
        /// <param name="data"></param>
        public static void CreateDuplicateSIQEntry(DicomFile file, StudyStorageLocation location, string sourcePath,
                                                   WorkQueue queue, WorkQueueUid uid, StudyProcessWorkQueueData data)
        {
            Platform.Log(LogLevel.Info, "Creating Work Queue Entry for duplicate...");
            String uidGroup = queue.GroupID ?? queue.GetKey().Key.ToString();

            using (var commandProcessor = new ServerCommandProcessor("Insert Work Queue entry for duplicate"))
            {
                commandProcessor.AddCommand(new FileDeleteCommand(sourcePath, true));

                var sopProcessingContext     = new SopInstanceProcessorContext(commandProcessor, location, uidGroup);
                DicomProcessingResult result = Process(sopProcessingContext, file, data);
                if (!result.Successful)
                {
                    FailUid(uid, true);
                    return;
                }

                commandProcessor.AddCommand(new DeleteWorkQueueUidCommand(uid));

                if (!commandProcessor.Execute())
                {
                    Platform.Log(LogLevel.Error, "Unexpected error when creating duplicate study integrity queue entry: {0}",
                                 commandProcessor.FailureReason);
                    FailUid(uid, true);
                }
            }
        }
		/// <summary>
		/// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
		/// </summary>
		/// <param name="context">The processing context</param>
		/// <param name="file">The file</param>
		/// <param name="data">The data</param>
		/// <param name="duplicate">How the processor should handle the duplicate</param>
		public static void ProcessStoredDuplicate(SopInstanceProcessorContext context,
		                                          DicomFile file,
		                                          StudyProcessWorkQueueData data,
		                                          DuplicateProcessingEnum duplicate)
		{
			SaveDuplicate(context, file);
			var uidData = new WorkQueueUidData
				{
					Extension = ServerPlatform.DuplicateFileExtension,
					GroupId = context.Group,
					DuplicateProcessing = duplicate
				};

			if (context.Request != null)
				uidData.OperationToken = context.Request.OperationToken;

			context.CommandProcessor.AddCommand(
				new UpdateWorkQueueCommand(file, context.StudyLocation, true, data, uidData, context.Request));
		}
		/// <summary>
		/// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
		/// </summary>
		/// <param name="context">The processing context</param>
		/// <param name="message">A subset of the message stored in <paramref name="sourceFilename"/></param>
		/// <param name="sourceFilename">The location of the filename that is a duplicate</param>
		/// <param name="data">The data</param>
		/// <param name="duplicate">How the processor should handle the duplicate</param>
		public static void ProcessStoredDuplicateFile(SopInstanceProcessorContext context,
													  string sourceFilename,
													  DicomMessageBase message,
													  StudyProcessWorkQueueData data,
													  DuplicateProcessingEnum duplicate)
		{
			SaveDuplicateFile(context, message.DataSet[DicomTags.SopInstanceUid].ToString(), sourceFilename);
			var uidData = new WorkQueueUidData
			{
				Extension = ServerPlatform.DuplicateFileExtension,
				GroupId = context.Group,
				DuplicateProcessing = duplicate
			};

			if (context.Request != null)
				uidData.OperationToken = context.Request.OperationToken;

			context.CommandProcessor.AddCommand(
				new UpdateWorkQueueCommand(message, context.StudyLocation, true, data, uidData, context.Request));
		}
Beispiel #4
0
        /// <summary>
        /// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
        /// </summary>
        /// <param name="context">The processing context</param>
        /// <param name="file">The file</param>
        /// <param name="data">The data</param>
        /// <param name="duplicate">How the processor should handle the duplicate</param>
        public static void ProcessStoredDuplicate(SopInstanceProcessorContext context,
                                                  DicomFile file,
                                                  StudyProcessWorkQueueData data,
                                                  DuplicateProcessingEnum duplicate)
        {
            SaveDuplicate(context, file);
            var uidData = new WorkQueueUidData
            {
                Extension           = ServerPlatform.DuplicateFileExtension,
                GroupId             = context.Group,
                DuplicateProcessing = duplicate
            };

            if (context.Request != null)
            {
                uidData.OperationToken = context.Request.OperationToken;
            }

            context.CommandProcessor.AddCommand(
                new UpdateWorkQueueCommand(file, context.StudyLocation, true, data, uidData, context.Request));
        }
Beispiel #5
0
        /// <summary>
        /// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
        /// </summary>
        /// <param name="context">The processing context</param>
        /// <param name="message">A subset of the message stored in <paramref name="sourceFilename"/></param>
        /// <param name="sourceFilename">The location of the filename that is a duplicate</param>
        /// <param name="data">The data</param>
        /// <param name="duplicate">How the processor should handle the duplicate</param>
        public static void ProcessStoredDuplicateFile(SopInstanceProcessorContext context,
                                                      string sourceFilename,
                                                      DicomMessageBase message,
                                                      StudyProcessWorkQueueData data,
                                                      DuplicateProcessingEnum duplicate)
        {
            SaveDuplicateFile(context, message.DataSet[DicomTags.SopInstanceUid].ToString(), sourceFilename);
            var uidData = new WorkQueueUidData
            {
                Extension           = ServerPlatform.DuplicateFileExtension,
                GroupId             = context.Group,
                DuplicateProcessing = duplicate
            };

            if (context.Request != null)
            {
                uidData.OperationToken = context.Request.OperationToken;
            }

            context.CommandProcessor.AddCommand(
                new UpdateWorkQueueCommand(message, context.StudyLocation, true, data, uidData, context.Request));
        }
Beispiel #6
0
        private static void SaveDuplicateFile(SopInstanceProcessorContext context, string sopInstanceUid, string sourceFilename)
        {
            String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);

            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.Group /* the AE title + timestamp */);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path  = Path.Combine(path, sopInstanceUid);
            path += "." + ServerPlatform.DuplicateFileExtension;

            context.CommandProcessor.AddCommand(new RenameFileCommand(sourceFilename, path, true));

            Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
        }
Beispiel #7
0
        private static void SaveDuplicate(SopInstanceProcessorContext context, DicomFile file)
        {
            String sopUid = file.DataSet[DicomTags.SopInstanceUid].ToString();

            String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);

            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.Group /* the AE title + timestamp */);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path  = Path.Combine(path, sopUid);
            path += "." + ServerPlatform.DuplicateFileExtension;

            context.CommandProcessor.AddCommand(new SaveDicomFileCommand(path, file, true));

            Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
        }
		/// <summary>
		/// Schedules a reconciliation for the specified <see cref="DicomFile"/>
		/// </summary>
		/// <param name="context"></param>
		/// <param name="file"></param>
		/// <param name="uid"></param>
		private static void ScheduleReconcile(SopInstanceProcessorContext context, DicomFile file, WorkQueueUid uid)
		{
			ImageReconciler reconciler = new ImageReconciler(context);
			reconciler.ScheduleReconcile(file, StudyIntegrityReasonEnum.InconsistentData, uid);
		}
		/// <summary>
		/// Process a specific DICOM file related to a <see cref="WorkQueue"/> request.
		/// </summary>
		/// <remarks>
		/// <para>
		/// On success and if <see cref="uid"/> is set, the <see cref="WorkQueueUid"/> field is deleted.
		/// </para>
		/// </remarks>
		/// <param name="stream">The <see cref="StudyXml"/> file to update with information from the file.</param>
		/// <param name="group">A group the sop is associated with.</param>
		/// <param name="file">The file to process.</param>
		/// <param name="compare">Flag to compare the demographics of <see cref="file"/> with the demographics in the database</param>
		/// <param name="retry">Flag telling if the item should be retried on failure.  Note that if the item is a duplicate, the WorkQueueUid item is not failed. </param>
		/// <param name="uid">An optional WorkQueueUid associated with the entry, that will be deleted upon success or failed on failure.</param>
		/// <param name="deleteFile">An option file to delete as part of the process</param>
		/// <param name="sopType">Flag telling if the SOP is a new or updated SOP</param>
        /// <exception cref="Exception"/>
        /// <exception cref="DicomDataException"/>
		public  ProcessingResult ProcessFile(string group, DicomFile file, StudyXml stream, bool compare, bool retry, WorkQueueUid uid, string deleteFile, SopInstanceProcessorSopType sopType)
		{
		    Platform.CheckForNullReference(file, "file");

            try
            {
                CheckDataLength(file);

                _instanceStats.ProcessTime.Start();
                ProcessingResult result = new ProcessingResult
                                              {
                                                  Status = ProcessingStatus.Success
                                              };

                using (ServerCommandProcessor processor = new ServerCommandProcessor("Process File"))
                {
                    SopInstanceProcessorContext processingContext = new SopInstanceProcessorContext(processor,
                                                                                      _context.StorageLocation, group);

                    if (EnforceNameRules)
                    {
                        _patientNameRules.Apply(file);
                    }

                    if (compare && ShouldReconcile(_context.StorageLocation, file))
                    {
                        ScheduleReconcile(processingContext, file, uid);
                        result.Status = ProcessingStatus.Reconciled;
                    }
                    else
                    {
                        InsertInstance(file, stream, uid, deleteFile,sopType);
                        result.Status = ProcessingStatus.Success;
                    }
                }

                _instanceStats.ProcessTime.End();

                if (_context.SopProcessedRulesEngine.Statistics.LoadTime.IsSet)
                    _instanceStats.SopRulesLoadTime.Add(_context.SopProcessedRulesEngine.Statistics.LoadTime);

                if (_context.SopProcessedRulesEngine.Statistics.ExecutionTime.IsSet)
                    _instanceStats.SopEngineExecutionTime.Add(_context.SopProcessedRulesEngine.Statistics.ExecutionTime);

                _context.SopProcessedRulesEngine.Statistics.Reset();

                //TODO: Should throw exception if result is failed?
                return result;

            }
            catch (Exception e)
            {
                // If its a duplicate, ignore the exception, and just throw it
                if (deleteFile != null && (e is InstanceAlreadyExistsException
                        || e.InnerException is InstanceAlreadyExistsException))
                    throw;

                if (uid != null)
                    FailUid(uid, retry);
                throw;
            }
		}
		private DicomProcessingResult HandleDuplicateFile(string sopInstanceUid, StudyStorageLocation studyLocation, ServerCommandProcessor commandProcessor, DicomMessageBase message, string sourceFilename, StudyProcessWorkQueueData data)
		{
			Study study = studyLocation.Study ??
						  studyLocation.LoadStudy(ServerExecutionContext.Current.PersistenceContext);
			if (study != null)
				Platform.Log(LogLevel.Info, "Received duplicate SOP {0} (A#:{1} StudyUid:{2}  Patient: {3}  ID:{4})",
							 sopInstanceUid,
							 study.AccessionNumber, study.StudyInstanceUid,
							 study.PatientsName, study.PatientId);
			else
				Platform.Log(LogLevel.Info,
							 "Received duplicate SOP {0} (StudyUid:{1}). Existing files haven't been processed.",
							 sopInstanceUid, studyLocation.StudyInstanceUid);

			var sopProcessingContext = new SopInstanceProcessorContext(commandProcessor, studyLocation, _context.ContextID,
																_context.Request)
			{
				DuplicateProcessing = _context.DuplicateProcessing
			};
			DicomProcessingResult result = DuplicateSopProcessorHelper.Process(sopProcessingContext, message, data,
			                                                                   sourceFilename);
			return result;
		}
		private static void SaveDuplicateFile(SopInstanceProcessorContext context, string sopInstanceUid, string sourceFilename)
		{
			String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, context.Group /* the AE title + timestamp */);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, sopInstanceUid);
			path += "." + ServerPlatform.DuplicateFileExtension;

			context.CommandProcessor.AddCommand(new RenameFileCommand(sourceFilename, path, true));

			Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
		}
		private static void SaveDuplicate(SopInstanceProcessorContext context, DicomFile file)
		{
			String sopUid = file.DataSet[DicomTags.SopInstanceUid].ToString();

			String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, context.Group /* the AE title + timestamp */);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
			context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

			path = Path.Combine(path, sopUid);
			path += "." + ServerPlatform.DuplicateFileExtension;

			context.CommandProcessor.AddCommand(new SaveDicomFileCommand(path, file, true));

			Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
		}
		/// <summary>
		/// Create Duplicate SIQ Entry
		/// </summary>
		/// <param name="file"></param>
		/// <param name="location"></param>
		/// <param name="sourcePath"></param>
		/// <param name="queue"></param>
		/// <param name="uid"></param>
		/// <param name="data"></param>
		public static void CreateDuplicateSIQEntry(DicomFile file, StudyStorageLocation location, string sourcePath,
		                                           WorkQueue queue, WorkQueueUid uid, StudyProcessWorkQueueData data)
		{
			Platform.Log(LogLevel.Info, "Creating Work Queue Entry for duplicate...");
			String uidGroup = queue.GroupID ?? queue.GetKey().Key.ToString();
			using (var commandProcessor = new ServerCommandProcessor("Insert Work Queue entry for duplicate"))
			{
				commandProcessor.AddCommand(new FileDeleteCommand(sourcePath, true));

				var sopProcessingContext = new SopInstanceProcessorContext(commandProcessor, location, uidGroup);
				DicomProcessingResult result = Process(sopProcessingContext, file, data);
				if (!result.Successful)
				{
					FailUid(uid, true);
					return;
				}

				commandProcessor.AddCommand(new DeleteWorkQueueUidCommand(uid));

				if (!commandProcessor.Execute())
				{
					Platform.Log(LogLevel.Error, "Unexpected error when creating duplicate study integrity queue entry: {0}",
					             commandProcessor.FailureReason);
					FailUid(uid, true);
				}
			}
		}
		/// <summary>
		/// Inserts the duplicate DICOM file into the <see cref="WorkQueue"/> for processing (if applicable).
		/// </summary>
		/// <param name="context">The processing context.</param>
		/// <param name="file">The duplicate DICOM file being processed.</param>
		/// <param name="data">Extra data to insert for the WorkQueue item.</param>
		/// <param name="sourceFilename">Optional source filename already saved to disk to import.</param>
		/// <returns>A <see cref="DicomProcessingResult"/> that contains the result of the processing.</returns>
		/// <remarks>
		/// This method inserts a <see cref="CommandBase"/> into <paramref name="context.CommandProcessor"/>.
		/// The outcome of the operation depends on the <see cref="DuplicateSopPolicyEnum"/> of the <see cref="ServerPartition"/>.
		/// If it is set to <see cref="DuplicateSopPolicyEnum.CompareDuplicates"/>, the duplicate file will be
		/// inserted into the <see cref="WorkQueue"/> for processing.
		/// </remarks>
		public static DicomProcessingResult Process(SopInstanceProcessorContext context, DicomMessageBase file,
		                                            StudyProcessWorkQueueData data, string sourceFilename=null)
		{
			Platform.CheckForNullReference(file, "file");
			Platform.CheckForNullReference(context, "context");
			Platform.CheckMemberIsSet(context.Group, "parameters.Group");
			Platform.CheckMemberIsSet(context.CommandProcessor, "parameters.CommandProcessor");
			Platform.CheckMemberIsSet(context.StudyLocation, "parameters.StudyLocation");
			if (string.IsNullOrEmpty(sourceFilename))
				Platform.CheckForNullReference(file as DicomFile, "file");

			var result = new DicomProcessingResult
				{
					DicomStatus = DicomStatuses.Success,
					Successful = true,
					StudyInstanceUid = file.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty),
					SeriesInstanceUid = file.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty),
					SopInstanceUid = file.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty),
					SopClassUid = file.DataSet[DicomTags.SopClassUid].GetString(0, string.Empty),
					AccessionNumber = file.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty)
				};

			string failureMessage;

			if (context.DuplicateProcessing.HasValue && context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Reject))
			{
				failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
				Platform.Log(LogLevel.Info, failureMessage);
				result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
				return result;
			}

			if (SopClassIsReport(result.SopClassUid) && context.StudyLocation.ServerPartition.AcceptLatestReport)
			{
				Platform.Log(LogLevel.Info, "Duplicate Report received, overwriting {0}", result.SopInstanceUid);
				if (string.IsNullOrEmpty(sourceFilename))
					ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteReport);
				else
					ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteReport);
				
				return result;
			}

			if (DuplicatePolicy.IsParitionDuplicatePolicyOverridden(context.StudyLocation))
			{
				Platform.Log(LogLevel.Warn,
				             "Duplicate instance received for study {0} on Partition {1}. Duplicate policy overridden. Will overwrite {2}",
				             result.StudyInstanceUid, context.StudyLocation.ServerPartition.AeTitle, result.SopInstanceUid);
				if (string.IsNullOrEmpty(sourceFilename))
					ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSop);
				else
					ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSop);
				return result;
			}

			if (context.DuplicateProcessing.HasValue)
			{
				Platform.Log(LogLevel.Info, context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Compare)
					                            ? "Duplicate SOP Instance received, comparing {0}"
					                            : "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
				if (string.IsNullOrEmpty(sourceFilename))
					ProcessStoredDuplicate(context, file as DicomFile, data, context.DuplicateProcessing.Value);
				else
					ProcessStoredDuplicateFile(context, sourceFilename, file, data, context.DuplicateProcessing.Value);

				return result;
			}

			if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.AcceptLatest))
			{
				Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
				if (string.IsNullOrEmpty(sourceFilename))
					ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
				else
					ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
				return result;
			}

			if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.SendSuccess))
			{
				Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, sending success response {0}", result.SopInstanceUid);
				return result;
			}

			if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.RejectDuplicates))
			{
				failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
				Platform.Log(LogLevel.Info, failureMessage);
				result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
				return result;
			}

			if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.CompareDuplicates))
			{
				if (string.IsNullOrEmpty(sourceFilename))
					ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.Compare);
				else
					ProcessStoredDuplicateFile(context,sourceFilename,file,data,DuplicateProcessingEnum.Compare);
			}
			else
			{
				failureMessage = String.Format("Duplicate SOP Instance received. Unsupported duplicate policy {0}.",
				                               context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum);
				result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
				return result;
			}

			return result;
		}
Beispiel #15
0
        /// <summary>
        /// Inserts the duplicate DICOM file into the <see cref="WorkQueue"/> for processing (if applicable).
        /// </summary>
        /// <param name="context">The processing context.</param>
        /// <param name="file">The duplicate DICOM file being processed.</param>
        /// <param name="data">Extra data to insert for the WorkQueue item.</param>
        /// <param name="sourceFilename">Optional source filename already saved to disk to import.</param>
        /// <returns>A <see cref="DicomProcessingResult"/> that contains the result of the processing.</returns>
        /// <remarks>
        /// This method inserts a <see cref="CommandBase"/> into <paramref name="context.CommandProcessor"/>.
        /// The outcome of the operation depends on the <see cref="DuplicateSopPolicyEnum"/> of the <see cref="ServerPartition"/>.
        /// If it is set to <see cref="DuplicateSopPolicyEnum.CompareDuplicates"/>, the duplicate file will be
        /// inserted into the <see cref="WorkQueue"/> for processing.
        /// </remarks>
        public static DicomProcessingResult Process(SopInstanceProcessorContext context, DicomMessageBase file,
                                                    StudyProcessWorkQueueData data, string sourceFilename = null)
        {
            Platform.CheckForNullReference(file, "file");
            Platform.CheckForNullReference(context, "context");
            Platform.CheckMemberIsSet(context.Group, "parameters.Group");
            Platform.CheckMemberIsSet(context.CommandProcessor, "parameters.CommandProcessor");
            Platform.CheckMemberIsSet(context.StudyLocation, "parameters.StudyLocation");
            if (string.IsNullOrEmpty(sourceFilename))
            {
                Platform.CheckForNullReference(file as DicomFile, "file");
            }

            var result = new DicomProcessingResult
            {
                DicomStatus       = DicomStatuses.Success,
                Successful        = true,
                StudyInstanceUid  = file.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty),
                SeriesInstanceUid = file.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty),
                SopInstanceUid    = file.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty),
                SopClassUid       = file.DataSet[DicomTags.SopClassUid].GetString(0, string.Empty),
                AccessionNumber   = file.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty)
            };

            string failureMessage;

            if (context.DuplicateProcessing.HasValue && context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Reject))
            {
                failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
                Platform.Log(LogLevel.Info, failureMessage);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            if (SopClassIsReport(result.SopClassUid) && context.StudyLocation.ServerPartition.AcceptLatestReport)
            {
                Platform.Log(LogLevel.Info, "Duplicate Report received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteReport);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteReport);
                }

                return(result);
            }

            if (DuplicatePolicy.IsParitionDuplicatePolicyOverridden(context.StudyLocation))
            {
                Platform.Log(LogLevel.Warn,
                             "Duplicate instance received for study {0} on Partition {1}. Duplicate policy overridden. Will overwrite {2}",
                             result.StudyInstanceUid, context.StudyLocation.ServerPartition.AeTitle, result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSop);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSop);
                }
                return(result);
            }

            if (context.DuplicateProcessing.HasValue)
            {
                Platform.Log(LogLevel.Info, context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Compare)
                                                                    ? "Duplicate SOP Instance received, comparing {0}"
                                                                    : "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, context.DuplicateProcessing.Value);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, context.DuplicateProcessing.Value);
                }

                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.AcceptLatest))
            {
                Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
                }
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.SendSuccess))
            {
                Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, sending success response {0}", result.SopInstanceUid);
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.RejectDuplicates))
            {
                failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
                Platform.Log(LogLevel.Info, failureMessage);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.CompareDuplicates))
            {
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.Compare);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.Compare);
                }
            }
            else
            {
                failureMessage = String.Format("Duplicate SOP Instance received. Unsupported duplicate policy {0}.",
                                               context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            return(result);
        }
 /// <summary>
 /// Creates an instance of <see cref="ImageReconciler"/>
 /// </summary>
 /// <param name="context"></param>
 public ImageReconciler(SopInstanceProcessorContext context)
 {
     _context = context;
 }