コード例 #1
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))
            {
                // Note: this is a special case where we need to temporarily override the duplicate policy for a particular study
                // so that SIQ entry can be processed (#10569). This should only happen once in a blue moon.

                Platform.Log(LogLevel.Warn,
                             "Duplicate instance received for study {0} on Partition {1}. Duplicate policy overridden in app config. 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);
        }
コード例 #2
0
        private ProcessDuplicateResult ProcessDuplicate(DicomFile dupFile, WorkQueueUid uid, StudyXml studyXml)
        {
            var result = new ProcessDuplicateResult();


            string duplicateSopPath = ServerPlatform.GetDuplicateUidPath(StorageLocation, uid);
            string basePath         = StorageLocation.GetSopInstancePath(uid.SeriesInstanceUid, uid.SopInstanceUid);

            if (!File.Exists(basePath))
            {
                // NOTE: This is special case. The file which caused dicom service to think this sop is a duplicate
                // no longer exists in the study folder. Perhaps it has been moved to another folder during auto reconciliation.
                // We have nothing to compare against so let's just throw it into the SIQ queue.
                CreateDuplicateSIQEntry(uid, dupFile, null);
                result.ActionTaken = DuplicateProcessResultAction.Reconcile;
            }
            else
            {
                // Check if system is configured to override the rule for this study
                if (DuplicatePolicy.IsParitionDuplicatePolicyOverridden(this.StorageLocation))
                {
                    return(OverwriteDuplicate(dupFile, uid, studyXml));
                }
                else
                {
                    var baseFile = new DicomFile(basePath);
                    baseFile.Load();

                    if (DuplicateSopProcessorHelper.SopClassIsReport(dupFile.SopClass.Uid) && ServerPartition.AcceptLatestReport)
                    {
                        return(ProcessDuplicateReport(dupFile, baseFile, uid, studyXml));
                    }


                    if (!dupFile.TransferSyntax.Equals(baseFile.TransferSyntax))
                    {
                        // If they're compressed, and we have a codec, lets decompress and still do the comparison
                        if (dupFile.TransferSyntax.Encapsulated &&
                            !dupFile.TransferSyntax.LossyCompressed &&
                            DicomCodecRegistry.GetCodec(dupFile.TransferSyntax) != null)
                        {
                            dupFile.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian);
                        }

                        if (baseFile.TransferSyntax.Encapsulated &&
                            !baseFile.TransferSyntax.LossyCompressed &&
                            DicomCodecRegistry.GetCodec(baseFile.TransferSyntax) != null)
                        {
                            baseFile.ChangeTransferSyntax(TransferSyntax.ExplicitVrLittleEndian);
                        }

                        if (dupFile.TransferSyntax.Encapsulated || baseFile.TransferSyntax.Encapsulated)
                        {
                            string failure = String.Format("Base file transfer syntax is '{0}' while duplicate file has '{1}'",
                                                           baseFile.TransferSyntax, dupFile.TransferSyntax);

                            var list          = new List <DicomAttributeComparisonResult>();
                            var compareResult = new DicomAttributeComparisonResult
                            {
                                ResultType = ComparisonResultType.DifferentValues,
                                TagName    = DicomTagDictionary.GetDicomTag(DicomTags.TransferSyntaxUid).Name,
                                Details    = failure
                            };
                            list.Add(compareResult);
                            CreateDuplicateSIQEntry(uid, dupFile, list);
                            result.ActionTaken = DuplicateProcessResultAction.Reconcile;
                            return(result);
                        }
                    }

                    var failureReason = new List <DicomAttributeComparisonResult>();
                    if (baseFile.DataSet.Equals(dupFile.DataSet, ref failureReason))
                    {
                        Platform.Log(LogLevel.Info,
                                     "Duplicate SOP being processed is identical.  Removing SOP: {0}",
                                     baseFile.MediaStorageSopInstanceUid);


                        RemoveWorkQueueUid(uid, duplicateSopPath);
                        result.ActionTaken = DuplicateProcessResultAction.Delete;
                    }
                    else
                    {
                        CreateDuplicateSIQEntry(uid, dupFile, failureReason);
                        result.ActionTaken = DuplicateProcessResultAction.Reconcile;
                    }
                }
            }

            return(result);
        }
コード例 #3
0
        // TODO: Make these values configurable

        #endregion

        #region Public Methods

        /// <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">Thje duplicate DICOM file being processed.</param>
        /// <returns>A <see cref="DicomProcessingResult"/> that contains the result of the processing.</returns>
        /// <remarks>
        /// This method inserts <see cref="ServerCommand"/> 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>
        static public DicomProcessingResult Process(SopProcessingContext context, DicomFile file)
        {
            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");

            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 (SopClassIsReport(result.SopClassUid) && context.StudyLocation.ServerPartition.AcceptLatestReport)
            {
                Platform.Log(LogLevel.Info, "Duplicate Report received, overwriting {0}", result.SopInstanceUid);
                SaveDuplicate(context, file);
                context.CommandProcessor.AddCommand(
                    new UpdateWorkQueueCommand(file, context.StudyLocation, true, ServerPlatform.DuplicateFileExtension, context.Group));
                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);
                SaveDuplicate(context, file);
                context.CommandProcessor.AddCommand(new UpdateWorkQueueCommand(file, context.StudyLocation, true, ServerPlatform.DuplicateFileExtension, context.Group));
                return(result);
            }
            else
            {
                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))
                {
                    SaveDuplicate(context, file);
                    context.CommandProcessor.AddCommand(
                        new UpdateWorkQueueCommand(file, context.StudyLocation, true, ServerPlatform.DuplicateFileExtension, context.Group));
                }
                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);
        }