public StudyItem(Study study) { _study = study; StudyStorage = StudyStorage.Load(_study.StudyStorageKey); StudyStorageLocation = StudyStorageLocation.FindStorageLocations(StudyStorage).FirstOrDefault(); _status = StudyStorage.StudyStatusEnum.Description; }
public override void DataBind() { ExistingPatientSeriesGridView.DataSource = ReconcileDetails.ExistingStudy.Series; ConflictingPatientSeriesGridView.DataSource = ReconcileDetails.ConflictingStudyInfo.Series; StudyStorage storage = StudyStorage.Load(HttpContextData.Current.ReadContext, StudyIntegrityQueueItem.StudyStorageKey); IList <StudyStorageLocation> studyLocations = StudyStorageLocation.FindStorageLocations(storage); StudyStorageLocation location = studyLocations[0]; StudyLocation.Text = location.GetStudyPath(); ConflictingStudyLocation.Text = ReconcileDetails != null ? ReconcileDetails.GetFolderPath() : SR.NotSpecified; string reason; CanReconcile = _controller.CanReconcile(location, out reason); MessagePanel.Visible = !CanReconcile; AlertMessage.Text = reason; OKButton.Enabled = CanReconcile; OptionRow.Visible = CanReconcile; base.DataBind(); }
protected void DeleteItemButton_Click(object sender, EventArgs e) { RestoreQueueItemList.RefreshCurrentPage(); IList <Model.RestoreQueue> items = RestoreQueueItemList.SelectedItems; if (items != null && items.Count > 0) { if (items.Count > 1) { MessageBox.Message = string.Format(SR.MultipleRestoreQueueDelete); } else { MessageBox.Message = string.Format(SR.SingleRestoreQueueDelete); } MessageBox.Message += "<table>"; foreach (Model.RestoreQueue item in items) { String text = ""; String.Format("<tr align='left'><td>{0}:{1}</td></tr>", SR.StudyInstanceUID, StudyStorage.Load(item.StudyStorageKey).StudyInstanceUid); MessageBox.Message += text; } MessageBox.Message += "</table>"; MessageBox.MessageType = MessageBox.MessageTypeEnum.YESNO; MessageBox.Data = items; MessageBox.Show(); } }
public string GetFolderPath() { if (_location == null) { if (_studyStorage == null) { using (IReadContext context = PersistentStoreRegistry.GetDefaultStore().OpenReadContext()) { _studyStorage = StudyStorage.Load(context, _item.StudyStorageKey); } } _location = StudyStorageLocation.FindStorageLocations(_studyStorage)[0]; } String path = Path.Combine(_location.FilesystemPath, _location.PartitionFolder); path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder); if (!string.IsNullOrEmpty(_item.GroupID)) { path = Path.Combine(path, _item.GroupID); } path = Path.Combine(path, _location.StudyInstanceUid); return(path); }
/// <summary> /// Returns the name of the directory in the filesytem /// where the study with the specified information will be stored. /// </summary> /// <returns></returns> /// private static string ResolveStorageFolder(ServerEntityKey partitionKey, string studyInstanceUid, string studyDate, IPersistenceContext persistenceContext, bool checkExisting) { string folder; if (checkExisting) { StudyStorage storage = StudyStorage.Load(persistenceContext, partitionKey, studyInstanceUid); if (storage != null) { folder = ImageServerCommonConfiguration.UseReceiveDateAsStudyFolder ? storage.InsertTime.ToString("yyyyMMdd") : String.IsNullOrEmpty(studyDate) ? ImageServerCommonConfiguration.DefaultStudyRootFolder : studyDate; return(folder); } } folder = ImageServerCommonConfiguration.UseReceiveDateAsStudyFolder ? Platform.Time.ToString("yyyyMMdd") : String.IsNullOrEmpty(studyDate) ? ImageServerCommonConfiguration.DefaultStudyRootFolder : studyDate; return(folder); }
protected override string GetTemporaryPath() { StudyStorageLocation storage = StudyStorageLocation.FindStorageLocations(StudyStorage.Load(_item.StudyStorageKey))[0]; if (storage == null) { return(base.GetTemporaryPath()); } else { String basePath = GetTempPathRoot(); if (String.IsNullOrEmpty(basePath)) { basePath = Path.Combine(storage.FilesystemPath, "temp"); } String tempDirectory = Path.Combine(basePath, String.Format("ArchiveQueue-{0}", _item.GetKey())); for (int i = 2; i < 1000; i++) { if (!Directory.Exists(tempDirectory)) { break; } tempDirectory = Path.Combine(basePath, String.Format("ArchiveQueue-{0}({1})", _item.GetKey(), i)); } if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } return(tempDirectory); } }
/// <summary> /// Creates an instance of <see cref="StudyDetails"/> base on a <see cref="Study"/> object. /// </summary> /// <param name="study"></param> /// <returns></returns> public StudyDetails CreateStudyDetail(Study study) { var details = new StudyDetails(); details.StudyInstanceUID = study.StudyInstanceUid; details.PatientName = study.PatientsName; details.AccessionNumber = study.AccessionNumber; details.PatientID = study.PatientId; details.StudyDescription = study.StudyDescription; details.StudyDate = study.StudyDate; details.StudyTime = study.StudyTime; var controller = new StudyController(); using (IReadContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenReadContext()) { details.Modalities = controller.GetModalitiesInStudy(ctx, study); } if (study.StudyInstanceUid != null) { StudyStorage storages = StudyStorage.Load(study.StudyStorageKey); if (storages != null) { details.WriteLock = storages.WriteLock; details.ReadLock = storages.ReadLock; details.Status = storages.StudyStatusEnum.ToString(); } } return(details); }
protected void DeleteItemButton_Click(object sender, EventArgs e) { IList <Model.ArchiveQueue> items = ArchiveQueueItemList.SelectedItems; if (items != null && items.Count > 0) { if (items.Count > 1) { MessageBox.Message = string.Format(SR.MultipleArchiveQueueDelete); } else { MessageBox.Message = string.Format(SR.SingleArchiveQueueDelete); } MessageBox.Message += "<table style=\"border: solid #CCCCCC 2px; margin-top: 5px;\">"; foreach (Model.ArchiveQueue item in items) { MessageBox.Message += String.Format("<tr><td style=\"font-weight: bold; color: #618FAD\">{0}:</td><td style=\"font-weight: normal; color: black;\">{1}</td></tr>", SR.StudyInstanceUID, StudyStorage.Load(item.StudyStorageKey).StudyInstanceUid); } MessageBox.Message += "</table>"; MessageBox.MessageType = MessageBox.MessageTypeEnum.YESNO; MessageBox.MessageStyle = "color: #FF0000; font-weight: bold;"; MessageBox.Data = items; MessageBox.Show(); } }
private void LoadStorageLocation() { if (_storageLocation == null) { var studyStorage = StudyStorage.Load(HttpContext.Current.GetSharedPersistentContext(), TheStudyIntegrityQueueItem.StudyStorageKey); _storageLocation = StudyStorageLocation.FindStorageLocations(studyStorage)[0]; } }
private void LoadStorageLocation() { if (_storageLocation == null) { var studyStorage = StudyStorage.Load(HttpContextData.Current.ReadContext, TheStudyIntegrityQueueItem.StudyStorageKey); _storageLocation = StudyStorageLocation.FindStorageLocations(studyStorage)[0]; } }
public InconsistentDataSIQRecord(StudyIntegrityQueue queue) { _queueItem = queue; ReconcileStudyWorkQueueData data = XmlUtils.Deserialize <ReconcileStudyWorkQueueData>(queue.Details); _conflictingImageDetails = data.Details; _conflictingImageDescriptor = XmlUtils.Deserialize <ImageSetDescriptor>(queue.StudyData); StudyStorage storage = StudyStorage.Load(HttpContextData.Current.ReadContext, queue.StudyStorageKey); Study study = storage.LoadStudy(HttpContextData.Current.ReadContext); _existingStudyInfo = new StudyInformation(new ServerEntityAttributeProvider(study)); }
private static bool GetStudyStorage(ServerPartition partition, string studyInstanceUid, out StudyStorage storage) { using (ServerExecutionContext context = new ServerExecutionContext()) { storage = StudyStorage.Load(context.ReadContext, partition.Key, studyInstanceUid); if (storage != null) { return(true); } return(false); } }
private void DetermineTargetLocation() { if (Context.History.DestStudyStorageKey != null) { _destinationStudyStorage = StudyStorageLocation.FindStorageLocations(StudyStorage.Load(Context.History.DestStudyStorageKey))[0]; } else { _destinationStudyStorage = Context.WorkQueueItemStudyStorage; Context.History.DestStudyStorageKey = _destinationStudyStorage.Key; } }
public static ReconcileHistoryRecord ReadReconcileRecord(StudyHistory historyRecord) { Platform.CheckTrue(historyRecord.StudyHistoryTypeEnum == StudyHistoryTypeEnum.StudyReconciled, "History record has invalid history record type"); ReconcileHistoryRecord record = new ReconcileHistoryRecord(); record.InsertTime = historyRecord.InsertTime; record.StudyStorageLocation = StudyStorageLocation.FindStorageLocations(StudyStorage.Load(historyRecord.StudyStorageKey))[0]; StudyReconcileDescriptorParser parser = new StudyReconcileDescriptorParser(); record.UpdateDescription = parser.Parse(historyRecord.ChangeDescription); return(record); }
/// <summary> /// Inserts an External edit request(s) to update a study. /// </summary> /// <remarks> /// The External Edit request can be for a study in any state. The study could be offline/nearline/etc. /// </remarks> /// <param name="context">The persistence context used for database connection.</param> /// <param name="studyStorageKey">The StudyStorage record key</param> /// <param name="reason">The reason the study is being editted</param> /// <param name="user">A string identifying the user that triggered the edit and is stored with the history for the edit.</param> /// <exception cref="InvalidStudyStateOperationException"></exception> /// <param name="updateItems"></param> /// <param name="editType">The request is a web edit request </param> public static IList <WorkQueue> ExternalEditStudy(IUpdateContext context, ServerEntityKey studyStorageKey, List <UpdateItem> updateItems, string reason, string user, EditType editType) { // Find all location of the study in the system and insert series delete request StudyStorage s = StudyStorage.Load(studyStorageKey); IList <WorkQueue> entries = new List <WorkQueue>(); // insert an edit request WorkQueue request = InsertExternalEditStudyRequest(context, s.Key, s.ServerPartitionKey, WorkQueueTypeEnum.ExternalEdit, updateItems, reason, user, editType); entries.Add(request); return(entries); }
protected override string GetTemporaryPath() { IList <StudyStorageLocation> storages = StudyStorageLocation.FindStorageLocations(StudyStorage.Load(_item.StudyStorageKey)); if (storages == null || storages.Count == 0) { // ??? return(base.GetTemporaryPath()); } ServerFilesystemInfo filesystem = FilesystemMonitor.Instance.GetFilesystemInfo(storages[0].FilesystemKey); if (filesystem == null) { // not ready? return(base.GetTemporaryPath()); } string basePath = GetTempPathRoot(); if (String.IsNullOrEmpty(basePath)) { basePath = Path.Combine(filesystem.Filesystem.FilesystemPath, "temp"); } String tempDirectory = Path.Combine(basePath, String.Format("{0}-{1}", _item.WorkQueueTypeEnum.Lookup, _item.GetKey())); for (int i = 2; i < 1000; i++) { if (!Directory.Exists(tempDirectory)) { break; } tempDirectory = Path.Combine(basePath, String.Format("{0}-{1}({2})", _item.WorkQueueTypeEnum.Lookup, _item.GetKey(), i)); } if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } return(tempDirectory); }
public override void DataBind() { ExistingPatientSeriesGridView.DataSource = DuplicateEntryDetails.ExistingStudy.Series; ConflictingPatientSeriesGridView.DataSource = DuplicateEntryDetails.ConflictingImageSet.StudyInfo.Series; StudyStorage storage = StudyStorage.Load(HttpContext.Current.GetSharedPersistentContext(), StudyIntegrityQueueItem.StudyStorageKey); IList <StudyStorageLocation> studyLocations = StudyStorageLocation.FindStorageLocations(storage); StudyLocation.Text = studyLocations[0].GetStudyPath(); var entry = new DuplicateSopReceivedQueue(StudyIntegrityQueueItem); DuplicateSopLocation.Text = entry.GetFolderPath(HttpContext.Current.GetSharedPersistentContext()); ComparisonResultGridView.DataSource = DuplicateEntryDetails.QueueData.ComparisonResults; base.DataBind(); }
private void CreateDestinationStudyStorage() { // This really should never happen; if (Context.History.DestStudyStorageKey != null) { _destinationStudyStorage = StudyStorageLocation.FindStorageLocations(StudyStorage.Load(Context.History.DestStudyStorageKey))[0]; return; } string newStudyInstanceUid = string.Empty; // Get the new Study Instance Uid by looking through the update commands foreach (BaseImageLevelUpdateCommand command in Commands) { SetTagCommand setTag = command as SetTagCommand; if (setTag != null && setTag.Tag.TagValue.Equals(DicomTags.StudyInstanceUid)) { newStudyInstanceUid = setTag.Value; break; } } if (string.IsNullOrEmpty(newStudyInstanceUid)) { throw new ApplicationException("Unexpectedly could not find new Study Instance Uid value for Create Study"); } using (ServerCommandProcessor processor = new ServerCommandProcessor("Reconciling image processor")) { // Assign new series and instance uid InitializeStorageCommand command = new InitializeStorageCommand(Context, newStudyInstanceUid, Context.WorkQueueItemStudyStorage.StudyFolder, TransferSyntax.GetTransferSyntax(Context.WorkQueueItemStudyStorage.TransferSyntaxUid)); processor.AddCommand(command); if (!processor.Execute()) { throw new ApplicationException(String.Format("Unable to create Study Storage for study: {0}", newStudyInstanceUid), processor.FailureException); } _destinationStudyStorage = command.Location; } }
public static WebEditStudyHistoryRecord ReadEditRecord(StudyHistory historyRecord) { Platform.CheckTrue(historyRecord.StudyHistoryTypeEnum == StudyHistoryTypeEnum.WebEdited || historyRecord.StudyHistoryTypeEnum == StudyHistoryTypeEnum.ExternalEdit, "History record has invalid history record type"); WebEditStudyHistoryRecord record = new WebEditStudyHistoryRecord { InsertTime = historyRecord.InsertTime, StudyStorageLocation = StudyStorageLocation.FindStorageLocations( StudyStorage.Load(historyRecord.StudyStorageKey))[0], UpdateDescription = XmlUtils.Deserialize <WebEditStudyHistoryChangeDescription>( historyRecord.ChangeDescription) }; return(record); }
protected override void OnExecute(CommandProcessor theProcessor) { Platform.CheckForNullReference(Context, "Context"); _destinationStudyStorage = Context.History.DestStudyStorageKey != null ? StudyStorageLocation.FindStorageLocations(StudyStorage.Load(Context.History.DestStudyStorageKey))[0] : Context.WorkQueueItemStudyStorage; EnsureStudyCanBeUpdated(_destinationStudyStorage); if (_updateDestination) { UpdateExistingStudy(); } LoadMergedStudyEntities(); try { LoadUidMappings(); if (Context.WorkQueueUidList.Count > 0) { ProcessUidList(); LogResult(); } } finally { UpdateHistory(_destinationStudyStorage); } if (_complete) { StudyRulesEngine engine = new StudyRulesEngine(_destinationStudyStorage, Context.Partition); engine.Apply(ServerRuleApplyTimeEnum.StudyProcessed, theProcessor); } }
private AutoReconcilerResult ProcessImageAsIs(DicomFile file, StudyHistory lastHistory) { StudyStorage destinationStudy = StudyStorage.Load(lastHistory.DestStudyStorageKey); StudyStorageLocation destStudy; AutoReconcilerResult preProcessingResult = new AutoReconcilerResult(StudyReconcileAction.ProcessAsIs); //Load the destination. An exception will be thrown if any issues are encountered. FilesystemMonitor.Instance.GetWritableStudyStorageLocation(destinationStudy.ServerPartitionKey, destinationStudy.StudyInstanceUid, StudyRestore.True, StudyCache.True, out destStudy); bool belongsToAnotherStudy = !destStudy.Equals(StorageLocation); EnsureStudyCanBeUpdated(destStudy); if (belongsToAnotherStudy) { preProcessingResult.Changes = new List <UpdateItem> { new UpdateItem(DicomTags.StudyInstanceUid, file.DataSet[DicomTags.StudyInstanceUid].ToString(), destStudy.StudyInstanceUid) }; file.DataSet[DicomTags.StudyInstanceUid].SetStringValue(destStudy.StudyInstanceUid); SopInstanceImporterContext importContext = new SopInstanceImporterContext( _contextID, file.SourceApplicationEntityTitle, destStudy.ServerPartition); SopInstanceImporter importer = new SopInstanceImporter(importContext); DicomProcessingResult result = importer.Import(file); if (!result.Successful) { throw new ApplicationException("Unable to import image to destination study"); } } return(preProcessingResult); }
private static WorkQueueAlertContextData GetWorkQueueContextData(Model.WorkQueue item) { Platform.CheckForNullReference(item, "item"); WorkQueueAlertContextData contextData = new WorkQueueAlertContextData { WorkQueueItemKey = item.Key.Key.ToString() }; StudyStorage storage = StudyStorage.Load(item.StudyStorageKey); IList <StudyStorageLocation> locations = StudyStorageLocation.FindStorageLocations(storage); if (locations != null && locations.Count > 0) { StudyStorageLocation location = locations[0]; if (location != null) { contextData.ValidationStudyInfo = new ValidationStudyInfo { StudyInstaneUid = location.StudyInstanceUid }; // study info is not always available (eg, when all images failed to process) if (location.Study != null) { contextData.ValidationStudyInfo.AccessionNumber = location.Study.AccessionNumber; contextData.ValidationStudyInfo.PatientsId = location.Study.PatientId; contextData.ValidationStudyInfo.PatientsName = location.Study.PatientsName; contextData.ValidationStudyInfo.ServerAE = location.ServerPartition.AeTitle; contextData.ValidationStudyInfo.StudyDate = location.Study.StudyDate; } } } return(contextData); }
private void LoadMergedStudyEntities() { StudyStorage storage = StudyStorage.Load(_destinationStudyStorage.Key); _destinationStudyStorage = StudyStorageLocation.FindStorageLocations(storage)[0]; }
/// <summary> /// Do the restore. /// </summary> /// <param name="queueItem">The queue item to restore.</param> public void Run(RestoreQueue queueItem) { using (RestoreProcessorContext context = new RestoreProcessorContext(queueItem)) { try { // Load up related classes. using (IReadContext readContext = _nasArchive.PersistentStore.OpenReadContext()) { _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey); _serverSyntax = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey); _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { StudyStorageKey = queueItem.StudyStorageKey }; IQueryStudyStorageLocation broker = readContext.GetBroker <IQueryStudyStorageLocation>(); _location = broker.FindOne(parms); if (_location == null) { _studyStorage = StudyStorage.Load(readContext, queueItem.StudyStorageKey); if (_studyStorage == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "Unable to find storage location, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "Unable to find storage location, rescheduling request."; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } } } if (_location == null) { Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}", _studyStorage.StudyInstanceUid); } else { Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid); } // If restoring a Nearline study, select a filesystem string destinationFolder; if (_location == null) { ServerFilesystemInfo fs = _nasArchive.Selector.SelectFilesystem(); if (fs == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "No writeable filesystem for restore, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "No writeable filesystem for restore, rescheduling request."; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } destinationFolder = Path.Combine(fs.Filesystem.FilesystemPath, _nasArchive.ServerPartition.PartitionFolder); } else { destinationFolder = _location.GetStudyPath(); } // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder = String.Empty; string filename = String.Empty; string studyInstanceUid = String.Empty; XmlElement element = _archiveStudyStorage.ArchiveXml.DocumentElement; if (element != null) { foreach (XmlElement node in element.ChildNodes) { if (node.Name.Equals("StudyFolder")) { studyFolder = node.InnerText; } else if (node.Name.Equals("Filename")) { filename = node.InnerText; } else if (node.Name.Equals("Uid")) { studyInstanceUid = node.InnerText; } } } string zipFile = Path.Combine(_nasArchive.NasPath, studyFolder); zipFile = Path.Combine(zipFile, studyInstanceUid); zipFile = Path.Combine(zipFile, filename); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. try { FileStream stream = File.OpenRead(zipFile); // Read a byte, just in case that makes a difference. stream.ReadByte(); stream.Close(); stream.Dispose(); } catch (Exception ex) { DateTime scheduledTime = Platform.Time.AddSeconds(NasSettings.Default.ReadFailRescheduleDelaySeconds); Platform.Log(LogLevel.Error, ex, "Archive {0} for Study {1} is unreadable, rescheduling restore to {2}", zipFile, _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, scheduledTime); // Just reschedule in "Restoring" state, the file is unreadable. _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Restoring, scheduledTime); return; } if (_location == null) { RestoreNearlineStudy(queueItem, zipFile, destinationFolder, studyFolder); } else { RestoreOnlineStudy(queueItem, zipFile, destinationFolder); } } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, _nasArchive.PartitionArchive.Description); queueItem.FailureDescription = e.Message; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } } }
private void LoadEntities() { _storage = StudyStorage.Load(_oldStudyLocation.Key); _study = _storage.LoadStudy(UpdateContext); }
/// <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(); } } }
private AutoReconcilerResult MergeImage(StudyReconcileAction action, DicomFile file, StudyHistory lastHistory) { string originalSeriesUid = file.DataSet[DicomTags.SeriesInstanceUid].ToString(); string originalSopUid = file.DataSet[DicomTags.SopInstanceUid].ToString(); AutoReconcilerResult preProcessingResult = null; StudyStorageLocation destStudy; UidMapper uidMapper = null; if (lastHistory.DestStudyStorageKey != null) { StudyStorage destinationStudy = StudyStorage.Load(lastHistory.DestStudyStorageKey); //Load the destination. An exception will be thrown if any issues are encountered. FilesystemMonitor.Instance.GetWritableStudyStorageLocation(destinationStudy.ServerPartitionKey, destinationStudy.StudyInstanceUid, StudyRestore.True, StudyCache.True, out destStudy); EnsureStudyCanBeUpdated(destStudy); bool belongsToAnotherStudy = !destStudy.Equals(StorageLocation); ImageUpdateCommandBuilder commandBuilder = new ImageUpdateCommandBuilder(); IList <BaseImageLevelUpdateCommand> commands = commandBuilder.BuildCommands <StudyMatchingMap>(destStudy); if (belongsToAnotherStudy) { Platform.Log(LogLevel.Info, "AUTO-RECONCILE: Move SOP {0} to Study {1}, A#: {2}, Patient {3}", originalSopUid, destStudy.StudyInstanceUid, destStudy.Study.AccessionNumber, destStudy.Study.PatientsName); // Load the Uid Map, either from cache or from disk if (!_uidMapCache.TryGetValue(destStudy.Key, out uidMapper)) { UidMapXml mapXml = new UidMapXml(); mapXml.Load(destStudy); uidMapper = new UidMapper(mapXml); _uidMapCache.Add(destStudy.Key, uidMapper); } try { commands.Add(GetUidMappingCommand(StorageLocation, destStudy, uidMapper, originalSopUid, originalSeriesUid)); } catch (InstanceAlreadyExistsException ex) { Platform.Log(LogLevel.Info, "An instance already exists with the SOP Instance Uid {0}", ex.SopInstanceUid); preProcessingResult = new AutoReconcilerResult(StudyReconcileAction.Discard) { DiscardImage = true }; return(preProcessingResult); } } preProcessingResult = new AutoReconcilerResult(action) { Changes = GetUpdateList(file, commands) }; UpdateImage(file, commands); // First, must update the map if (uidMapper != null && uidMapper.Dirty) { UpdateUidMap(destStudy, uidMapper); } if (belongsToAnotherStudy) { SopInstanceImporterContext importContext = new SopInstanceImporterContext(_contextID, file.SourceApplicationEntityTitle, destStudy.ServerPartition); SopInstanceImporter importer = new SopInstanceImporter(importContext); DicomProcessingResult result = importer.Import(file); if (!result.Successful) { throw new ApplicationException(result.ErrorMessage); } } } return(preProcessingResult); }
/// <summary> /// Do the restore. /// </summary> /// <param name="queueItem">The queue item to restore.</param> public void Run(RestoreQueue queueItem) { using (var context = new RestoreProcessorContext(queueItem)) { try { // Load up related classes. using (IReadContext readContext = _hsmArchive.PersistentStore.OpenReadContext()) { _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey); _serverSyntax = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey); _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid); var parms = new StudyStorageLocationQueryParameters { StudyStorageKey = queueItem.StudyStorageKey }; var broker = readContext.GetBroker <IQueryStudyStorageLocation>(); _location = broker.FindOne(parms); if (_location == null) { _studyStorage = StudyStorage.Load(readContext, queueItem.StudyStorageKey); if (_studyStorage == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "Unable to find storage location, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "Unable to find storage location, rescheduling request."; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } } } if (_location == null) { Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}", _studyStorage.StudyInstanceUid); // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder; string zipFile = GetZipFileName(out studyFolder); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. if (!CanReadZip(zipFile, queueItem)) { return; } RestoreNearlineStudy(queueItem, zipFile, studyFolder); } else { Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid); // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder; string zipFile = GetZipFileName(out studyFolder); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. if (!CanReadZip(zipFile, queueItem)) { return; } RestoreOnlineStudy(queueItem, zipFile, _location.GetStudyPath()); } } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, _hsmArchive.PartitionArchive.Description); queueItem.FailureDescription = e.Message; _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } } }
/// <summary> /// Returns an instance of <see cref="StudySummary"/> based on a <see cref="Study"/> object. /// </summary> /// <param name="study"></param> /// <param name="read"></param> /// <returns></returns> /// <remark> /// /// </remark> static public StudySummary CreateStudySummary(IPersistenceContext read, Study study) { if (study == null) { return(null); } var studySummary = new StudySummary(); var controller = new StudyController(); studySummary.TheStudy = study; studySummary.Key = study.GetKey(); studySummary.AccessionNumber = study.AccessionNumber; studySummary.NumberOfStudyRelatedInstances = study.NumberOfStudyRelatedInstances; studySummary.NumberOfStudyRelatedSeries = study.NumberOfStudyRelatedSeries; studySummary.PatientId = study.PatientId; studySummary.PatientsName = study.PatientsName; studySummary.StudyDate = study.StudyDate; studySummary.StudyInstanceUid = study.StudyInstanceUid; studySummary.StudyDescription = study.StudyDescription; studySummary.ModalitiesInStudy = controller.GetModalitiesInStudy(read, study); studySummary.ReferringPhysiciansName = study.ReferringPhysiciansName; studySummary.ResponsibleOrganization = study.ResponsibleOrganization; studySummary.ResponsiblePerson = study.ResponsiblePerson; studySummary.StudyTime = study.StudyTime; studySummary.StudyId = study.StudyId; studySummary.HasOrder = study.OrderKey != null; if (study.OrderKey != null) { var order = Order.Load(study.OrderKey); studySummary.OrderRequiresQC = order.QCExpected; studySummary.StudyIsQCed = (study.QCStatusEnum != null && study.QCStatusEnum != QCStatusEnum.NA); } studySummary.ThePartition = ServerPartitionMonitor.Instance.FindPartition(study.ServerPartitionKey) ?? ServerPartition.Load(read, study.ServerPartitionKey); studySummary.ReferringPhysiciansName = study.ReferringPhysiciansName; studySummary.TheStudyStorage = StudyStorage.Load(read, study.StudyStorageKey); studySummary.StudyStatusEnum = studySummary.TheStudyStorage.StudyStatusEnum; studySummary.QueueStudyStateEnum = studySummary.TheStudyStorage.QueueStudyStateEnum; studySummary.TheArchiveLocation = controller.GetFirstArchiveStudyStorage(read, studySummary.TheStudyStorage.Key); studySummary.IsArchiving = controller.GetArchiveQueueCount(study) > 0; studySummary.IsProcessing = studySummary.TheStudyStorage.WriteLock; // the study is considered "locked" if it's being processed or some action which requires the lock has been scheduled // No additional action should be allowed on the study until everything is completed. studySummary.IsLocked = studySummary.IsProcessing || (studySummary.TheStudyStorage.QueueStudyStateEnum != QueueStudyStateEnum.Idle); if (controller.GetStudyIntegrityQueueCount(studySummary.TheStudyStorage.Key) > 0) { studySummary.IsReconcileRequired = true; } studySummary.HasPendingExternalEdit = controller.GetCountPendingExternalEditWorkQueueItems(study) > 0; if (studySummary.HasPendingExternalEdit) { studySummary.HasPendingWorkQueueItems = true; } else { studySummary.HasPendingWorkQueueItems = controller.GetCountPendingWorkQueueItems(study) > 0; } var ep = new StudySummaryAssemblerExtensionPoint(); foreach (IStudySummaryAssembler assemblerPlugin in ep.CreateExtensions()) { assemblerPlugin.PopulateStudy(studySummary, study); } return(studySummary); }
public StudyStorage GetStudyStorage(Study study) { Platform.CheckForNullReference(study, "Study"); return(StudyStorage.Load(study.StudyStorageKey)); }