/// <summary> /// Trigger the Client to send a Verification (DICOM C-ECHO-RQ). /// </summary> /// <param name="actorName">Destination Actor Name.</param> /// <returns>Boolean indicating success or failure.</returns> public bool TriggerClientVerification(ActorName actorName) { // Set up a Verification SOP Class - C-ECHO-RQ trigger DicomTrigger dicomTrigger = new DicomTrigger(Dvtk.IheActors.Bases.TransactionNameEnum.RAD_UNKNOWN); dicomTrigger.AddItem(new DicomMessage(DvtkData.Dimse.DimseCommand.CECHORQ), HliScp.VERIFICATION_SOP_CLASS_UID, HliScp.IMPLICIT_VR_LITTLE_ENDIAN); DicomTriggerItem dicomTriggerItem = dicomTrigger.TriggerItems[0]; // thread must wait for association completion _scu.SignalCompletion = true; // set up the presentation context from the trigger PresentationContext[] presentationContexts = new PresentationContext[1]; presentationContexts[0] = new PresentationContext(dicomTriggerItem.SopClassUid, dicomTriggerItem.TransferSyntaxes); _scu.TriggerSendAssociation(dicomTriggerItem.Message, presentationContexts); // wait for association completion // - timeout of 0 means "no timeout". _semaphore.Wait(0); // return a boolean indicating if the trigger was processed successfully or not return(_scu.ProcessTriggerResult); }
private DicomTrigger GenerateTrigger(DicomMessage dicomMessage) { DicomTrigger storageCommitTrigger = new DicomTrigger(TransactionNameEnum.RAD_10); storageCommitTrigger.AddItem(GenerateTriggers.MakeStorageCommitEvent(_informationModels, dicomMessage), "1.2.840.10008.1.20.1", "1.2.840.10008.1.2"); return(storageCommitTrigger); }
private DicomTrigger GenerateTrigger(DicomMessage dicomMessage) { DicomTrigger storageCommitTrigger = new DicomTrigger(TransactionNameEnum.RAD_10); storageCommitTrigger.AddItem(GenerateTriggers.MakeStorageCommitEvent(_informationModels, dicomMessage), "1.2.840.10008.1.20.1", "1.2.840.10008.1.2"); return storageCommitTrigger; }
/// <summary> /// Handle a Dicom Transaction from the given Actor Name. /// </summary> /// <param name="actorName">Source Actor Name.</param> /// <param name="dicomTransaction">Dicom Transaction.</param> protected override void HandleTransactionFrom(ActorName actorName, DicomTransaction dicomTransaction) { switch (actorName.Type) { case ActorTypeEnum.AcquisitionModality: // received Modality Procedure Step In Progress [RAD-6] or // received Modality Procedur Step Completed [RAD-7] case ActorTypeEnum.EvidenceCreator: { // received Creator Procedure Step In Progress [RAD-20] or // received Creator Procedure Step Completed [RAD-21] TransactionNameEnum transactionName = dicomTransaction.TransactionName; DicomMessage dicomMessage = (DicomMessage)dicomTransaction.DicomMessages[0]; // ignore the C-ECHO-RQ used in the Verification SOP Class // - no need to forward this if (dicomMessage.CommandSet.DimseCommand != DvtkData.Dimse.DimseCommand.CECHORQ) { // make a trigger from the transaction message DicomTrigger dicomTrigger = new DicomTrigger(transactionName); dicomTrigger.AddItem(dicomMessage, "1.2.840.10008.3.1.2.3.3", "1.2.840.10008.1.2"); // trigger the following actors bool triggerResult = TriggerActorInstances(ActorTypeEnum.DssOrderFiller, dicomTrigger, false); if (triggerResult == true) { triggerResult = TriggerActorInstances(ActorTypeEnum.ImageManager, dicomTrigger, false); } } break; } default: break; } }
/// <summary> /// Send a C-MOVE-RQ Information Model Retrieve. /// Retrieve based on the informationModel provided and the query/retrieve level. Take /// the retrieve tags from the retrieveTags provided. The retrieve is done to the move /// destination. /// /// The C-MOVE-RSP messages returned are stored in a DicomQueryItemCollection named RetrieveItems. /// </summary> /// <param name="informationModel">Q/R Information Model to be used in the retrieve operation.</param> /// <param name="level">Query / retrieve level.</param> /// <param name="moveDestination">AE Title of the "move" destination.</param> /// <param name="retrieveTags">List of Retrieve Tags.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendRetrieveImages(QueryRetrieveInformationModelEnum informationModel, QueryRetrieveLevelEnum level, System.String moveDestination, TagValueCollection retrieveTags) { System.String queryRetrieveLevel = System.String.Empty; switch(level) { case QueryRetrieveLevelEnum.PatientQueryRetrieveLevel: queryRetrieveLevel = "PATIENT"; break; case QueryRetrieveLevelEnum.StudyQueryRetrieveLevel: queryRetrieveLevel = "STUDY"; break; case QueryRetrieveLevelEnum.SeriesQueryRetrieveLevel: queryRetrieveLevel = "SERIES"; break; case QueryRetrieveLevelEnum.InstanceQueryRetrieveLevel: queryRetrieveLevel = "IMAGE"; break; default: return false; } if (retrieveTags.Find(Tag.QUERY_RETRIEVE_LEVEL) == null) { retrieveTags.Add(new DicomTagValue(Tag.QUERY_RETRIEVE_LEVEL, queryRetrieveLevel)); } _retrieveItems = new DicomQueryItemCollection(); DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_16); System.String sopClassUid = System.String.Empty; switch(informationModel) { case QueryRetrieveInformationModelEnum.PatientRootQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.1.2"; break; case QueryRetrieveInformationModelEnum.StudyRootQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.2.2"; break; case QueryRetrieveInformationModelEnum.PatientStudyOnlyQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.3.2"; break; default: return false; } trigger.AddItem(GenerateTriggers.MakeCMoveRetrieve(informationModel, moveDestination, retrieveTags), sopClassUid, "1.2.840.10008.1.2"); // RAD-16 - trigger the ImageArchive bool triggerResult = TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true); // Get the retrieve items returned if (triggerResult == true) { foreach (ActorsTransaction actorsTransaction in ActorsTransactionLog) { if (actorsTransaction.FromActorName.Type == ActorTypeEnum.ImageArchive) { BaseTransaction baseTransaction = actorsTransaction.Transaction; if (baseTransaction is DicomTransaction) { DicomTransaction dicomTransaction = (DicomTransaction)baseTransaction; if (dicomTransaction.Processed == false) { DicomMessageCollection cMoveResponses = dicomTransaction.DicomMessages.CMoveResponses; int index = 0; foreach (DvtkHighLevelInterface.Dicom.Messages.DicomMessage dicomMessage in cMoveResponses) { // store all C-MOVE-RSP messages // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_COMPLETED_SUBOPERATIONS) to get completed count // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_FAILED_SUBOPERATIONS) to get failed count // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_REMAINING_SUBOPERATIONS) to get remaining count // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_WARNING_SUBOPERATIONS) to get warning count DicomQueryItem dicomRetriveItem = new DicomQueryItem(index++, dicomMessage); _retrieveItems.Add(dicomRetriveItem); } dicomTransaction.Processed = true; } } } } } return triggerResult; }
/// <summary> /// Send a C-FIND-RQ Information Model Query. /// Query based on the informationModel provided and the query/retrieve level. Take /// the query tags from the queryTags provided. /// /// The C-FIND-RSP messages returned are stored in a DicomQueryItemCollection named QueryItems. /// </summary> /// <param name="informationModel">Q/R Information Model to be used in the query operation.</param> /// <param name="level">Query / retrieve level.</param> /// <param name="queryTags">List of Query Tags.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendQueryImages(QueryRetrieveInformationModelEnum informationModel, QueryRetrieveLevelEnum level, TagValueCollection queryTags) { System.String queryRetrieveLevel = System.String.Empty; switch(level) { case QueryRetrieveLevelEnum.PatientQueryRetrieveLevel: _patientLevelQueryItems = new DicomQueryItemCollection(); queryRetrieveLevel = "PATIENT"; break; case QueryRetrieveLevelEnum.StudyQueryRetrieveLevel: _studyLevelQueryItems = new DicomQueryItemCollection(); queryRetrieveLevel = "STUDY"; break; case QueryRetrieveLevelEnum.SeriesQueryRetrieveLevel: _seriesLevelQueryItems = new DicomQueryItemCollection(); queryRetrieveLevel = "SERIES"; break; case QueryRetrieveLevelEnum.InstanceQueryRetrieveLevel: _instanceLevelQueryItems = new DicomQueryItemCollection(); queryRetrieveLevel = "IMAGE"; break; default: return false; } if (queryTags.Find(Tag.QUERY_RETRIEVE_LEVEL) == null) { queryTags.Add(new DicomTagValue(Tag.QUERY_RETRIEVE_LEVEL, queryRetrieveLevel)); } DicomQueryItemCollection queryItems = QueryItems(level); DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_14); System.String sopClassUid = System.String.Empty; switch(informationModel) { case QueryRetrieveInformationModelEnum.PatientRootQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.1.1"; break; case QueryRetrieveInformationModelEnum.StudyRootQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.2.1"; break; case QueryRetrieveInformationModelEnum.PatientStudyOnlyQueryRetrieveInformationModel: sopClassUid = "1.2.840.10008.5.1.4.1.2.3.1"; break; default: return false; } trigger.AddItem(GenerateTriggers.MakeCFindQuery(informationModel, queryTags), sopClassUid, "1.2.840.10008.1.2"); // RAD-14 - trigger the ImageArchive bool triggerResult = TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true); // Get the query items returned if (triggerResult == true) { foreach (ActorsTransaction actorsTransaction in ActorsTransactionLog) { if (actorsTransaction.FromActorName.Type == ActorTypeEnum.ImageArchive) { BaseTransaction baseTransaction = actorsTransaction.Transaction; if (baseTransaction is DicomTransaction) { DicomTransaction dicomTransaction = (DicomTransaction)baseTransaction; if (dicomTransaction.Processed == false) { DicomMessageCollection cFindResponses = dicomTransaction.DicomMessages.CFindResponses; int index = 0; foreach (DvtkHighLevelInterface.Dicom.Messages.DicomMessage dicomMessage in cFindResponses) { if (dicomMessage.DataSet.Count != 0) { DicomQueryItem dicomQueryItem = new DicomQueryItem(index++, dicomMessage); queryItems.Add(dicomQueryItem); } } dicomTransaction.Processed = true; } } } } } return triggerResult; }
private bool TriggerModalityProcedureStepInProgress(DicomQueryItem modalityWorklistItem) { // Use modality Worklist Item to help construct the MPPS InProgress Message // Get the attribute values to copy DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator"); DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage); DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator"); mppsInProgressComparator.PopulateDicomMessage(_nCreateSetMppsInProgress, dicomWorklistItemComparator); // Trigger the N-CREATE-RQ MPPS InProgress DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_6); trigger.AddItem(_nCreateSetMppsInProgress, "1.2.840.10008.3.1.2.3.3", "1.2.840.10008.1.2"); // Update the default PerformedProcedureStepEntity values for the next MPPS In-Progress DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.PerformedProcedureStepEntity); // RAD-6 - trigger the PerformedProcedureStepManager return TriggerActorInstances(ActorTypeEnum.PerformedProcedureStepManager, trigger, true); }
private bool TriggerModalityProcedureStepCompletedDiscontinued(DvtkHighLevelInterface.Dicom.Messages.DicomMessage nSetMppsCompletedDiscontinued) { // Trigger the N-SET-RQ MPPS Completed/Discontinued DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_7); trigger.AddItem(nSetMppsCompletedDiscontinued, "1.2.840.10008.3.1.2.3.3", "1.2.840.10008.1.2"); // RAD-7 - trigger the PerformedProcedureStepManager return TriggerActorInstances(ActorTypeEnum.PerformedProcedureStepManager, trigger, true); }
/// <summary> /// Send the Storage Commitment message - use the storage commitment details /// built up during any previous SendModalityImagesStored() operations. /// The N-ACTION-RQ will be sent to the Image Manager. /// /// If the configured ActorOption1 for the DicomPeerToPeerConfiguration from the /// AcquisitionModalityActor to the ImageManagerActor is set to the string /// "DO_STORAGE_COMMITMENT_ON_SINGLE_ASSOCIATION" then the framework expects the /// Image Manager to return the N-EVENT-REPORT details over the same association /// as the N-ACTION details were sent. If the ActorOption1 configuration parameter /// is not set as above then the framework will expect the Image Manger to return /// the N-EVENT-REPORT details over a different association than the one used for the /// N-ACTION details. /// </summary> /// <param name="awaitNEventReport">Boolean indicating whether to wait for the /// N-EVENT-REPORT - either over the same or different association before returning /// to the caller.</param> /// <param name="timeOut">Time (in Seconds) to wait for the N-EVENT-REPORT to be sent /// from the Image Manager - only used if "awaitNEventReport" is set true.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendStorageCommitment(bool awaitNEventReport, int timeOut) { // Check if we need to wait for the Event Report if (awaitNEventReport == true) { // Subscribe to the event SubscribeStorageCommitmentNEventReportResponseEvent(); } // Generate a new Storage Commitment Transaction UID InBuiltDefaultTagValues inbuiltDefaultTagValues = new InBuiltDefaultTagValues(); System.String uidRoot = inbuiltDefaultTagValues.UidRoot; DicomTagValueAutoSetUid tagValueUid = new DicomTagValueAutoSetUid(AffectedEntityEnum.AnyEntity, Tag.TRANSACTION_UID, uidRoot, 1); _storageCommitTransactionUid = tagValueUid.Value; DvtkHighLevelInterface.Dicom.Messages.DicomMessage nActionStorageCommitment = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.NACTIONRQ); GenerateTriggers.MakeNActionStorageCommitment(_storageCommitItems, nActionStorageCommitment, _storageCommitTransactionUid, _mppsInstanceUid); // Trigger the N-ACTION-RQ Storage Commitment DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_10); trigger.AddItem(nActionStorageCommitment, "1.2.840.10008.1.20.1", "1.2.840.10008.1.2"); // RAD-10 - trigger the ImageManager bool result = TriggerActorInstances(ActorTypeEnum.ImageManager, trigger, true); if (result == true) { // Check if we need to wait for the Event Report if (awaitNEventReport == true) { // Wait for the N-Event-Report response // for the given timeout result = WaitStorageCommitmentNEventReportResponse(timeOut); // Unsubscribe to the event UnsubscribeStorageCommitmentNEventReportResponseEvent(); } } return result; }
/// <summary> /// Send a CFind Modality Worklist Query trigger by reading the query /// dataset from the given mwlQueryDcmFilename. If the scheduledProcedureStepStartDate /// is defined (not string empty) then if a value for this attribute is present in the /// read datset it will be overwritten by the scheduledProcedureStepStartDate value. /// </summary> /// <param name="mwlQueryDcmFilename">DCM file containing the MWL Query Dataset.</param> /// <param name="scheduledProcedureStepStartDate">Optional (not sting empty) start date to overwrite dataset value.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendQueryModalityWorklist(System.String mwlQueryDcmFilename, System.String scheduledProcedureStepStartDate) { // Generate trigger using the mwl dcm file contents and the given scheduledProcedureStepStartDate DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_5); trigger.AddItem(GenerateTriggers.MakeCFindModalityWorklist(mwlQueryDcmFilename, scheduledProcedureStepStartDate), "1.2.840.10008.5.1.4.31", "1.2.840.10008.1.2"); return TriggerModalityWorklistQuery(trigger); }
/// <summary> /// Send a CFind Modality Worklist Query trigger from the given queryTags. /// All other return keys are taken from the supported return key attributes /// in the Worklist Information Model. /// </summary> /// <param name="queryTags">List of Query Tags.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendQueryModalityWorklist(TagValueCollection queryTags) { // Generate trigger using the query tags DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_5); trigger.AddItem(GenerateTriggers.MakeCFindModalityWorklist(queryTags), "1.2.840.10008.5.1.4.31", "1.2.840.10008.1.2"); return TriggerModalityWorklistQuery(trigger); }
/// <summary> /// Send all the images found in the given storage directory. /// </summary> /// <param name="storageDirectory">Given storage directory - containing storage DCM files.</param> /// <param name="modalityWorklistItem">Worklist Item used to provide overruling values for /// the Image headers.</param> /// <param name="withSingleAssociation">Boolean indicating whether the images should be sent in a single /// association or not.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendModalityImagesStored(System.String storageDirectory, DicomQueryItem modalityWorklistItem, bool withSingleAssociation) { if ((storageDirectory.Length == 0) || (modalityWorklistItem == null)) return false; // Use a hash table to store the instance uid mappings // - the instance uids for the study, series and sop are going to be updated for all the datasets // read from the storageDirectory Hashtable instanceMapper = new Hashtable(); // Get the directory info for the storage directory - and make sure that it exists DirectoryInfo directoryInfo = new DirectoryInfo(storageDirectory); if (directoryInfo.Exists == false) { System.String message = System.String.Format("storageDirectory:\"{0}\" - does not exist.", storageDirectory); throw new System.Exception(message); } // Get a trigger DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_8); trigger.HandleInSingleAssociation = withSingleAssociation; // Interate over all the DCM files found in the storage directory // - update the instances found with the worklist item contents and // set up the triggers for the Image Archive foreach(FileInfo fileInfo in directoryInfo.GetFiles()) { if ((fileInfo.Extension.ToLower().Equals(".dcm")) || (fileInfo.Extension == System.String.Empty)) { // Read the file meta information - it must be present for this actor DvtkData.Media.FileMetaInformation fileMetaInformation = Dvtk.DvtkDataHelper.ReadFMIFromFile(fileInfo.FullName); if (fileMetaInformation == null) continue; // Try to get the transfer syntax uid // - start with Implicit VR Little Endian System.String transferSyntaxUid = "1.2.840.10008.1.2"; DvtkData.Dimse.Attribute attribute = fileMetaInformation.GetAttribute(DvtkData.Dimse.Tag.TRANSFER_SYNTAX_UID); if (attribute != null) { UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)attribute.DicomValue; if (uniqueIdentifier.Values.Count > 0) { transferSyntaxUid = uniqueIdentifier.Values[0]; } } // Read the dataset from the DCM file DvtkData.Dimse.DataSet dataset = Dvtk.DvtkDataHelper.ReadDataSetFromFile(fileInfo.FullName); if (dataset == null) continue; // Remove any Group Lengths from the dataset dataset.RemoveGroupLengthAttributes(); // Try to get the series instance uid System.String oldSeriesInstanceUid = System.String.Empty; DvtkData.Dimse.Attribute seriesInstanceUidAttribute = dataset.GetAttribute(Tag.SERIES_INSTANCE_UID); if (seriesInstanceUidAttribute != null) { UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)seriesInstanceUidAttribute.DicomValue; if (uniqueIdentifier.Values.Count > 0) { oldSeriesInstanceUid = uniqueIdentifier.Values[0]; } // Remove the old series instance from the dataset dataset.Remove(seriesInstanceUidAttribute); } // See if a mapping exists System.String newSeriesInstanceUid = (System.String) instanceMapper[oldSeriesInstanceUid]; if (newSeriesInstanceUid == null) { // Add a mapping DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.SeriesEntity); newSeriesInstanceUid = DefaultValueManager.GetInstantiatedValue(Tag.SERIES_INSTANCE_UID); instanceMapper.Add(oldSeriesInstanceUid, newSeriesInstanceUid); } // Add the new series instance uid to the dataset dataset.AddAttribute(Tag.SERIES_INSTANCE_UID.GroupNumber, Tag.SERIES_INSTANCE_UID.ElementNumber, VR.UI, newSeriesInstanceUid); // Try to get the sop instance uid System.String oldSopInstanceUid = System.String.Empty; DvtkData.Dimse.Attribute sopInstanceUidAttribute = dataset.GetAttribute(Tag.SOP_INSTANCE_UID); if (sopInstanceUidAttribute != null) { UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)sopInstanceUidAttribute.DicomValue; if (uniqueIdentifier.Values.Count > 0) { oldSopInstanceUid = uniqueIdentifier.Values[0]; } // Remove the old sop instance from the dataset dataset.Remove(sopInstanceUidAttribute); } // See if a mapping exists System.String newSopInstanceUid = (System.String) instanceMapper[oldSopInstanceUid]; if (newSopInstanceUid == null) { // Add a mapping DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.InstanceEntity); newSopInstanceUid = DefaultValueManager.GetInstantiatedValue(Tag.SOP_INSTANCE_UID); instanceMapper.Add(oldSopInstanceUid, newSopInstanceUid); } // Add the new sop instance uid to the dataset dataset.AddAttribute(Tag.SOP_INSTANCE_UID.GroupNumber, Tag.SOP_INSTANCE_UID.ElementNumber, VR.UI, newSopInstanceUid); // Use modality Worklist Item to help construct the Storage Message // Get the attribute values to copy DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator"); DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage); // Also try to use the MPPS InProgress Message to help construct the Storage Message DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator"); DicomComparator dicomMppsInProgressComparator = null; if (_nCreateSetMppsInProgress != null) { dicomMppsInProgressComparator = mppsInProgressComparator.InitializeDicomComparator(_nCreateSetMppsInProgress); } // Create the Storage message DvtkHighLevelInterface.Comparator.Comparator storageComparator = new DvtkHighLevelInterface.Comparator.Comparator("StorageComparator"); DvtkHighLevelInterface.Dicom.Messages.DicomMessage cStoreInstance = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); GenerateTriggers.MakeCStoreInstance(DefaultValueManager, cStoreInstance, dataset); storageComparator.PopulateDicomMessage(cStoreInstance, dicomWorklistItemComparator); if (dicomMppsInProgressComparator != null) { storageComparator.PopulateDicomMessage(cStoreInstance, dicomMppsInProgressComparator); } // Try to get the sop class uid System.String sopClassUid = System.String.Empty; DvtkData.Dimse.Attribute sopClassUidAttribute = dataset.GetAttribute(Tag.SOP_CLASS_UID); if (sopClassUidAttribute != null) { UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)sopClassUidAttribute.DicomValue; if (uniqueIdentifier.Values.Count > 0) { sopClassUid = uniqueIdentifier.Values[0]; } } // Add trigger item to the trigger trigger.AddItem(cStoreInstance, sopClassUid, transferSyntaxUid); } } // RAD-8 - trigger the ImageArchive return TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true); }
/// <summary> /// Send a single image generated from the Default Value Manager and /// the given Modality Worklist Item. /// </summary> /// <param name="startNewSeries">Boolean indicating if this image is part of a new /// Series or not.</param> /// <param name="modalityWorklistItem">Worklist Item used to provide overruling values for /// the Image header.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendModalityImagesStored(bool startNewSeries, DicomQueryItem modalityWorklistItem) { if (modalityWorklistItem == null) return false; // Update the default SeriesEntity values for the next Storage Message if (startNewSeries == true) { DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.SeriesEntity); } // Use modality Worklist Item to help construct the Storage Message // Get the attribute values to copy DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator"); DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage); // Also try to use the MPPS InProgress Message to help construct the Storage Message DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator"); DicomComparator dicomMppsInProgressComparator = null; if (_nCreateSetMppsInProgress != null) { dicomMppsInProgressComparator = mppsInProgressComparator.InitializeDicomComparator(_nCreateSetMppsInProgress); } // Create the Storage message DvtkHighLevelInterface.Comparator.Comparator storageComparator = new DvtkHighLevelInterface.Comparator.Comparator("StorageComparator"); DvtkHighLevelInterface.Dicom.Messages.DicomMessage cStoreInstance = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ); GenerateTriggers.MakeCStoreInstance(DefaultValueManager, cStoreInstance); storageComparator.PopulateDicomMessage(cStoreInstance, dicomWorklistItemComparator); if (dicomMppsInProgressComparator != null) { storageComparator.PopulateDicomMessage(cStoreInstance, dicomMppsInProgressComparator); } // Trigger the C-STORE-RQ Instance DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_8); trigger.HandleInSingleAssociation = true; trigger.AddItem(cStoreInstance, "1.2.840.10008.5.1.4.1.1.7", "1.2.840.10008.1.2"); // Update the default InstanceEntity values for the next Storage Message DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.InstanceEntity); // RAD-8 - trigger the ImageArchive return TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true); }
/// <summary> /// Trigger the Client to send a Verification (DICOM C-ECHO-RQ). /// </summary> /// <param name="actorName">Destination Actor Name.</param> /// <returns>Boolean indicating success or failure.</returns> public bool TriggerClientVerification(ActorName actorName) { // Set up a Verification SOP Class - C-ECHO-RQ trigger DicomTrigger dicomTrigger = new DicomTrigger(Dvtk.IheActors.Bases.TransactionNameEnum.RAD_UNKNOWN); dicomTrigger.AddItem(new DicomMessage(DvtkData.Dimse.DimseCommand.CECHORQ), HliScp.VERIFICATION_SOP_CLASS_UID, HliScp.IMPLICIT_VR_LITTLE_ENDIAN); DicomTriggerItem dicomTriggerItem = dicomTrigger.TriggerItems[0]; // thread must wait for association completion _scu.SignalCompletion = true; // set up the presentation context from the trigger PresentationContext[] presentationContexts = new PresentationContext[1]; presentationContexts[0] = new PresentationContext(dicomTriggerItem.SopClassUid, dicomTriggerItem.TransferSyntaxes); _scu.TriggerSendAssociation(dicomTriggerItem.Message, presentationContexts); // wait for association completion // - timeout of 0 means "no timeout". _semaphore.Wait(0); // return a boolean indicating if the trigger was processed successfully or not return _scu.ProcessTriggerResult; }