private TaskInfo SendStudy(string studyInstanceUid, string aeTarget) { var taskInfo = new TaskInfo() { Token = new CancellationTokenSource() }; taskInfo.Task = Task.Run(() => { taskInfo.Token.Token.ThrowIfCancellationRequested(); this._logger.Log(LogLevel.Info, "Sending study to " + aeTarget + ": " + studyInstanceUid); var remoteAe = this._db.GetEntity(aeTarget); if (remoteAe == null) { this._logger.Log(LogLevel.Error, "Unknown send target AE: " + aeTarget); return; } var images = this._db.FetchStudyImages(studyInstanceUid); taskInfo.ProgressCount = 0; taskInfo.ProgressTotal = images.Count; TaskCompletionSource <bool> source = new TaskCompletionSource <bool>(); var sender = new DICOMSender(this._logger, aeTarget + "/" + studyInstanceUid, this._settings.VerboseLogging); sender.SCUFinished += (DICOMSCU scu, bool success) => { source.SetResult(success); }; sender.SendUpdate += (DICOMSender senderx, ushort remaining, ushort completed, ushort warned, ushort failed) => { taskInfo.ProgressCount = completed + warned + failed; }; sender.Send(this.GetHostingAE(), remoteAe, images.Select(image => new SendableImage { FilePath = _db.FixImagePath(image.Path), AbstractSyntax = AbstractSyntaxes.Lookup(image.SOPClassID), TransferSyntax = TransferSyntaxes.Lookup(image.TransferSyntaxID) })); source.Task.Wait(); this._logger.Log(LogLevel.Info, "Done sending study to " + aeTarget + ": " + studyInstanceUid); }, taskInfo.Token.Token); return(taskInfo); }
/// <summary> /// Attempt to pull an abstract syntax out of a DICOMData. /// </summary> /// <param name="data">The DICOMData to extract from.</param> /// <returns>The abstract syntax from either the media storage Sop class uid field or the sop class uid field. /// If both are missing, returns CT Image Storage.</returns> public static AbstractSyntax ExtractAbstractSyntaxFromDicomData(DICOMData data) { var MediaStorageSOPClassUID = data.Elements[DICOMTags.MediaStorageSOPClassUID] as DICOMElementUI; if (MediaStorageSOPClassUID != null) { return(AbstractSyntaxes.Lookup(MediaStorageSOPClassUID.Data as string)); } else { var SOPClassUID = data.Elements[DICOMTags.SOPClassUID] as DICOMElementUI; if (SOPClassUID != null) { return(AbstractSyntaxes.Lookup(SOPClassUID.Data as string)); } else { // Fall back to basic CT image storage... return(AbstractSyntaxes.CTImageStorage); } } }
internal void ParsePacket(SwappableBinaryReader dataSource, int itemLength) { long startOffset = dataSource.BaseStream.Position; ContextID = dataSource.ReadByte(); byte reserved = dataSource.ReadByte(); Result = (PresentationResult)dataSource.ReadByte(); reserved = dataSource.ReadByte(); while (dataSource.BaseStream.Position - startOffset < itemLength) { //read sub-item byte subItemType = dataSource.ReadByte(); byte subItemReserved = dataSource.ReadByte(); ushort subItemLength = dataSource.ReadUInt16(); if (subItemType == 0x30) { string rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength)); AbstractSyntaxSpecified = AbstractSyntaxes.Lookup(rawSyntax); } else if (subItemType == 0x40) { string rawSyntax = Uid.UidRawToString(dataSource.ReadBytes(subItemLength)); TransferSyntax syntax = TransferSyntaxes.Lookup(rawSyntax); if (syntax != null) { TransferSyntaxesProposed.Add(syntax); } } else { //no idea what it is, or we don't care dataSource.ReadBytes(itemLength); } } }
internal QRRequestData(DICOMData cmd, DICOMData data) { //parse query-retrieve level QueryLevel = AbstractSyntaxes.Lookup((string)cmd[DICOMTags.AffectedSOPClass].Data).ParseQRLevel(); if (QueryLevel == QueryRetrieveLevel.ModalityWorklist) { FindLevel = QRLevelType.Study; } else { //parse find level string type = ((string)data[DICOMTags.QueryRetrieveLevel].Data).Trim().ToUpper(); if (type == "PATIENT") { FindLevel = QRLevelType.Patient; } else if (type == "STUDY") { FindLevel = QRLevelType.Study; } else if (type == "SERIES") { FindLevel = QRLevelType.Series; } else if (type == "IMAGE") { FindLevel = QRLevelType.Image; } else { FindLevel = QRLevelType.Study; //fallback } } Console.Write(data.Dump()); //pull all search terms SearchTerms = new Dictionary <uint, object>(); foreach (DICOMElement elem in data.Elements.Values) { //Don't add group length elements if (elem.Elem == 0) { continue; } if (elem.Tag == DICOMTags.QueryRetrieveLevel) { continue; } if (elem.Tag == DICOMTags.ScheduledProcedureStepSequence) { if (elem.VRShort == DICOMElementSQ.vrshort) { foreach (SQItem sqItem in ((DICOMElementSQ)elem).Items) { foreach (DICOMElement elemi in sqItem.Elements) { if (elemi.Elem == 0) { continue; } if (elemi.Tag == DICOMTags.QueryRetrieveLevel) { continue; } SearchTerms.Add(elemi.Tag, elemi.Data); } } } } else if (elem.Data.ToString() != "") { SearchTerms.Add(elem.Tag, elem.Data); } } FillTagsList(data); }
private void SendNextImage() { DICOMData data = null; while (sendQueue.Count > 0) { var nextImg = sendQueue.Dequeue(); try { data = nextImg.DicomData; if (data == null) { if (!File.Exists(nextImg.FilePath)) { logger.Log(LogLevel.Error, "File doesn't exist: " + nextImg.FilePath); failed++; if (SendUpdate != null) { SendUpdate(this, (ushort)sendQueue.Count, completed, warned, failed); } continue; } data = new DICOMData(); if (!data.ParseFile(nextImg.FilePath, true, logger)) { failed++; if (SendUpdate != null) { SendUpdate(this, (ushort)sendQueue.Count, completed, warned, failed); } continue; } } // See if anyone wants to do any work to it if (PreSendImage != null) { PreSendImage(this, data); } AbstractSyntax absSyntax = AbstractSyntaxes.CTImageStorage; if (data.Elements.ContainsKey(DICOMTags.SOPClassUID)) { absSyntax = AbstractSyntaxes.Lookup((string)data[DICOMTags.SOPClassUID].Data); } conn.SendCSTORERQ(data, absSyntax, CommandPriority.Medium, moveInitiatorAETitle, moveMessageID); } catch (Exception e) { logger.Log(LogLevel.Error, "Unknown error encountered in DICOMSender.SendNextImage: " + e.Message); failed++; if (SendUpdate != null) { SendUpdate(this, (ushort)sendQueue.Count, completed, warned, failed); } } return; } conn.SendReleaseRQ(); }