예제 #1
0
        /// <summary>
        /// Gets a list of <see cref="StudySummary"/> correspeonding to the studies currently selected
        /// </summary>
        /// <returns></returns>
        private void LoadSelectedStudies()
        {
            _selectedStudies = new List <StudySummary>();

            string[] selectedKeys = StudyListControl.SelectedDataKeys;
            if (selectedKeys != null)
            {
                foreach (var key in selectedKeys)
                {
                    // Note: the selected study may not be on the current the page.
                    // This can happens for example when some of the studies which appear before it are deleted from the system.
                    // For this reason, if the selected study does not appear on the current page, we need to load the studies from the database
                    StudySummary studySummary;
                    if (!TryFindStudySummaryOnCurrentPage(key, out studySummary))
                    {
                        var persistentContext = HttpContext.Current.GetSharedPersistentContext();
                        var study             = Study.Load(persistentContext, new ServerEntityKey("Study", key));
                        if (study != null)
                        {
                            studySummary = StudySummaryAssembler.CreateStudySummary(persistentContext, study);
                        }
                    }

                    if (studySummary != null)
                    {
                        _selectedStudies.Add(studySummary);
                    }
                }
            }
        }
        private void RemoveExistingImage(WorkQueueUid uid)
        {
            string path = StorageLocation.GetSopInstancePath(uid.SeriesInstanceUid, uid.SopInstanceUid);

            if (!File.Exists(path))
            {
                return;
            }

            StudyXml studyXml = StorageLocation.LoadStudyXml();
            var      file     = new DicomFile(path);

            file.Load(DicomReadOptions.DoNotStorePixelDataInDataSet | DicomReadOptions.Default); // don't need to load pixel data cause we will delete it

            #if DEBUG
            int originalInstanceCountInXml  = studyXml.NumberOfStudyRelatedInstances;
            int originalStudyInstanceCount  = Study.NumberOfStudyRelatedInstances;
            int originalSeriesInstanceCount = Study.Series[uid.SeriesInstanceUid].NumberOfSeriesRelatedInstances;
            #endif

            using (var processor = new ServerCommandProcessor("Delete Existing Image"))
            {
                var seriesInstanceUid = file.DataSet[DicomTags.SeriesInstanceUid].ToString();
                var sopInstanceUid    = file.DataSet[DicomTags.SopInstanceUid].ToString();

                processor.AddCommand(new FileDeleteCommand(path, true));
                processor.AddCommand(new RemoveInstanceFromStudyXmlCommand(StorageLocation, studyXml, seriesInstanceUid, sopInstanceUid));
                processor.AddCommand(new UpdateInstanceCountCommand(StorageLocation, seriesInstanceUid, sopInstanceUid));

                if (!processor.Execute())
                {
                    throw new ApplicationException(String.Format("Unable to remove existing image {0}", file.Filename), processor.FailureException);
                }
            }

            #if DEBUG
            Debug.Assert(!File.Exists(path));
            Debug.Assert(studyXml.NumberOfStudyRelatedInstances == originalInstanceCountInXml - 1);
            Debug.Assert(Study.Load(Study.Key).NumberOfStudyRelatedInstances == originalStudyInstanceCount - 1);
            Debug.Assert(Study.Load(Study.Key).Series[uid.SeriesInstanceUid].NumberOfSeriesRelatedInstances == originalSeriesInstanceCount - 1);
            #endif
        }
        protected override TestResult InnerTest(object data, object root)
        {
            if (ServerExecutionContext.Current.PrimaryStudyKey != null)
            {
                var study = Study.Load(ServerExecutionContext.Current.PrimaryStudyKey);
                Platform.CheckForNullReference(study, "The referenced study does not exist in the database");

                if (study.OrderKey != null)
                {
                    var order = Order.Load(study.OrderKey);
                    if (order.QCExpected)
                    {
                        return(DefaultTestResult(true));
                    }
                }
                Platform.Log("QC", LogLevel.Info, "Study does not have an order or the order is not intended for QC.");
            }

            return(DefaultTestResult(false));
        }
