private void LoadStudyXml(bool throwIfNotExists) { if (_studyXml == null) { if (StudyXmlUri == null) { throw new DataStoreException("The study xml location must be set."); } XmlDocument doc = new XmlDocument(); _studyXml = new StudyXml(StudyInstanceUid); if (File.Exists(StudyXmlUri.LocalDiskPath)) { using (FileStream stream = GetFileStream(FileMode.Open, FileAccess.Read)) { StudyXmlIo.Read(doc, stream); _studyXml.SetMemento(doc); } } else if (throwIfNotExists) { throw new FileNotFoundException("The study xml file could not be found", StudyXmlUri.LocalDiskPath); } } }
/// <summary> /// Convert Uids into SopInstance /// </summary> /// <returns></returns> protected virtual IEnumerable <StorageInstance> GetStorageInstanceList() { string studyPath = StorageLocation.GetStudyPath(); StudyXml studyXml = LoadStudyXml(StorageLocation); Dictionary <string, StorageInstance> list = new Dictionary <string, StorageInstance>(); foreach (WorkQueueUid uid in WorkQueueUidList) { if (list.ContainsKey(uid.SopInstanceUid)) { Platform.Log(LogLevel.Warn, "AutoRoute WorkQueueUid {0} is a duplicate.", uid.Key); continue; // duplicate;} } SeriesXml seriesXml = studyXml[uid.SeriesInstanceUid]; InstanceXml instanceXml = seriesXml[uid.SopInstanceUid]; string seriesPath = Path.Combine(studyPath, uid.SeriesInstanceUid); string instancePath = Path.Combine(seriesPath, uid.SopInstanceUid + ServerPlatform.DicomFileExtension); StorageInstance instance = new StorageInstance(instancePath) { SopClass = instanceXml.SopClass, TransferSyntax = instanceXml.TransferSyntax, SopInstanceUid = instanceXml.SopInstanceUid, StudyInstanceUid = studyXml.StudyInstanceUid, PatientId = studyXml.PatientId, PatientsName = studyXml.PatientsName }; list.Add(uid.SopInstanceUid, instance); } return(list.Values); }
/// <summary> /// Constructor /// </summary> /// <param name="zipFile">The path of the zip file to create</param> /// <param name="studyXml">The <see cref="StudyXml"/> file describing the contents of the study.</param> /// <param name="studyFolder">The folder the study is stored in.</param> /// <param name="tempFolder">The folder for tempory files when creating the zip file.</param> public CreateStudyZipCommand(string zipFile, StudyXml studyXml, string studyFolder, string tempFolder) : base("Create study zip file",true) { _zipFile = zipFile; _studyXml = studyXml; _studyFolder = studyFolder; _tempFolder = tempFolder; }
private void AddDuplicateToStudy(DicomFile duplicateDicomFile, WorkQueueUid uid, ProcessDuplicateAction action) { var context = new StudyProcessorContext(StorageLocation, WorkQueueItem); var sopInstanceProcessor = new SopInstanceProcessor(context) { EnforceNameRules = true }; string group = uid.GroupID ?? ServerHelper.GetUidGroup(duplicateDicomFile, ServerPartition, WorkQueueItem.InsertTime); StudyXml studyXml = StorageLocation.LoadStudyXml(); int originalInstanceCount = studyXml.NumberOfStudyRelatedInstances; bool compare = action != ProcessDuplicateAction.OverwriteAsIs; // NOTE: "compare" has no effect for OverwriteUseExisting or OverwriteUseDuplicate // because in both cases, the study and the duplicates are modified to be the same. ProcessingResult result = sopInstanceProcessor.ProcessFile(group, duplicateDicomFile, studyXml, compare, true, uid, duplicateDicomFile.Filename, SopInstanceProcessorSopType.UpdatedSop); if (result.Status == ProcessingStatus.Reconciled) { throw new ApplicationException("Unexpected status of Reconciled image in duplicate handling!"); } Debug.Assert(studyXml.NumberOfStudyRelatedInstances == originalInstanceCount + 1); Debug.Assert(File.Exists(StorageLocation.GetSopInstancePath(uid.SeriesInstanceUid, uid.SopInstanceUid))); }
public void TestSopClass() { List<DicomFile> images = SetupImages(4); string seriesUid = images[0].DataSet[DicomTags.SeriesInstanceUid].ToString(); images[0].MediaStorageSopClassUid = SopClass.EnhancedCtImageStorageUid; images[1].MediaStorageSopClassUid = SopClass.EnhancedMrImageStorageUid; images[2].MediaStorageSopClassUid = SopClass.EnhancedSrStorageUid; images[3].MediaStorageSopClassUid = SopClass.EnhancedXaImageStorageUid; StudyXml xml = new StudyXml(); foreach (DicomFile file in images) xml.AddFile(file); XmlDocument doc = xml.GetMemento(new StudyXmlOutputSettings()); Assert.AreEqual(xml[seriesUid][images[0].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedCtImageStorageUid); Assert.AreEqual(xml[seriesUid][images[1].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedMrImageStorageUid); Assert.AreEqual(xml[seriesUid][images[2].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedSrStorageUid); Assert.AreEqual(xml[seriesUid][images[3].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedXaImageStorageUid); xml = new StudyXml(); xml.SetMemento(doc); Assert.AreEqual(xml[seriesUid][images[0].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedCtImageStorageUid); Assert.AreEqual(xml[seriesUid][images[1].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedMrImageStorageUid); Assert.AreEqual(xml[seriesUid][images[2].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedSrStorageUid); Assert.AreEqual(xml[seriesUid][images[3].DataSet[DicomTags.SopInstanceUid]].SopClass.Uid, SopClass.EnhancedXaImageStorageUid); }
/// <summary> /// Validates the state of the study. /// </summary> /// <param name="context">Name of the application</param> /// <param name="studyStorage">The study to validate</param> /// <param name="modes">Specifying what validation to execute</param> public void ValidateStudyState(String context, StudyStorageLocation studyStorage, StudyIntegrityValidationModes modes) { Platform.CheckForNullReference(studyStorage, "studyStorage"); if (modes == StudyIntegrityValidationModes.None) { return; } using (var scope = new ServerExecutionContext()) { // Force a re-load, the study may have changed if a delete happened. Study study = Study.Find(scope.PersistenceContext, studyStorage.Key); if (study != null) { StudyXml studyXml = studyStorage.LoadStudyXml(); if (modes == StudyIntegrityValidationModes.Default || (modes & StudyIntegrityValidationModes.InstanceCount) == StudyIntegrityValidationModes.InstanceCount) { if (studyXml != null && studyXml.NumberOfStudyRelatedInstances != study.NumberOfStudyRelatedInstances) { var validationStudyInfo = new ValidationStudyInfo(study, studyStorage.ServerPartition); throw new StudyIntegrityValidationFailure( ValidationErrors.InconsistentObjectCount, validationStudyInfo, String.Format("Number of instances in database and xml do not match: {0} vs {1}.", study.NumberOfStudyRelatedInstances, studyXml.NumberOfStudyRelatedInstances )); } } } } }
public StudyRulesEngine(ServerRulesEngine studyRulesEngine, StudyStorageLocation location, ServerPartition partition, StudyXml studyXml) { _studyRulesEngine = studyRulesEngine; _studyXml = studyXml; _location = location; _partition = partition ?? ServerPartition.Load(_location.ServerPartitionKey); }
private void DoStudyLevelValidation(StudyStorageLocation storageLocation, StudyXml studyXml, Study study, ServerPartition partition) { int xmlNumInstances = studyXml.NumberOfStudyRelatedInstances; int xmlNumSeries = studyXml.NumberOfStudyRelatedSeries; if (study.NumberOfStudyRelatedInstances != xmlNumInstances) { throw new StudyIntegrityValidationFailure( ValidationErrors.InconsistentObjectCount, new ValidationStudyInfo(study, partition), String.Format("Number of study related instances in the database ({0}) does not match number of images in the filesystem ({1})", study.NumberOfStudyRelatedInstances, xmlNumInstances)); } if (study.NumberOfStudyRelatedSeries != xmlNumSeries) { throw new StudyIntegrityValidationFailure(ValidationErrors.InconsistentObjectCount, new ValidationStudyInfo(study, partition), String.Format("Number of study related series in the database ({0}) does not match number of series in the xml ({1})", study.NumberOfStudyRelatedSeries, xmlNumSeries)); } long dirFileCount = DirectoryUtility.Count(storageLocation.GetStudyPath(), "*" + ServerPlatform.DicomFileExtension, true, null); if (xmlNumInstances != dirFileCount) { throw new StudyIntegrityValidationFailure(ValidationErrors.InconsistentObjectCount, new ValidationStudyInfo(study, partition), String.Format("Number of instance in xml ({0}) does not match number of images in the filesystem ({1})", xmlNumInstances, dirFileCount)); } }
/// <summary> /// ProcessSavedFile all of the SOP Instances associated with a <see cref="WorkQueue"/> item. /// </summary> /// <param name="item">The <see cref="WorkQueue"/> item.</param> /// <returns>Number of instances that have been processed successfully.</returns> private int ProcessUidList(Model.WorkQueue item) { StudyXml studyXml = LoadStudyXml(StorageLocation); int successfulProcessCount = 0; foreach (WorkQueueUid sop in WorkQueueUidList) { if (sop.Failed) { continue; } if (CancelPending) { Platform.Log(LogLevel.Info, "Processing of study canceled for shutdown: {0}", StorageLocation.StudyInstanceUid); return(successfulProcessCount); } if (ProcessWorkQueueUid(item, sop, studyXml)) { successfulProcessCount++; } } return(successfulProcessCount); }
protected override int OnStart(StudyLoaderArgs studyLoaderArgs) { var serverAe = studyLoaderArgs.Server; Platform.CheckForNullReference(serverAe, "Server"); Platform.CheckMemberIsSet(serverAe.StreamingParameters, "StreamingParameters"); _serverAe = serverAe; EventResult result = EventResult.Success; AuditedInstances loadedInstances = new AuditedInstances(); try { StudyXml studyXml = RetrieveStudyXml(studyLoaderArgs); _instances = GetInstances(studyXml).GetEnumerator(); loadedInstances.AddInstance(studyXml.PatientId, studyXml.PatientsName, studyXml.StudyInstanceUid); return(studyXml.NumberOfStudyRelatedInstances); } finally { AuditHelper.LogOpenStudies(new string[] { _serverAe.AETitle }, loadedInstances, EventSource.CurrentUser, result); } }
/// <summary> /// Load the first instance from the first series of the StudyXml file for a study. /// </summary> /// <param name="location">The storage location of the study.</param> /// <returns></returns> protected static DicomFile LoadInstance(StudyStorageLocation location) { string studyXml = Path.Combine(location.GetStudyPath(), location.StudyInstanceUid + ".xml"); if (!File.Exists(studyXml)) { return null; } FileStream stream = FileStreamOpener.OpenForRead(studyXml, FileMode.Open); var theDoc = new XmlDocument(); StudyXmlIo.Read(theDoc, stream); stream.Close(); stream.Dispose(); var xml = new StudyXml(); xml.SetMemento(theDoc); IEnumerator<SeriesXml> seriesEnumerator = xml.GetEnumerator(); if (seriesEnumerator.MoveNext()) { SeriesXml seriesXml = seriesEnumerator.Current; IEnumerator<InstanceXml> instanceEnumerator = seriesXml.GetEnumerator(); if (instanceEnumerator.MoveNext()) { InstanceXml instance = instanceEnumerator.Current; var file = new DicomFile("file.dcm",new DicomAttributeCollection(), instance.Collection) {TransferSyntax = instance.TransferSyntax}; return file; } } return null; }
/// <summary> /// Gets the <see cref="StudyXml"/> if it exists in this storage location. /// </summary> /// <remarks> /// </remarks> /// <returns></returns> public StudyXml LoadStudyXml() { // TODO: Use FileStreamOpener instead // Can't do it until we break the dependency of ImageServer.Common on Model if (_studyXml == null) { lock (SyncRoot) { try { Stream xmlStream = Open(GetStudyXmlPath()); if (xmlStream != null) { XmlDocument xml = new XmlDocument(); using (xmlStream) { StudyXmlIo.Read(xml, xmlStream); xmlStream.Close(); } _studyXml = new StudyXml(); _studyXml.SetMemento(xml); } } catch (Exception) { } } } return(_studyXml); }
protected Study CreateTestStudy1() { var studyUid = "1.2.3"; var sops = base.SetupMRSeries(4, 5, studyUid); var xml = new StudyXml(studyUid); var seriesUids = new Dictionary <string, string>(); var seriesModalities = new Dictionary <string, string>(); var modalities = new[] { "MR", "MR", "SC", "KO" }; foreach (var sop in sops) { //Make the UIDs constant. var seriesUid = sop[DicomTags.SeriesInstanceUid].ToString(); if (!seriesUids.ContainsKey(seriesUid)) { seriesModalities[seriesUid] = modalities[seriesUids.Count]; seriesUids[seriesUid] = string.Format("1.2.3.{0}", seriesUids.Count + 1); } var modality = seriesModalities[seriesUid]; seriesUid = seriesUids[seriesUid]; sop[DicomTags.SeriesInstanceUid].SetString(0, seriesUid); sop[DicomTags.Modality].SetString(0, modality); var file = new DicomFile("", new DicomAttributeCollection(), sop); xml.AddFile(file); } var study = new Study(); study.Update(xml); return(study); }
public RemoveInstanceFromStudyXmlCommand(StudyStorageLocation location, StudyXml studyXml, DicomFile file) :base("Remove Instance From Study Xml", true) { _studyLocation = location; _file = file; _studyXml = studyXml; }
public RemoveSeriesFromStudyXml(StudyXml studyXml, string seriesUid) : base(String.Format("Remove series {0} from study XML of study {1}", seriesUid, studyXml.StudyInstanceUid), true) { _studyXml = studyXml; _seriesUid = seriesUid; _studyInstanceUid = studyXml.StudyInstanceUid; }
/// <summary> /// Gets the list of instances to be sent from the study xml /// </summary> /// <returns></returns> protected override IEnumerable <StorageInstance> GetStorageInstanceList() { Platform.CheckForNullReference(StorageLocation, "StorageLocation"); var list = new List <StorageInstance>(); string studyPath = StorageLocation.GetStudyPath(); StudyXml studyXml = LoadStudyXml(StorageLocation); foreach (SeriesXml seriesXml in studyXml) { foreach (InstanceXml instanceXml in seriesXml) { string seriesPath = Path.Combine(studyPath, seriesXml.SeriesInstanceUid); string instancePath = Path.Combine(seriesPath, instanceXml.SopInstanceUid + ServerPlatform.DicomFileExtension); var instance = new StorageInstance(instancePath) { SopClass = instanceXml.SopClass, TransferSyntax = instanceXml.TransferSyntax, SopInstanceUid = instanceXml.SopInstanceUid, StudyInstanceUid = studyXml.StudyInstanceUid, SeriesInstanceUid = seriesXml.SeriesInstanceUid, PatientId = studyXml.PatientId, PatientsName = studyXml.PatientsName }; list.Add(instance); } } return(list); }
public RemoveInstanceFromStudyXmlCommand(StudyStorageLocation location, StudyXml studyXml, DicomFile file) : base("Remove Instance From Study Xml", true) { _studyLocation = location; _file = file; _studyXml = studyXml; }
protected Study CreateTestStudy1() { var studyUid = "1.2.3"; var sops = base.SetupMRSeries(4, 5, studyUid); var xml = new StudyXml(studyUid); var seriesUids = new Dictionary<string, string>(); var seriesModalities = new Dictionary<string, string>(); var modalities = new[] { "MR", "MR", "SC", "KO" }; foreach (var sop in sops) { //Make the UIDs constant. var seriesUid = sop[DicomTags.SeriesInstanceUid].ToString(); if (!seriesUids.ContainsKey(seriesUid)) { seriesModalities[seriesUid] = modalities[seriesUids.Count]; seriesUids[seriesUid] = string.Format("1.2.3.{0}", seriesUids.Count + 1); } var modality = seriesModalities[seriesUid]; seriesUid = seriesUids[seriesUid]; sop[DicomTags.SeriesInstanceUid].SetString(0, seriesUid); sop[DicomTags.Modality].SetString(0, modality); var file = new DicomFile("", new DicomAttributeCollection(), sop); xml.AddFile(file); } var study = new Study(); study.Update(xml); return study; }
public void StudyXmlTest() { string directory; using (var processor = new TestCommandProcessor()) { var studyXml = new StudyXml(DicomUid.GenerateUid().UID); var images = SetupMRSeries(2, 5, studyXml.StudyInstanceUid); directory = Path.Combine(processor.ProcessorContext.TempDirectory, "StudyXmlTest"); DirectoryUtility.DeleteIfExists(directory); processor.AddCommand(new CreateDirectoryCommand(directory)); foreach (var i in images) { string file = Path.Combine(directory, i[DicomTags.SopInstanceUid] + ".dcm"); processor.AddCommand(new SaveDicomFileCommand(file, new DicomFile(file, new DicomAttributeCollection(), i), false)); processor.AddCommand(new InsertInstanceXmlCommand(studyXml, file)); } Assert.IsTrue(processor.Execute(), processor.FailureReason); Assert.IsTrue((images.Count * 2 + 1) == processor.TestContext.CommandsExecuted); foreach (var i in images) { Assert.IsTrue(studyXml.Contains(i[DicomTags.SeriesInstanceUid], i[DicomTags.SopInstanceUid])); } DirectoryUtility.DeleteIfExists(directory); } }
protected override void OnExecute(CommandProcessor theProcessor) { StudyXml currentXml = LoadStudyXml(); _newXml = new StudyXml(_studyInstanceUid); foreach (SeriesXml series in currentXml) { string seriesPath = Path.Combine(_rootPath, series.SeriesInstanceUid); if (!Directory.Exists(seriesPath)) { Platform.Log(LogLevel.Info, "RebuildXML: series folder {0} is missing", seriesPath); continue; } foreach (InstanceXml instance in series) { string instancePath = Path.Combine(seriesPath, instance.SopInstanceUid + ServerPlatform.DicomFileExtension); if (!File.Exists(instancePath)) { Platform.Log(LogLevel.Info, "RebuildXML: file {0} is missing", instancePath); } else { if (!theProcessor.ExecuteSubCommand(this, new InsertInstanceXmlCommand(_newXml, instancePath))) throw new ApplicationException(theProcessor.FailureReason); } } } if (!theProcessor.ExecuteSubCommand(this, new SaveXmlCommand(_newXml, _rootPath, _studyInstanceUid))) throw new ApplicationException(theProcessor.FailureReason); }
public void ConstructorTest() { StudyXml stream = new StudyXml(); stream = new StudyXml("1.1.1"); }
/// <summary> /// Load all of the instances in a given <see cref="StudyXml"/> file into the component for sending. /// </summary> /// <param name="location"></param> /// <param name="studyXml">The <see cref="StudyXml"/> file to load from</param> public void LoadStudyFromStudyXml(StudyLocation location, StudyXml studyXml) { foreach (SeriesXml seriesXml in studyXml) { LoadSeriesFromSeriesXml(studyXml, location, seriesXml, studyXml.PatientsName, studyXml.PatientId); } }
/// <summary> /// Constructor /// </summary> /// <param name="zipFile">The path of the zip file to create</param> /// <param name="studyXml">The <see cref="StudyXml"/> file describing the contents of the study.</param> /// <param name="studyFolder">The folder the study is stored in.</param> /// <param name="tempFolder">The folder for tempory files when creating the zip file.</param> public CreateStudyZipCommand(string zipFile, StudyXml studyXml, string studyFolder, string tempFolder) : base("Create study zip file", true) { _zipFile = zipFile; _studyXml = studyXml; _studyFolder = studyFolder; _tempFolder = tempFolder; }
public InsertOrUpdateStudyCommand(StudyLocation location, StudyXml xml, UpdateReason reason) : base("Insert or Update Study Command") { _studyInstanceUid = xml.StudyInstanceUid; _studyXml = xml; _reason = reason; _location = location; }
public void CreationTest() { IList<DicomAttributeCollection> instanceList; string studyInstanceUid = DicomUid.GenerateUid().UID; instanceList = SetupMRSeries(4, 10, studyInstanceUid); StudyXml studyXml = new StudyXml(studyInstanceUid); string studyXmlFilename = Path.GetTempFileName(); foreach (DicomAttributeCollection instanceCollection in instanceList) { instanceCollection[DicomTags.PixelData] = null; DicomFile theFile = new DicomFile("test", new DicomAttributeCollection(), instanceCollection); SetupMetaInfo(theFile); studyXml.AddFile(theFile); WriteStudyStream(studyXmlFilename, studyXml); } StudyXml newXml = LoadStudyStream(studyXmlFilename); if (!Compare(newXml, instanceList)) Assert.Fail("Comparison of StudyXML failed against base loaded from disk"); if (!Compare(studyXml, instanceList)) Assert.Fail("Comparison of StudyXML failed against base in memory"); }
/// <summary> /// Apply the rules. /// </summary> /// <remarks> /// When rules are applied, we are simply adding new <see cref="ServerDatabaseCommand"/> instances /// for the rules to the currently executing <see cref="ServerCommandProcessor"/>. They will be /// executed after all other rules have been executed. /// </remarks> protected override void OnExecute(CommandProcessor theProcessor) { string studyXmlFile = Path.Combine(_directory, String.Format("{0}.xml", _studyInstanceUid)); StudyXml theXml = new StudyXml(_studyInstanceUid); if (File.Exists(studyXmlFile)) { using (Stream fileStream = FileStreamOpener.OpenForRead(studyXmlFile, FileMode.Open)) { var theMemento = new StudyXmlMemento(); StudyXmlIo.Read(theMemento, fileStream); theXml.SetMemento(theMemento); fileStream.Close(); } } else { string errorMsg = String.Format("Unable to load study XML file of restored study: {0}", studyXmlFile); Platform.Log(LogLevel.Error, errorMsg); throw new ApplicationException(errorMsg); } DicomFile defaultFile = null; bool rulesExecuted = false; foreach (SeriesXml seriesXml in theXml) { foreach (InstanceXml instanceXml in seriesXml) { // Skip non-image objects if (instanceXml.SopClass.Equals(SopClass.KeyObjectSelectionDocumentStorage) || instanceXml.SopClass.Equals(SopClass.GrayscaleSoftcopyPresentationStateStorageSopClass) || instanceXml.SopClass.Equals(SopClass.BlendingSoftcopyPresentationStateStorageSopClass) || instanceXml.SopClass.Equals(SopClass.ColorSoftcopyPresentationStateStorageSopClass)) { // Save the first one encountered, just in case the whole study is non-image objects. if (defaultFile == null) defaultFile = new DicomFile("test", new DicomAttributeCollection(), instanceXml.Collection); continue; } DicomFile file = new DicomFile("test", new DicomAttributeCollection(), instanceXml.Collection); _context.Message = file; _engine.Execute(_context); rulesExecuted = true; break; } if (rulesExecuted) break; } if (!rulesExecuted && defaultFile != null) { _context.Message = defaultFile; _engine.Execute(_context); } }
public RemoveInstanceFromStudyXmlCommand(StudyStorageLocation location, StudyXml studyXml, string seriesInstanceUid, string sopInstanceUid) : base("RemoveInstanceFromStudyXmlCommand", true) { _studyLocation = location; _seriesInstanceUid = seriesInstanceUid; _sopInstanceUid = sopInstanceUid; _studyXml = studyXml; }
public RemoveSopInstanceFromStudyXmlCommand(StudyXml studyXml, string seriesUid, string sopInstanceUid) : base(String.Format("Remove sop {0} from study XML of study {1}", sopInstanceUid, studyXml.StudyInstanceUid), true) { _studyXml = studyXml; _seriesUid = seriesUid; _sopInstanceUid = sopInstanceUid; _studyInstanceUid = studyXml.StudyInstanceUid; }
public Study(StudyXml xml, IDicomFileLoader dicomFileLoader) { _studyInstanceUid = xml.StudyInstanceUid; _xml = xml; _dicomFileLoader = dicomFileLoader; _seriesCollection = new SeriesCollection(this); _firstSopInstance = _seriesCollection.SelectMany(s => s.SopInstances).FirstOrDefault(); }
public InsertInstanceXmlCommand(StudyXml stream, string path) : base("Insert into Study XML", true) { Platform.CheckForNullReference(stream, "StudyStream object"); Platform.CheckForNullReference(path, "Path to DICOM File"); _stream = stream; _path = path; }
private bool ProcessWorkQueueUid(Model.WorkQueue item, WorkQueueUid sop, StudyXml studyXml, IDicomCodecFactory theCodecFactory) { Platform.CheckForNullReference(item, "item"); Platform.CheckForNullReference(sop, "sop"); Platform.CheckForNullReference(studyXml, "studyXml"); if (!studyXml.Contains(sop.SeriesInstanceUid, sop.SopInstanceUid)) { // Uid was inserted but not in the study xml. // Auto-recovery might have detect problem with that file and remove it from the study. // Assume the study xml has been corrected and ignore the uid. Platform.Log(LogLevel.Warn, "Skipping SOP {0} in series {1}. It is no longer part of the study.", sop.SopInstanceUid, sop.SeriesInstanceUid); // Delete it out of the queue DeleteWorkQueueUid(sop); return true; } string basePath = Path.Combine(StorageLocation.GetStudyPath(), sop.SeriesInstanceUid); basePath = Path.Combine(basePath, sop.SopInstanceUid); string path; if (sop.Extension != null) path = basePath + "." + sop.Extension; else path = basePath + ServerPlatform.DicomFileExtension; try { ProcessFile(item, sop, path, studyXml, theCodecFactory); // WorkQueueUid has been deleted out by the processor return true; } catch (Exception e) { if (e.InnerException != null && e.InnerException is DicomCodecUnsupportedSopException) { Platform.Log(LogLevel.Warn, e, "Instance not supported for compressor: {0}. Deleting WorkQueue entry for SOP {1}", e.Message, sop.SopInstanceUid); item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message; // Delete it out of the queue DeleteWorkQueueUid(sop); return false; } Platform.Log(LogLevel.Error, e, "Unexpected exception when compressing file: {0} SOP Instance: {1}", path, sop.SopInstanceUid); item.FailureDescription = e.InnerException != null ? e.InnerException.Message : e.Message; sop.FailureCount++; UpdateWorkQueueUid(sop); return false; } }
/// <summary> /// Get a list of paths to the first image in each series within the study being processed. /// </summary> /// <returns></returns> private List <string> GetFirstInstanceInEachStudySeries() { var fileList = new List <string>(); if (_studyXml == null) { string studyXml = _location.GetStudyXmlPath(); if (!File.Exists(studyXml)) { return(fileList); } _studyXml = new StudyXml(); using (FileStream stream = FileStreamOpener.OpenForRead(studyXml, FileMode.Open)) { var theDoc = new XmlDocument(); StudyXmlIo.Read(theDoc, stream); stream.Close(); _studyXml.SetMemento(theDoc); } } // Note, we try and force ourselves to have an uncompressed // image, if one exists. That way the rules will be reapplied on the object // if necessary for compression. foreach (SeriesXml seriesXml in _studyXml) { InstanceXml saveInstance = null; foreach (InstanceXml instance in seriesXml) { if (instance.TransferSyntax.Encapsulated) { if (saveInstance == null) { saveInstance = instance; } } else { saveInstance = instance; break; } } if (saveInstance != null) { string path = Path.Combine(_location.GetStudyPath(), seriesXml.SeriesInstanceUid); path = Path.Combine(path, saveInstance.SopInstanceUid + ServerPlatform.DicomFileExtension); fileList.Add(path); } } return(fileList); }
/// <summary> /// Load all of the instances in a given <see cref="StudyXml"/> file into the component for sending. /// </summary> /// <param name="studyPath"></param> /// <param name="studyXml">The <see cref="StudyXml"/> file to load from</param> public void LoadStudyFromStudyXml(string studyPath, StudyXml studyXml) { foreach (SeriesXml seriesXml in studyXml) { string seriesPath = Path.Combine(studyPath, seriesXml.SeriesInstanceUid); LoadSeriesFromSeriesXml(studyXml, seriesPath, seriesXml, studyXml.PatientsName, studyXml.PatientId); } }
private void WriteStudyStream(string streamFile, string gzStreamFile, StudyXml theStream) { XmlDocument doc = theStream.GetMemento(_outputSettings); // allocate the random number generator here, in case we need it below var rand = new Random(); string tmpStreamFile = streamFile + "_tmp"; string tmpGzStreamFile = gzStreamFile + "_tmp"; for (int i = 0; ; i++) { try { if (File.Exists(tmpStreamFile)) { FileUtils.Delete(tmpStreamFile); } if (File.Exists(tmpGzStreamFile)) { FileUtils.Delete(tmpGzStreamFile); } _fileSaved = true; using (FileStream xmlStream = FileStreamOpener.OpenForSoleUpdate(tmpStreamFile, FileMode.CreateNew), gzipStream = FileStreamOpener.OpenForSoleUpdate(tmpGzStreamFile, FileMode.CreateNew)) { StudyXmlIo.WriteXmlAndGzip(doc, xmlStream, gzipStream); xmlStream.Close(); gzipStream.Close(); } if (File.Exists(streamFile)) { FileUtils.Delete(streamFile); } File.Move(tmpStreamFile, streamFile); if (File.Exists(_gzPath)) { FileUtils.Delete(_gzPath); } File.Move(tmpGzStreamFile, _gzPath); return; } catch (IOException) { if (i < 5) { Thread.Sleep(rand.Next(5, 50)); // Sleep 5-50 milliseconds continue; } throw; } } }
private IEnumerable<InstanceXml> GetInstances(StudyXml studyXml) { foreach (SeriesXml seriesXml in studyXml) { foreach (InstanceXml instanceXml in seriesXml) { yield return instanceXml; } } }
/// <summary> /// Process a specific DICOM file which may be related to a <see cref="WorkItem"/> request. /// </summary> /// <remarks> /// <para> /// On success and if <see cref="uid"/> is set, the <see cref="WorkItemUid"/> field is marked as complete. If processing fails, /// the FailureCount field is incremented for the <see cref="WorkItemUid"/>. /// </para> /// </remarks> /// <param name="studyXml">The <see cref="StudyXml"/> file to update with information from the file.</param> /// <param name="file">The file to process.</param> /// <param name="uid">An optional WorkQueueUid associated with the entry, that will be deleted upon success or failed on failure.</param> /// <exception cref="ApplicationException"/> /// <exception cref="DicomDataException"/> public void ProcessFile(DicomFile file, StudyXml studyXml, WorkItemUid uid) { Platform.CheckForNullReference(file, "file"); Platform.CheckForNullReference(studyXml, "studyXml"); var processFile = new ProcessorFile(file, uid); InsertBatch(new List <ProcessorFile> { processFile }, studyXml); }
public SaveXmlCommand(StudyXml stream, StudyStorageLocation storageLocation) : base("Insert into Study XML", true) { Platform.CheckForNullReference(stream, "StudyStream object"); Platform.CheckForNullReference(storageLocation, "Study Storage Location"); _stream = stream; _xmlPath = Path.Combine(storageLocation.GetStudyPath(), storageLocation.StudyInstanceUid + ".xml"); _gzPath = _xmlPath + ".gz"; }
public UpdateStudySizeInDBCommand(StudyStorageLocation location) : base("Update Study Size In DB") { _location = location; // this may take a few ms so it's better to do it here instead in OnExecute() StudyXml studyXml = _location.LoadStudyXml(); _studySizeInKB = studyXml.GetStudySize() / KB; }
private IEnumerable <InstanceXml> GetInstances(StudyXml studyXml) { foreach (SeriesXml seriesXml in studyXml) { foreach (InstanceXml instanceXml in seriesXml) { yield return(instanceXml); } } }
public InsertStudyXmlCommand(DicomFile file, StudyXml stream, StudyStorageLocation storageLocation) : base("Insert into Study XML", true) { Platform.CheckForNullReference(file, "Dicom File object"); Platform.CheckForNullReference(stream, "StudyStream object"); Platform.CheckForNullReference(storageLocation, "Study Storage Location"); _file = file; _stream = stream; _studyStorageLocation = storageLocation; }
public SaveXmlCommand(StudyXml stream, string rootStudyPath, string studyInstanceUid) : base("Insert into Study XML", true) { Platform.CheckForNullReference(stream, "StudyStream object"); Platform.CheckForNullReference(rootStudyPath, "Study folder path"); Platform.CheckForNullReference(studyInstanceUid, "Study Instance Uid"); _stream = stream; _xmlPath = Path.Combine(rootStudyPath, studyInstanceUid + ".xml"); _gzPath = _xmlPath + ".gz"; }
/// <summary> /// Load all of the instances in a given <see cref="StudyXml"/> file into the component for sending. /// </summary> /// <param name="location"></param> /// <param name="seriesInstanceUid"></param> /// <param name="studyXml">The <see cref="StudyXml"/> file to load from</param> public void LoadSeriesFromStudyXml(StudyLocation location, StudyXml studyXml, string seriesInstanceUid) { foreach (SeriesXml seriesXml in studyXml) { if (seriesInstanceUid.Equals(seriesXml.SeriesInstanceUid)) { LoadSeriesFromSeriesXml(studyXml, location, seriesXml, studyXml.PatientsName, studyXml.PatientId); break; } } }
private void DoSeriesLevelValidation(StudyStorageLocation storageLocation, StudyXml studyXml, Study study) { IDictionary <string, Series> seriesList = study.Series; foreach (var entry in seriesList) { Series series = entry.Value; SeriesXml seriesXml = studyXml[series.SeriesInstanceUid]; ValidateSeries(storageLocation, series, seriesXml); } }
private void DoSeriesLevelValidation(StudyStorageLocation storageLocation, StudyXml studyXml, Study study) { IDictionary<string, Series> seriesList = study.Series; foreach (var entry in seriesList) { Series series = entry.Value; SeriesXml seriesXml = studyXml[series.SeriesInstanceUid]; ValidateSeries(storageLocation, series, seriesXml); } }
private void SaveStudyXml(StudyXml studyXml) { XmlDocument doc = studyXml.GetMemento(new StudyXmlOutputSettings()); using (FileStream xmlStream = FileStreamOpener.OpenForSoleUpdate(StorageLocation.GetStudyXmlPath(), FileMode.Create), gzipStream = FileStreamOpener.OpenForSoleUpdate(StorageLocation.GetCompressedStudyXmlPath(), FileMode.Create)) { StudyXmlIo.WriteXmlAndGzip(doc, xmlStream, gzipStream); xmlStream.Close(); gzipStream.Close(); } }
/// <summary> /// Load the StudyXml file. /// </summary> /// <param name="studyXmlFile"></param> public void LoadStudyXml(string studyXmlFile) { using (Stream fileStream = FileStreamOpener.OpenForRead(studyXmlFile, FileMode.Open)) { XmlDocument theDoc = new XmlDocument(); StudyXmlIo.Read(theDoc, fileStream); _studyXml = new StudyXml(_storageLocation.StudyInstanceUid); _studyXml.SetMemento(theDoc); fileStream.Close(); } }
public InsertStudyXmlCommand(DicomFile file, StudyXml studyXml, StudyLocation storageLocation, bool writeFile) : base("Insert Study Xml", true) { _file = file; _studyXml = studyXml; _studyStorageLocation = storageLocation; _writeFile = writeFile; _settings = new StudyXmlOutputSettings { IncludePrivateValues = StudyXmlTagInclusion.IgnoreTag, IncludeUnknownTags = StudyXmlTagInclusion.IgnoreTag, IncludeLargeTags = StudyXmlTagInclusion.IncludeTagExclusion, MaxTagLength = 2048, IncludeSourceFileName = true }; }
private void WriteStudyStream(string streamFile, StudyXml theStream) { StudyXmlOutputSettings settings = new StudyXmlOutputSettings(); settings.IncludeSourceFileName = false; XmlDocument doc = theStream.GetMemento(settings); if (File.Exists(streamFile)) File.Delete(streamFile); using (Stream fileStream = new FileStream(streamFile, FileMode.CreateNew)) { StudyXmlIo.Write(doc, fileStream); fileStream.Close(); } return; }
private void CreateSubCommands() { _archiveXml = new XmlDocument(); _studyXml = _storageLocation.LoadStudyXml(); string studyFolder = _storageLocation.GetStudyPath(); // Create the study date folder _zipFilename = Path.Combine(_hsmPath, _storageLocation.StudyFolder); AddSubCommand(new CreateDirectoryCommand(_zipFilename)); // Create a folder for the study _zipFilename = Path.Combine(_zipFilename, _storageLocation.StudyInstanceUid); AddSubCommand(new CreateDirectoryCommand(_zipFilename)); // Save the archive data in the study folder, based on a filename with a date / time stamp string filename = String.Format("{0}.zip", Platform.Time.ToString("yyyy-MM-dd-HHmm")); _zipFilename = Path.Combine(_zipFilename, filename); // Create the Xml data to store in the ArchiveStudyStorage table telling // where the archived study is located. XmlElement hsmArchiveElement = _archiveXml.CreateElement("HsmArchive"); _archiveXml.AppendChild(hsmArchiveElement); XmlElement studyFolderElement = _archiveXml.CreateElement("StudyFolder"); hsmArchiveElement.AppendChild(studyFolderElement); studyFolderElement.InnerText = _storageLocation.StudyFolder; XmlElement filenameElement = _archiveXml.CreateElement("Filename"); hsmArchiveElement.AppendChild(filenameElement); filenameElement.InnerText = filename; XmlElement studyInstanceUidElement = _archiveXml.CreateElement("Uid"); hsmArchiveElement.AppendChild(studyInstanceUidElement); studyInstanceUidElement.InnerText = _storageLocation.StudyInstanceUid; // Create the Zip file var zipStudyCommand = new CreateStudyZipCommand(_zipFilename, _studyXml, studyFolder, _tempPath) { ForceCompress = this.ForceCompress }; zipStudyCommand.ProgressUpdated += (s, e) => EventsHelper.Fire(this.ProgressUpdated, this, e); AddSubCommand(zipStudyCommand); // Update the database. AddSubCommand(new InsertArchiveStudyStorageCommand(_storageLocation.GetKey(), _archive.GetKey(), _storageLocation.ServerTransferSyntaxKey, _archiveXml)); }
private static void WriteStudyStream(string streamFile, string gzStreamFile, StudyXml theStream) { XmlDocument doc = theStream.GetMemento(_outputSettings); // allocate the random number generator here, in case we need it below Random rand = new Random(); string tmpStreamFile = streamFile + "_tmp"; string tmpGzStreamFile = gzStreamFile + "_tmp"; for (int i = 0; ; i++) try { if (File.Exists(tmpStreamFile)) FileUtils.Delete(tmpStreamFile); if (File.Exists(tmpGzStreamFile)) FileUtils.Delete(tmpGzStreamFile); using (FileStream xmlStream = FileStreamOpener.OpenForSoleUpdate(tmpStreamFile, FileMode.CreateNew), gzipStream = FileStreamOpener.OpenForSoleUpdate(tmpGzStreamFile, FileMode.CreateNew)) { StudyXmlIo.WriteXmlAndGzip(doc, xmlStream, gzipStream); xmlStream.Close(); gzipStream.Close(); } if (File.Exists(streamFile)) FileUtils.Delete(streamFile); File.Move(tmpStreamFile, streamFile); if (File.Exists(gzStreamFile)) FileUtils.Delete(gzStreamFile); File.Move(tmpGzStreamFile,gzStreamFile); return; } catch (IOException) { if (i < 5) { Thread.Sleep(rand.Next(5, 50)); // Sleep 5-50 milliseconds continue; } throw; } }
public void Create() { SelectFolderDialogCreationArgs args = new SelectFolderDialogCreationArgs(); args.Path = _lastFolder ?? Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); FileDialogResult result = base.Context.DesktopWindow.ShowSelectFolderDialogBox(args); if (result.Action == DialogBoxAction.Ok) { _lastFolder = result.FileName; StudyLoaderExtensionPoint xp = new StudyLoaderExtensionPoint(); IStudyLoader loader = (IStudyLoader)CollectionUtils.SelectFirst(xp.CreateExtensions(), delegate(object extension) { return ((IStudyLoader) extension).Name == "DICOM_LOCAL";}); var selected = base.Context.SelectedStudy; loader.Start(new StudyLoaderArgs(selected.StudyInstanceUid, selected.Server, null)); StudyXml xml = new StudyXml(); Sop sop; while (null != (sop = loader.LoadNextSop())) { xml.AddFile(((ILocalSopDataSource) sop.DataSource).File); } StudyXmlOutputSettings settings = new StudyXmlOutputSettings(); settings.IncludePrivateValues = StudyXmlTagInclusion.IgnoreTag; settings.IncludeUnknownTags = StudyXmlTagInclusion.IgnoreTag; settings.MaxTagLength = 100 * 1024; settings.IncludeSourceFileName = true; XmlDocument doc = xml.GetMemento(settings); string fileName = System.IO.Path.Combine(result.FileName, "studyxml.xml"); XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.Indentation = 5; doc.Save(writer); } }
/// <summary> /// Load a <see cref="StudyXml"/> file for a given <see cref="StudyStorageLocation"/> /// </summary> /// <param name="location">The location a study is stored.</param> /// <returns>The <see cref="StudyXml"/> instance for <paramref name="location"/></returns> private StudyXml LoadStudyStream(string location) { StudyXml theXml = new StudyXml(); if (File.Exists(location)) { using (Stream fileStream = new FileStream(location, FileMode.Open)) { XmlDocument theDoc = new XmlDocument(); StudyXmlIo.Read(theDoc, fileStream); theXml.SetMemento(theDoc); fileStream.Close(); } } return theXml; }
public void Initialize(StudyLocation location, List<string> seriesInstanceUids ) { _location = location; SeriesInstanceUids = seriesInstanceUids; StudyXml = _location.LoadStudyXml(); NumberOfSeriesRelatedInstances = 0; foreach (string seriesInstanceUid in seriesInstanceUids) { foreach (SeriesXml seriesXml in StudyXml) { if (seriesXml.SeriesInstanceUid.Equals(seriesInstanceUid)) { NumberOfSeriesRelatedInstances += seriesXml.NumberOfSeriesRelatedInstances; } } } }