/// <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)); }
/// <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(); } } }
/// <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(); } }
/// <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(); } }