예제 #4
0
        /// <summary>
        /// Populate the data from a <see cref="Series"/> entity into a DICOM C-FIND-RSP message.
        /// </summary>
        /// <param name="read">The connection to use to read the values.</param>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
        /// <param name="row">The <see cref="Series"/> table to populate the row from.</param>
        private void PopulateSeries(IPersistenceContext read, DicomAttributeCollection request, DicomMessageBase response, IEnumerable <uint> tagList,
                                    Series row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            Study        theStudy = Study.Load(read, row.StudyKey);
            StudyStorage storage  = StudyStorage.Load(read, theStudy.ServerPartitionKey, theStudy.StudyInstanceUid);

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(ServerPartitionMonitor.Instance.FindPartition(row.ServerPartitionKey).AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue(storage.StudyStatusEnum == StudyStatusEnum.Nearline
                                                                       ? "NEARLINE"
                                                                       : "ONLINE");

            if (false == String.IsNullOrEmpty(theStudy.SpecificCharacterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(theStudy.SpecificCharacterSet);
                dataSet.SpecificCharacterSet = theStudy.SpecificCharacterSet; // this will ensure the data is encoded using the specified character set
            }

            foreach (uint tag in tagList)
            {
                try
                {
                    switch (tag)
                    {
                    case DicomTags.PatientId:
                        dataSet[DicomTags.PatientId].SetStringValue(request[DicomTags.PatientId].ToString());
                        break;

                    case DicomTags.StudyInstanceUid:
                        dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                            request[DicomTags.StudyInstanceUid].ToString());
                        break;

                    case DicomTags.SeriesInstanceUid:
                        dataSet[DicomTags.SeriesInstanceUid].SetStringValue(row.SeriesInstanceUid);
                        break;

                    case DicomTags.Modality:
                        dataSet[DicomTags.Modality].SetStringValue(row.Modality);
                        break;

                    case DicomTags.SeriesNumber:
                        dataSet[DicomTags.SeriesNumber].SetStringValue(row.SeriesNumber);
                        break;

                    case DicomTags.SeriesDescription:
                        dataSet[DicomTags.SeriesDescription].SetStringValue(row.SeriesDescription);
                        break;

                    case DicomTags.PerformedProcedureStepStartDate:
                        dataSet[DicomTags.PerformedProcedureStepStartDate].SetStringValue(
                            row.PerformedProcedureStepStartDate);
                        break;

                    case DicomTags.PerformedProcedureStepStartTime:
                        dataSet[DicomTags.PerformedProcedureStepStartTime].SetStringValue(
                            row.PerformedProcedureStepStartTime);
                        break;

                    case DicomTags.NumberOfSeriesRelatedInstances:
                        dataSet[DicomTags.NumberOfSeriesRelatedInstances].AppendInt32(row.NumberOfSeriesRelatedInstances);
                        break;

                    case DicomTags.RequestAttributesSequence:
                        LoadRequestAttributes(read, response, row);
                        break;

                    case DicomTags.QueryRetrieveLevel:
                        dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("SERIES");
                        break;

                    default:
                        dataSet[tag].SetNullValue();
                        break;

                    // Meta tags that should have not been in the RQ, but we've already set
                    case DicomTags.RetrieveAeTitle:
                    case DicomTags.InstanceAvailability:
                    case DicomTags.SpecificCharacterSet:
                        break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    dataSet[tag].SetNullValue();
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Delete a Study.
        /// </summary>
        public void DeleteStudy(ServerEntityKey studyKey, string reason)
        {
            StudySummary study = StudySummaryAssembler.CreateStudySummary(HttpContext.Current.GetSharedPersistentContext(), Study.Load(HttpContext.Current.GetSharedPersistentContext(), studyKey));

            if (study.IsReconcileRequired)
            {
                throw new ApplicationException(
                          String.Format("Deleting the study is not allowed at this time : there are items to be reconciled."));

                // NOTE: another check will occur when the delete is actually processed
            }

            using (IUpdateContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                StudyDeleteHelper.DeleteStudy(ctx, study.ThePartition, study.StudyInstanceUid, reason);
                ctx.Commit();
            }
        }
예제 #6
0
        /// <summary>
        /// Delete a Study.
        /// </summary>
        public void DeleteStudy(ServerEntityKey studyKey, string reason)
        {
            StudySummary study = StudySummaryAssembler.CreateStudySummary(HttpContextData.Current.ReadContext, Study.Load(HttpContextData.Current.ReadContext, studyKey));

            if (study.IsReconcileRequired)
            {
                throw new ApplicationException(
                          String.Format("Deleting the study is not allowed at this time : there are items to be reconciled."));

                // NOTE: another check will occur when the delete is actually processed
            }


            using (IUpdateContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
            {
                LockStudyParameters lockParms = new LockStudyParameters
                {
                    QueueStudyStateEnum = QueueStudyStateEnum.WebDeleteScheduled,
                    StudyStorageKey     = study.TheStudyStorage.Key
                };
                ILockStudy broker = ctx.GetBroker <ILockStudy>();
                broker.Execute(lockParms);
                if (!lockParms.Successful)
                {
                    throw new ApplicationException(String.Format("Unable to lock the study : {0}", lockParms.FailureReason));
                }


                InsertWorkQueueParameters insertParms = new InsertWorkQueueParameters
                {
                    WorkQueueTypeEnum  = WorkQueueTypeEnum.WebDeleteStudy,
                    ServerPartitionKey = study.ThePartition.Key,
                    StudyStorageKey    = study.TheStudyStorage.Key,
                    ScheduledTime      = Platform.Time
                };

                WebDeleteStudyLevelQueueData extendedData = new WebDeleteStudyLevelQueueData
                {
                    Level    = DeletionLevel.Study,
                    Reason   = reason,
                    UserId   = ServerHelper.CurrentUserId,
                    UserName = ServerHelper.CurrentUserName
                };
                insertParms.WorkQueueData = XmlUtils.SerializeAsXmlDoc(extendedData);
                IInsertWorkQueue insertWorkQueue = ctx.GetBroker <IInsertWorkQueue>();

                if (insertWorkQueue.FindOne(insertParms) == null)
                {
                    throw new ApplicationException("DeleteStudy failed");
                }


                ctx.Commit();
            }
        }