/// <summary> /// Sends an A-ASSOCIATE-AC or A-ASSOCIATE-RJ based on the supplied presentation contexts. /// </summary> /// <remarks> /// This method will send an A-ASSOCIATE-AC if at least one presentation context will be accepted /// in the supplied presentation contexts. Otherwise an A-ASSOCIATE-RJ will be sent. <br></br><br></br> /// /// Any requested presentation context that has no counterpart in the supplied presentation /// contexts will automaticaly be added to the A-ASSOCIATE-AC with the presentation context rejected.<br></br><br></br> /// </remarks> /// <param name="presentationContexts">The presentation contexts.</param> /// <returns>The sent AssociateAc or AssociateRj.</returns> protected internal DulMessage SendAssociateRp(params PresentationContext[] presentationContexts) { PresentationContextCollection presentationContextCollection = new PresentationContextCollection(); foreach(PresentationContext presentationContext in presentationContexts) { presentationContextCollection.Add(presentationContext); } return(SendAssociateRp(presentationContextCollection)); }
private PresentationContext[] SetPresentationContexts(PresentationContextCollection pcs) { PresentationContextCollection localPCs = new PresentationContextCollection(); // use the local trigger items to establish a list of presentation contexts that // only appear once foreach (PresentationContext pc in pcs) { if (FindMatchingPresentationContext(localPCs,pc) == false) { localPCs.Add(pc); } } // now set up the returned presentation contexts from the local trigger collection PresentationContext[] presentationContexts = new PresentationContext[localPCs.Count]; int index = 0; foreach (PresentationContext pc in localPCs) { // save the presentation context string[] transferSyntaxes = new string[pc.TransferSyntaxes.Count]; int i = 0; foreach(string ts in pc.TransferSyntaxes) { transferSyntaxes.SetValue(ts,i); i++; } presentationContexts[index++] = new PresentationContext(pc.AbstractSyntax, transferSyntaxes); } return presentationContexts; }
/// <summary> /// Method to handle the workflow after receiving an Associate Request. /// </summary> /// <param name="associateRq">Associate Request message.</param> public override void AfterHandlingAssociateRequest(AssociateRq associateRq) { if (IsMessageHandled == false) { // determine which workflow to follow switch(_scpRespondToAssociateRequest) { case ScpRespondToAssociateRequestEnum.WithAssociateAccept: { // send an associate accept with the supported transfer syntaxes. PresentationContextCollection presentationContextsForAssociateAc = new PresentationContextCollection(); foreach (PresentationContext reqtedPC in associateRq.PresentationContexts) { String abstractSyntaxInAssociateRq = reqtedPC.AbstractSyntax; PresentationContext presentationContextForAssociateAc = null; if (sopList.Contains(abstractSyntaxInAssociateRq)) { String transferSyntaxForAssociateAc = null; this.Options.LocalAeTitle = associateRq.CalledAETitle; this.Options.RemoteAeTitle = associateRq.CallingAETitle; if (reqtedPC.AbstractSyntax == "1.2.840.10008.1.20.1") { transferSyntaxForAssociateAc = DetermineTransferSyntaxToAccept (reqtedPC.TransferSyntaxes, tsCommitList); } else { transferSyntaxForAssociateAc = DetermineTransferSyntaxToAccept (reqtedPC.TransferSyntaxes, tsStoreList); } if (transferSyntaxForAssociateAc.Length == 0) { presentationContextForAssociateAc = new PresentationContext (reqtedPC.AbstractSyntax, 4, ""); } else { presentationContextForAssociateAc = new PresentationContext (reqtedPC.AbstractSyntax, 0, transferSyntaxForAssociateAc); } } else { presentationContextForAssociateAc = new PresentationContext (reqtedPC.AbstractSyntax, 3, ""); } presentationContextsForAssociateAc.Add(presentationContextForAssociateAc); } SendAssociateAc(presentationContextsForAssociateAc); isAssociated = true; break; } case ScpRespondToAssociateRequestEnum.WithAssociateReject: // send an associate reject with the given parameters SendAssociateRj(_rejectResult, _rejectSource, _rejectReason); break; case ScpRespondToAssociateRequestEnum.WithAbort: default: // send an abort request with the given parameters SendAbort(_abortSource, _abortReason); break; } // message has now been handled IsMessageHandled = true; } }
private void SendDICOMDataInSingleAssociation(string[] mediaFiles) { // Set the dicom messages to send List<DicomFile> dicomMessageCollection = new List<DicomFile>(); PresentationContextCollection pcCollection = new PresentationContextCollection(); StoreScu storageScuThread = new StoreScu(); storageScuThread.Initialize(this.overviewThread); storageScuThread.Options.CopyFrom(this.storageOptions); String resultsFileBaseName = "StorageOperation_" + System.DateTime.Now.ToString("yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture); storageScuThread.Options.ResultsFileNameOnlyWithoutExtension = resultsFileBaseName; storageScuThread.Options.Identifier = resultsFileBaseName; storageScuThread.Options.LogThreadStartingAndStoppingInParent = false; storageScuThread.Options.LogWaitingForCompletionChildThreads = false; storageScuThread.Options.AutoValidate = false; //The Current Directory is being set to the Results Directory because // when DICOMDIRs(or DICOM Files)Media are exported, the Environment.CurrentDirectory //is set to the Directory in which the DCM objects are present and the export will fail // if the DICOMDIR is present on a Physical Media. Environment.CurrentDirectory = this.storageOptions.ResultsDirectory; foreach (string dcmFilename in mediaFiles) { string msg = string.Format("Reading the DICOM object - {0}", dcmFilename); storageScuThread.WriteInformation(msg); try { // Read the DCM File DicomFile dcmFile = new DicomFile(); dcmFile.Read(dcmFilename, storageScuThread); FileMetaInformation fMI = dcmFile.FileMetaInformation; // Get the transfer syntax and SOP class UID System.String transferSyntax = "1.2.840.10008.1.2.1"; System.String sopClassUid = ""; if ((fMI != null)) { // Get the Transfer syntax HLI.Attribute tranferSyntaxAttr = fMI["0x00020010"]; transferSyntax = tranferSyntaxAttr.Values[0]; // Get the SOP Class UID Values values = fMI["0x00020002"].Values; sopClassUid = values[0]; } else { // Get the SOP Class UID Values values = dcmFile.DataSet["0x00080016"].Values; sopClassUid = values[0]; } //Check for DICOMDIR if(sopClassUid == "") { storageScuThread.WriteError("Can't determine SOP Class UID for DCM file. \nSkipping the DCM File."); continue; } else if (sopClassUid == "1.2.840.10008.1.3.10") { HLI.DataSet tempDataSet = new HLI.DataSet(); // Read the DICOMDIR dataset dcmFile.DataSet.DvtkDataDataSet = Dvtk.DvtkDataHelper.ReadDataSetFromFile(dcmFilename); Dvtk.Sessions.ScriptSession session = this.storageOptions.DvtkScriptSession; ArrayList refFiles = ImportRefFilesFromDicomdir(dcmFilename, dcmFile.DataSet); foreach (string refFilename in refFiles) { // Read the Reference File DicomFile refFile = new DicomFile(); refFile.Read(refFilename, storageScuThread); FileMetaInformation refFMI = refFile.FileMetaInformation; // Get the transfer syntax and SOP class UID System.String refTransferSyntax = "1.2.840.10008.1.2.1"; if ((refFMI != null) && refFMI.Exists("0x00020010")) { // Get the Transfer syntax HLI.Attribute refTranferSyntaxAttr = refFMI["0x00020010"]; refTransferSyntax = refTranferSyntaxAttr.Values[0]; } Values sopValues = refFile.DataSet["0x00080016"].Values; System.String refSopClassUid = sopValues[0]; PresentationContext refPresentationContext = new PresentationContext(refSopClassUid, // Abstract Syntax Name refTransferSyntax); // Transfer Syntax Name(s) pcCollection.Add(refPresentationContext); //DicomMessage refStorageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); //refStorageMessage.DataSet.CloneFrom(refFile.DataSet); dicomMessageCollection.Add(refFile); } } else { PresentationContext presentationContext = new PresentationContext(sopClassUid, // Abstract Syntax Name transferSyntax); // Transfer Syntax Name(s) pcCollection.Add(presentationContext); //DicomMessage storageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); //storageMessage.DataSet.CloneFrom(dcmFile.DataSet); dicomMessageCollection.Add(dcmFile); } } catch (Exception e) { storageScuThread.WriteError(e.Message + "\nSkipping the DCM File."); } } // set the presentation contexts for the association PresentationContext[] presentationContexts = SetPresentationContexts(pcCollection); storageScuThread.DICOMFileCollection = dicomMessageCollection; storageScuThread.PresentationContexts = presentationContexts; storageScuThread.Start(); storageScuThread.WaitForCompletion(); DicomMessageCollection cStoreResponses = storageScuThread.Messages.DicomMessages.CStoreResponses; //storageScuThread.Stop(); HandleCStoreResponses(storageCommitItems, cStoreResponses); storageScuThread.Messages.DicomMessages.CStoreResponses.Clear(); }
private void SendDICOMDataInMultipleAssociation(string[] mediaFiles) { int index = 0; // Set the dicom messages to send DicomMessageCollection dicomMessageCollection = new DicomMessageCollection(); PresentationContextCollection pcCollection = new PresentationContextCollection(); //The Current Directory is being set to the Results Directory because // when DICOMDIRs(or DICOM Files)Media are exported, the Environment.CurrentDirectory //is set to the Directory in which the DCM objects are present and the export will fail // if the DICOMDIR is present on a Physical Media. Environment.CurrentDirectory = this.storageOptions.ResultsDirectory; foreach (string dcmFilename in mediaFiles) { HliScu storageScuSubThread = new HliScu(); storageScuSubThread.Initialize(this.overviewThread); storageScuSubThread.Options.CopyFrom(this.storageOptions); storageScuSubThread.Options.Identifier = string.Format("StorageOperation_{0}",index); String resultsFileBaseName = string.Format("StorageOperation_{0}_", index) + System.DateTime.Now.ToString("yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture); storageScuSubThread.Options.ResultsFileNameOnlyWithoutExtension = resultsFileBaseName; storageScuSubThread.Options.LogThreadStartingAndStoppingInParent = false; storageScuSubThread.Options.LogWaitingForCompletionChildThreads = false; storageScuSubThread.Options.AutoValidate = false; string msg = string.Format("Reading and exporting the DICOM object - {0}", dcmFilename); storageScuSubThread.WriteInformation(msg); try { // Read the DCM File DicomFile dcmFile = new DicomFile(); dcmFile.Read(dcmFilename, storageScuSubThread); FileMetaInformation fMI = dcmFile.FileMetaInformation; // Get the transfer syntax and SOP class UID System.String transferSyntax = "1.2.840.10008.1.2.1"; if ((fMI != null) && fMI.Exists("0x00020010")) { // Get the Transfer syntax HLI.Attribute tranferSyntaxAttr = fMI["0x00020010"]; transferSyntax = tranferSyntaxAttr.Values[0]; } Values values = fMI["0x00020002"].Values; System.String sopClassUid = values[0]; //Check for DICOMDIR if (sopClassUid == "1.2.840.10008.1.3.10") { // Read the DICOMDIR dataset dcmFile.DataSet.DvtkDataDataSet = Dvtk.DvtkDataHelper.ReadDataSetFromFile(dcmFilename); ArrayList refFiles = ImportRefFilesFromDicomdir(dcmFilename, dcmFile.DataSet); foreach (string refFilename in refFiles) { // Read the Reference File DicomFile refFile = new DicomFile(); refFile.Read(refFilename, storageScuSubThread); FileMetaInformation refFMI = refFile.FileMetaInformation; // Get the transfer syntax and SOP class UID System.String refTransferSyntax = "1.2.840.10008.1.2.1"; if ((refFMI != null) && refFMI.Exists("0x00020010")) { // Get the Transfer syntax HLI.Attribute refTranferSyntaxAttr = refFMI["0x00020010"]; refTransferSyntax = refTranferSyntaxAttr.Values[0]; } Values sopValues = refFile.DataSet["0x00080016"].Values; System.String refSopClassUid = sopValues[0]; PresentationContext refPresentationContext = new PresentationContext(refSopClassUid, // Abstract Syntax Name refTransferSyntax); // Transfer Syntax Name(s) pcCollection.Add(refPresentationContext); DicomMessage refStorageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); refStorageMessage.DataSet.CloneFrom(refFile.DataSet); dicomMessageCollection.Add(refStorageMessage); // set the presentation contexts for the association PresentationContext[] presentationContexts = SetPresentationContexts(pcCollection); storageScuSubThread.Start(); storageScuSubThread.TriggerSendAssociationAndWait(dicomMessageCollection, presentationContexts); } } else { PresentationContext presentationContext = new PresentationContext(sopClassUid, // Abstract Syntax Name transferSyntax); // Transfer Syntax Name(s) PresentationContext[] presentationContexts = new PresentationContext[1]; presentationContexts[0] = presentationContext; DicomMessage storageMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); storageMessage.DataSet.CloneFrom(dcmFile.DataSet); storageScuSubThread.Start(); storageScuSubThread.TriggerSendAssociationAndWait(storageMessage, presentationContexts); } if (storageScuSubThread.HasExceptionOccured) { storageScuSubThread.WriteError(string.Format("Store operation of {0} failed", dcmFilename)); } } catch (Exception e) { storageScuSubThread.WriteError(e.Message + "\nSkipping the DCM File."); } index++; storageScuSubThread.Stop(); } DicomMessageCollection cStoreResponses = threadManager.Messages.DicomProtocolMessages.DicomMessages.CStoreResponses; foreach (DicomMessage cStoreRsp in cStoreResponses) { Int32 statusVal = Int32.Parse(cStoreRsp.CommandSet.GetValues("0x00000900")[0]); String sopInstUid = cStoreRsp.CommandSet.GetValues("0x00001000")[0]; if (statusVal == 0) { string infoMsg = string.Format("Image with SOP Instance UID{0} stored successfully.", sopInstUid); overviewThread.WriteInformation(infoMsg); } else { string warnMsg = string.Format("Non-zero status returned. Image with SOP Instance UID{0} storage failed.", sopInstUid); overviewThread.WriteWarning(warnMsg); } } HandleCStoreResponses(storageCommitItems, cStoreResponses); threadManager.Messages.DicomProtocolMessages.DicomMessages.CStoreResponses.Clear(); }
/// <summary> /// Creates presentation contexts to be used in an A-ASSOCIATE-AC that are based on the /// presentation contexts of this instance. /// </summary> /// <remarks> /// The following holds for the returned presentation contexts:<br></br> /// - For each requested presentation contex, do the following:<br></br> /// 1)<br></br> /// Check if one or more of the requested transfer syntaxes is present in the first supplied /// TransferSyntaxes instance. If this is the case, use the requested transfer syntax that is /// requested before the other ones in the accepted presentation context counterpart (has /// result field 0).<br></br> /// 2)<br></br> /// If no requested transfer syntaxes was present, try this with the second supplied /// TransferSyntaxes instance.<br></br> /// 3) If no requested transfer syntaxes was present is in any supplied TransferSyntaxes /// instance, reject the presentation context with result 4.<br></br><br></br> /// /// Note that a difference exists between supplying one TransferSyntaxes instance with all /// transfer syntaxes to accept and supplying multiple TransferSyntaxes instances each containing /// only one transfer syntax. In the first case, the preference (order of proposed transfer /// syntaxes) of the SCU will be used, in the second case the preference of the caller of this /// method will be used. /// </remarks> /// <param name="transferSyntaxesList">The transfer syntaxes to accept.</param> /// <returns>The created presentation contexts.</returns> public PresentationContextCollection CreatePresentationContextsForAssociateAc(params TransferSyntaxes[] transferSyntaxesList) { PresentationContextCollection presentationContextsForAssociateAc = new PresentationContextCollection(); PresentationContextCollection presentationContexts = PresentationContexts; foreach(PresentationContext presentationContextInAssociateRq in presentationContexts) { String abstractSyntaxInAssociateRq = presentationContextInAssociateRq.AbstractSyntax; PresentationContext presentationContextForAssociateAc = null; String transferSyntaxForAssociateAc = DetermineTransferSyntaxToAccept (presentationContextInAssociateRq.TransferSyntaxes, transferSyntaxesList); if (transferSyntaxForAssociateAc.Length == 0) { presentationContextForAssociateAc = new PresentationContext (presentationContextInAssociateRq.AbstractSyntax, 4, ""); } else { presentationContextForAssociateAc = new PresentationContext (presentationContextInAssociateRq.AbstractSyntax, 0, transferSyntaxForAssociateAc); } presentationContextForAssociateAc.SetId(presentationContextInAssociateRq.ID); presentationContextsForAssociateAc.Add(presentationContextForAssociateAc); } return(presentationContextsForAssociateAc); }
/// <summary> /// Creates presentation contexts to be used in an A-ASSOCIATE-AC that are based on the /// presentation contexts of this instance. /// </summary> /// <remarks> /// The following holds for the returned presentation contexts: /// - All requested presentation contexts with an abstract syntax contained in the supplied /// SOP classes will be accepted (have result field 0). The rest will be rejected /// (have result field 3). /// - For each accepted requested presentation context, the first proposed transfer syntax /// will be used. /// </remarks> /// <param name="sopClasses">The SOP Classes to accept.</param> /// <returns>The created presentation contexts.</returns> public PresentationContextCollection CreatePresentationContextsForAssociateAc(SopClasses sopClasses) { PresentationContextCollection presentationContextsForAssociateAc = new PresentationContextCollection(); PresentationContextCollection presentationContexts = PresentationContexts; foreach(PresentationContext presentationContextInAssociateRq in presentationContexts) { String abstractSyntaxInAssociateRq = presentationContextInAssociateRq.AbstractSyntax; PresentationContext presentationContextForAssociateAc = null; if (sopClasses.List.Contains(abstractSyntaxInAssociateRq)) { presentationContextForAssociateAc = new PresentationContext (presentationContextInAssociateRq.AbstractSyntax, 0, presentationContextInAssociateRq.TransferSyntaxes[0]); } else { presentationContextForAssociateAc = new PresentationContext (presentationContextInAssociateRq.AbstractSyntax, 3, ""); } presentationContextForAssociateAc.SetId(presentationContextInAssociateRq.ID); presentationContextsForAssociateAc.Add(presentationContextForAssociateAc); } return(presentationContextsForAssociateAc); }
// // - Methods - // /// <summary> /// Creates presentation contexts to be used in an A-ASSOCIATE-AC that are based on the /// presentation contexts of this instance. /// </summary> /// <remarks> /// The following holds for the returned presentation contexts: /// - All requested presentation contexts will be accepted (have result field 0). /// - For each requested presentation context, the first proposed transfer syntax will be used. /// </remarks> /// <returns>The created presentation contexts.</returns> public PresentationContextCollection CreatePresentationContextsForAssociateAc() { PresentationContextCollection presentationContextsForAssociateAc = new PresentationContextCollection(); PresentationContextCollection presentationContexts = PresentationContexts; foreach(PresentationContext presentationContextInAssociateRq in presentationContexts) { PresentationContext presentationContextForAssociateAc = new PresentationContext (presentationContextInAssociateRq.AbstractSyntax, 0, presentationContextInAssociateRq.TransferSyntaxes[0]); presentationContextForAssociateAc.SetId(presentationContextInAssociateRq.ID); presentationContextsForAssociateAc.Add(presentationContextForAssociateAc); } return(presentationContextsForAssociateAc); }